1//===- ELFSegment.h -------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MCLD_LD_ELFSEGMENT_H
10#define MCLD_LD_ELFSEGMENT_H
11#include <mcld/Support/Allocators.h>
12#include <mcld/Config/Config.h>
13#include <llvm/Support/ELF.h>
14#include <llvm/Support/DataTypes.h>
15#include <vector>
16
17namespace mcld
18{
19
20class LDSection;
21
22/** \class ELFSegment
23 *  \brief decribe the program header for ELF executable or shared object
24 */
25class ELFSegment
26{
27public:
28  typedef std::vector<LDSection*> SectionList;
29  typedef SectionList::iterator iterator;
30  typedef SectionList::const_iterator const_iterator;
31  typedef SectionList::reverse_iterator reverse_iterator;
32  typedef SectionList::const_reverse_iterator const_reverse_iterator;
33
34private:
35  friend class Chunk<ELFSegment, MCLD_SEGMENTS_PER_OUTPUT>;
36  ELFSegment();
37  ELFSegment(uint32_t pType, uint32_t pFlag = llvm::ELF::PF_R);
38
39public:
40  ~ELFSegment();
41
42  ///  -----  iterators  -----  ///
43  iterator       begin()       { return m_SectionList.begin(); }
44  const_iterator begin() const { return m_SectionList.begin(); }
45  iterator       end()         { return m_SectionList.end(); }
46  const_iterator end()   const { return m_SectionList.end(); }
47
48  reverse_iterator       rbegin()       { return m_SectionList.rbegin(); }
49  const_reverse_iterator rbegin() const { return m_SectionList.rbegin(); }
50  reverse_iterator       rend()         { return m_SectionList.rend(); }
51  const_reverse_iterator rend()   const { return m_SectionList.rend(); }
52
53  LDSection*       front()       { return m_SectionList.front(); }
54  const LDSection* front() const { return m_SectionList.front(); }
55  LDSection*       back()        { return m_SectionList.back(); }
56  const LDSection* back()  const { return m_SectionList.back(); }
57
58  ///  -----  observers  -----  ///
59  uint32_t type()   const { return m_Type; }
60  uint64_t offset() const { return m_Offset; }
61  uint64_t vaddr()  const { return m_Vaddr; }
62  uint64_t paddr()  const { return m_Paddr; }
63  uint64_t filesz() const { return m_Filesz; }
64  uint64_t memsz()  const { return m_Memsz; }
65  uint32_t flag()   const { return m_Flag; }
66  uint64_t align()  const { return std::max(m_Align, m_MaxSectionAlign); }
67
68  size_t size() const { return m_SectionList.size(); }
69  bool  empty() const { return m_SectionList.empty(); }
70
71  bool isLoadSegment() const;
72  bool isDataSegment() const;
73  bool isBssSegment() const;
74
75  ///  -----  modifiers  -----  ///
76  void setOffset(uint64_t pOffset)
77  { m_Offset = pOffset; }
78
79  void setVaddr(uint64_t pVaddr)
80  { m_Vaddr = pVaddr; }
81
82  void setPaddr(uint64_t pPaddr)
83  { m_Paddr = pPaddr; }
84
85  void setFilesz(uint64_t pFilesz)
86  { m_Filesz = pFilesz; }
87
88  void setMemsz(uint64_t pMemsz)
89  { m_Memsz = pMemsz; }
90
91  void setFlag(uint32_t pFlag)
92  { m_Flag = pFlag; }
93
94  void updateFlag(uint32_t pFlag)
95  {
96    // PT_TLS segment should be PF_R
97    if (llvm::ELF::PT_TLS != m_Type)
98      m_Flag |= pFlag;
99  }
100
101  void setAlign(uint64_t pAlign)
102  { m_Align = pAlign; }
103
104  iterator insert(iterator pPos, LDSection* pSection);
105
106  void append(LDSection* pSection);
107
108  /* factory methods */
109  static ELFSegment* Create(uint32_t pType, uint32_t pFlag = llvm::ELF::PF_R);
110  static void Destroy(ELFSegment*& pSegment);
111  static void Clear();
112
113private:
114  uint32_t m_Type;            // Type of segment
115  uint32_t m_Flag;            // Segment flags
116  uint64_t m_Offset;          // File offset where segment is located, in bytes
117  uint64_t m_Vaddr;           // Virtual address of the segment
118  uint64_t m_Paddr;           // Physical address of the segment (OS-specific)
119  uint64_t m_Filesz;          // # of bytes in file image of segment (may be 0)
120  uint64_t m_Memsz;           // # of bytes in mem image of segment (may be 0)
121  uint64_t m_Align;           // alignment constraint
122  uint64_t m_MaxSectionAlign; // max alignment of the sections in this segment
123  SectionList m_SectionList;
124};
125
126} // namespace of mcld
127
128#endif
129
130