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/Config/Config.h"
12 #include "mcld/Support/Allocators.h"
13 
14 #include <llvm/Support/DataTypes.h>
15 #include <llvm/Support/ELF.h>
16 
17 #include <vector>
18 
19 namespace mcld {
20 
21 class LDSection;
22 
23 /** \class ELFSegment
24  *  \brief decribe the program header for ELF executable or shared object
25  */
26 class ELFSegment {
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   explicit 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) { m_Offset = pOffset; }
77 
setVaddr(uint64_t pVaddr)78   void setVaddr(uint64_t pVaddr) { m_Vaddr = pVaddr; }
79 
setPaddr(uint64_t pPaddr)80   void setPaddr(uint64_t pPaddr) { m_Paddr = pPaddr; }
81 
setFilesz(uint64_t pFilesz)82   void setFilesz(uint64_t pFilesz) { m_Filesz = pFilesz; }
83 
setMemsz(uint64_t pMemsz)84   void setMemsz(uint64_t pMemsz) { m_Memsz = pMemsz; }
85 
setFlag(uint32_t pFlag)86   void setFlag(uint32_t pFlag) { m_Flag = pFlag; }
87 
updateFlag(uint32_t pFlag)88   void updateFlag(uint32_t pFlag) {
89     // PT_TLS segment should be PF_R
90     if (llvm::ELF::PT_TLS != m_Type)
91       m_Flag |= pFlag;
92   }
93 
setAlign(uint64_t pAlign)94   void setAlign(uint64_t pAlign) { m_Align = pAlign; }
95 
96   iterator insert(iterator pPos, LDSection* pSection);
97 
98   void append(LDSection* pSection);
99 
100   /* factory methods */
101   static ELFSegment* Create(uint32_t pType, uint32_t pFlag = llvm::ELF::PF_R);
102   static void Destroy(ELFSegment*& pSegment);
103   static void Clear();
104 
105  private:
106   uint32_t m_Type;             // Type of segment
107   uint32_t m_Flag;             // Segment flags
108   uint64_t m_Offset;           // File offset where segment is located, in bytes
109   uint64_t m_Vaddr;            // Virtual address of the segment
110   uint64_t m_Paddr;            // Physical address of the segment (OS-specific)
111   uint64_t m_Filesz;           // # of bytes in file image of segment (may be 0)
112   uint64_t m_Memsz;            // # of bytes in mem image of segment (may be 0)
113   uint64_t m_Align;            // alignment constraint
114   uint64_t m_MaxSectionAlign;  // max alignment of the sections in this segment
115   SectionList m_SectionList;
116 };
117 
118 }  // namespace mcld
119 
120 #endif  // MCLD_LD_ELFSEGMENT_H_
121