• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- LDSection.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 
10 #ifndef MCLD_LD_LDSECTION_H
11 #define MCLD_LD_LDSECTION_H
12 #ifdef ENABLE_UNITTEST
13 #include <gtest.h>
14 #endif
15 
16 #include <llvm/Support/DataTypes.h>
17 #include <mcld/Support/Allocators.h>
18 #include <mcld/Config/Config.h>
19 #include <mcld/LD/LDFileFormat.h>
20 #include <string>
21 
22 namespace mcld {
23 
24 class SectionData;
25 class RelocData;
26 class EhFrame;
27 
28 /** \class LDSection
29  *  \brief LDSection represents a section header entry. It is a unified
30  *  abstraction of a section header entry for various file formats.
31  */
32 class LDSection
33 {
34 private:
35   friend class Chunk<LDSection, MCLD_SECTIONS_PER_INPUT>;
36 
37   LDSection();
38 
39   LDSection(const std::string& pName,
40             LDFileFormat::Kind pKind,
41             uint32_t pType,
42             uint32_t pFlag,
43             uint64_t pSize = 0,
44             uint64_t pAddr = 0);
45 
46 public:
47   ~LDSection();
48 
49   static LDSection* Create(const std::string& pName,
50                            LDFileFormat::Kind pKind,
51                            uint32_t pType,
52                            uint32_t pFlag,
53                            uint64_t pSize = 0,
54                            uint64_t pAddr = 0);
55 
56   static void Destroy(LDSection*& pSection);
57 
58   static void Clear();
59 
60   bool hasOffset() const;
61 
62   /// name - the name of this section.
name()63   const std::string& name() const
64   { return m_Name; }
65 
66   /// kind - the kind of this section, such as Text, BSS, GOT, and so on.
67   /// from LDFileFormat::Kind
kind()68   LDFileFormat::Kind kind() const
69   { return m_Kind; }
70 
71   /// type - The categorizes the section's contents and semantics. It's
72   /// different from llvm::SectionKind. Type is format-dependent, but
73   /// llvm::SectionKind is format independent and is used for bit-code.
74   ///   In ELF, it is sh_type
75   ///   In MachO, it's type field of struct section::flags
type()76   uint32_t type() const
77   { return m_Type; }
78 
79   /// flag - An integer describes miscellaneous attributes.
80   ///   In ELF, it is sh_flags.
81   ///   In MachO, it's attribute field of struct section::flags
flag()82   uint32_t flag() const
83   { return m_Flag; }
84 
85   /// size - An integer specifying the size in bytes of the virtual memory
86   /// occupied by this section.
87   ///   In ELF, if the type() is SHT_NOBITS, this function return zero.
88   ///   Before layouting, output's LDSection::size() should return zero.
size()89   uint64_t size() const
90   { return m_Size; }
91 
92   /// offset - An integer specifying the offset of this section in the file.
93   ///   Before layouting, output's LDSection::offset() should return zero.
offset()94   uint64_t offset() const
95   { return m_Offset; }
96 
97   /// addr - An integer specifying the virtual address of this section in the
98   /// virtual image.
99   ///   Before layouting, output's LDSection::offset() should return zero.
100   ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
101   ///   constraint is set in SectionData::setAlignment. addr() contains the
102   ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
103   ///   MachO uses the same scenario.
104   ///
105   ///   Because addr() in output is changing during linking, MCLinker does not
106   ///   store the address of the output here. The address is in Layout
addr()107   uint64_t addr() const
108   { return m_Addr; }
109 
110   /// align - An integer specifying the align of this section in the file.
111   ///   Before layouting, output's LDSection::align() should return zero.
align()112   uint32_t align() const
113   { return m_Align; }
114 
index()115   size_t index() const
116   { return m_Index; }
117 
118   /// getLink - return the Link. When a section A needs the other section B
119   /// during linking or loading, we say B is A's Link section.
120   /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info.
121   ///
122   /// @return if the section needs no other sections, return NULL
getLink()123   LDSection* getLink()
124   { return m_pLink; }
125 
getLink()126   const LDSection* getLink() const
127   { return m_pLink; }
128 
getInfo()129   size_t getInfo() const
130   { return m_Info; }
131 
setKind(LDFileFormat::Kind pKind)132   void setKind(LDFileFormat::Kind pKind)
133   { m_Kind = pKind; }
134 
setSize(uint64_t size)135   void setSize(uint64_t size)
136   { m_Size = size; }
137 
setOffset(uint64_t Offset)138   void setOffset(uint64_t Offset)
139   { m_Offset = Offset; }
140 
setAddr(uint64_t addr)141   void setAddr(uint64_t addr)
142   { m_Addr = addr; }
143 
setAlign(uint32_t align)144   void setAlign(uint32_t align)
145   { m_Align = align; }
146 
setFlag(uint32_t flag)147   void setFlag(uint32_t flag)
148   { m_Flag = flag; }
149 
setType(uint32_t type)150   void setType(uint32_t type)
151   { m_Type = type; }
152 
153   // -----  SectionData  ----- //
getSectionData()154   const SectionData* getSectionData() const { return m_Data.sect_data; }
getSectionData()155   SectionData*       getSectionData()       { return m_Data.sect_data; }
156 
setSectionData(SectionData * pSD)157   void setSectionData(SectionData* pSD) { m_Data.sect_data = pSD; }
158 
159   bool hasSectionData() const;
160 
161   // ------  RelocData  ------ //
getRelocData()162   const RelocData* getRelocData() const { return m_Data.reloc_data; }
getRelocData()163   RelocData*       getRelocData()       { return m_Data.reloc_data; }
164 
setRelocData(RelocData * pRD)165   void setRelocData(RelocData* pRD) { m_Data.reloc_data = pRD; }
166 
167   bool hasRelocData() const;
168 
169   // ------  EhFrame  ------ //
getEhFrame()170   const EhFrame* getEhFrame() const { return m_Data.eh_frame; }
getEhFrame()171   EhFrame*       getEhFrame()       { return m_Data.eh_frame; }
172 
setEhFrame(EhFrame * pEhFrame)173   void setEhFrame(EhFrame* pEhFrame) { m_Data.eh_frame = pEhFrame; }
174 
175   bool hasEhFrame() const;
176 
177   /// setLink - set the sections should link with.
178   /// if pLink is NULL, no Link section is set.
setLink(LDSection * pLink)179   void setLink(LDSection* pLink)
180   { m_pLink = pLink; }
181 
setInfo(size_t pInfo)182   void setInfo(size_t pInfo)
183   { m_Info = pInfo; }
184 
setIndex(size_t pIndex)185   void setIndex(size_t pIndex)
186   { m_Index = pIndex; }
187 
188 private:
189   union SectOrRelocData
190   {
191     SectionData* sect_data;
192     RelocData*   reloc_data;
193     EhFrame*     eh_frame;
194   };
195 
196 private:
197   std::string m_Name;
198 
199   LDFileFormat::Kind m_Kind;
200   uint32_t m_Type;
201   uint32_t m_Flag;
202 
203   uint64_t m_Size;
204   uint64_t m_Offset;
205   uint64_t m_Addr;
206   uint32_t m_Align;
207 
208   size_t m_Info;
209   LDSection* m_pLink;
210 
211   /// m_Data - the SectionData or RelocData of this section
212   SectOrRelocData m_Data;
213 
214   /// m_Index - the index of the file
215   size_t m_Index;
216 
217 }; // end of LDSection
218 
219 } // end namespace mcld
220 
221 #endif
222 
223