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