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 
17 namespace mcld
18 {
19 
20 class LDSection;
21 
22 /** \class ELFSegment
23  *  \brief decribe the program header for ELF executable or shared object
24  */
25 class ELFSegment
26 {
27 public:
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 
34 private:
35   friend class Chunk<ELFSegment, MCLD_SEGMENTS_PER_OUTPUT>;
36   ELFSegment();
37   ELFSegment(uint32_t pType, uint32_t pFlag = llvm::ELF::PF_R);
38 
39 public:
40   ~ELFSegment();
41 
42   ///  -----  iterators  -----  ///
begin()43   iterator       begin()       { return m_SectionList.begin(); }
begin()44   const_iterator begin() const { return m_SectionList.begin(); }
end()45   iterator       end()         { return m_SectionList.end(); }
end()46   const_iterator end()   const { return m_SectionList.end(); }
47 
rbegin()48   reverse_iterator       rbegin()       { return m_SectionList.rbegin(); }
rbegin()49   const_reverse_iterator rbegin() const { return m_SectionList.rbegin(); }
rend()50   reverse_iterator       rend()         { return m_SectionList.rend(); }
rend()51   const_reverse_iterator rend()   const { return m_SectionList.rend(); }
52 
front()53   LDSection*       front()       { return m_SectionList.front(); }
front()54   const LDSection* front() const { return m_SectionList.front(); }
back()55   LDSection*       back()        { return m_SectionList.back(); }
back()56   const LDSection* back()  const { return m_SectionList.back(); }
57 
58   ///  -----  observers  -----  ///
type()59   uint32_t type()   const { return m_Type; }
offset()60   uint64_t offset() const { return m_Offset; }
vaddr()61   uint64_t vaddr()  const { return m_Vaddr; }
paddr()62   uint64_t paddr()  const { return m_Paddr; }
filesz()63   uint64_t filesz() const { return m_Filesz; }
memsz()64   uint64_t memsz()  const { return m_Memsz; }
flag()65   uint32_t flag()   const { return m_Flag; }
align()66   uint64_t align()  const { return std::max(m_Align, m_MaxSectionAlign); }
67 
size()68   size_t size() const { return m_SectionList.size(); }
empty()69   bool  empty() const { return m_SectionList.empty(); }
70 
71   bool isLoadSegment() const;
72   bool isDataSegment() const;
73   bool isBssSegment() const;
74 
75   ///  -----  modifiers  -----  ///
setOffset(uint64_t pOffset)76   void setOffset(uint64_t pOffset)
77   { m_Offset = pOffset; }
78 
setVaddr(uint64_t pVaddr)79   void setVaddr(uint64_t pVaddr)
80   { m_Vaddr = pVaddr; }
81 
setPaddr(uint64_t pPaddr)82   void setPaddr(uint64_t pPaddr)
83   { m_Paddr = pPaddr; }
84 
setFilesz(uint64_t pFilesz)85   void setFilesz(uint64_t pFilesz)
86   { m_Filesz = pFilesz; }
87 
setMemsz(uint64_t pMemsz)88   void setMemsz(uint64_t pMemsz)
89   { m_Memsz = pMemsz; }
90 
setFlag(uint32_t pFlag)91   void setFlag(uint32_t pFlag)
92   { m_Flag = pFlag; }
93 
updateFlag(uint32_t pFlag)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 
setAlign(uint64_t pAlign)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 
113 private:
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