• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- GNULDBackend.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_TARGET_GNU_LDBACKEND_H
10 #define MCLD_TARGET_GNU_LDBACKEND_H
11 #ifdef ENABLE_UNITTEST
12 #include <gtest.h>
13 #endif
14 
15 #include <llvm/Support/ELF.h>
16 #include <mcld/ADT/HashTable.h>
17 #include <mcld/ADT/HashEntry.h>
18 #include <mcld/LD/ELFDynObjReader.h>
19 #include <mcld/LD/ELFDynObjWriter.h>
20 #include <mcld/LD/ELFObjectReader.h>
21 #include <mcld/LD/ELFObjectWriter.h>
22 #include <mcld/LD/ELFDynObjFileFormat.h>
23 #include <mcld/LD/ELFExecFileFormat.h>
24 #include <mcld/LD/ELFSegment.h>
25 #include <mcld/LD/GNUArchiveReader.h>
26 #include <mcld/Support/GCFactory.h>
27 #include <mcld/Target/ELFDynamic.h>
28 #include <mcld/Target/TargetLDBackend.h>
29 #include <mcld/LD/ELFSegmentFactory.h>
30 
31 namespace mcld
32 {
33 
34 struct SymCompare
35 {
operatorSymCompare36   bool operator()(const LDSymbol* X, const LDSymbol* Y) const
37   { return (X==Y); }
38 };
39 
40 struct PtrHash
41 {
operatorPtrHash42   size_t operator()(const LDSymbol* pKey) const
43   {
44     return (unsigned((uintptr_t)pKey) >> 4) ^
45            (unsigned((uintptr_t)pKey) >> 9);
46   }
47 };
48 
49 class MCLDInfo;
50 class Layout;
51 class SymbolCategory;
52 
53 /** \class GNULDBackend
54  *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
55  *  LDBackend.
56  */
57 class GNULDBackend : public TargetLDBackend
58 {
59   // These dynamic section tags are GNU extension.
60   enum {
61     DT_RELACOUNT  = 0x6ffffff9,
62     DT_RELCOUNT   = 0x6ffffffa,
63     DT_FLAGS_1    = 0x6ffffffb,
64     DT_VERDEF     = 0x6ffffffc,
65     DT_VERDEFNUM  = 0x6ffffffd,
66     DT_VERNEED    = 0x6ffffffe,
67     DT_VERNEEDNUM = 0x6fffffff
68   };
69 
70 protected:
71   // Based on Kind in LDFileFormat to define basic section orders for ELF, and
72   // refer gold linker to add more enumerations to handle Regular and BSS kind
73   enum SectionOrder {
74     SHO_INTERP = 1,          // .interp
75     SHO_RO_NOTE,             // .note.ABI-tag, .note.gnu.build-id
76     SHO_NAMEPOOL,            // *.hash, .dynsym, .dynstr
77     SHO_RELOCATION,          // .rel.*, .rela.*
78     SHO_REL_PLT,             // .rel.plt should come after other .rel.*
79     SHO_INIT,                // .init
80     SHO_PLT,                 // .plt
81     SHO_TEXT,                // .text
82     SHO_FINI,                // .fini
83     SHO_RO,                  // .rodata
84     SHO_EHFRAME,             // .eh_frame_hdr, .eh_frame
85     SHO_TLS_DATA,            // .tdata
86     SHO_TLS_BSS,             // .tbss
87     SHO_RELRO_LOCAL,         // .data.rel.ro.local
88     SHO_RELRO,               // .data.rel.ro,
89     SHO_RELRO_LAST,          // for x86 to adjust .got if needed
90     SHO_NON_RELRO_FIRST,     // for x86 to adjust .got.plt if needed
91     SHO_DATA,                // .data
92     SHO_LARGE_DATA,          // .ldata
93     SHO_RW_NOTE,             //
94     SHO_SMALL_DATA,          // .sdata
95     SHO_SMALL_BSS,           // .sbss
96     SHO_BSS,                 // .bss
97     SHO_LARGE_BSS,           // .lbss
98     SHO_UNDEFINED = ~(0U)    // default order
99   };
100 
101 protected:
102   GNULDBackend();
103 
104 public:
105   virtual ~GNULDBackend();
106 
107   bool initArchiveReader(MCLinker& pLinker, MCLDInfo& pInfo);
108   bool initObjectReader(MCLinker& pLinker);
109   bool initDynObjReader(MCLinker& pLinker);
110   bool initObjectWriter(MCLinker& pLinker);
111   bool initDynObjWriter(MCLinker& pLinker);
112 
113   bool initExecSections(MCLinker& pMCLinker);
114   bool initDynObjSections(MCLinker& pMCLinker);
115 
116   bool initStandardSymbols(MCLinker& pLinker);
117 
118   GNUArchiveReader *getArchiveReader();
119   GNUArchiveReader *getArchiveReader() const;
120 
121   ELFObjectReader *getObjectReader();
122   ELFObjectReader *getObjectReader() const;
123 
124   ELFDynObjReader *getDynObjReader();
125   ELFDynObjReader *getDynObjReader() const;
126 
127   ELFObjectWriter *getObjectWriter();
128   ELFObjectWriter *getObjectWriter() const;
129 
130   ELFDynObjWriter *getDynObjWriter();
131   ELFDynObjWriter *getDynObjWriter() const;
132 
133   ELFDynObjFileFormat* getDynObjFileFormat();
134   ELFDynObjFileFormat* getDynObjFileFormat() const;
135 
136   ELFExecFileFormat* getExecFileFormat();
137   ELFExecFileFormat* getExecFileFormat() const;
138 
139   size_t sectionStartOffset() const;
140 
141   /// The return value of machine() it the same as e_machine in the ELF header*/
142   virtual uint32_t machine() const = 0;
143 
144   /// ELFVersion - the value of e_ident[EI_VERSION]
ELFVersion()145   virtual uint8_t ELFVersion() const
146   { return llvm::ELF::EV_CURRENT; }
147 
148   /// OSABI - the value of e_ident[EI_OSABI]
149   virtual uint8_t OSABI() const = 0;
150 
151   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
152   virtual uint8_t ABIVersion() const = 0;
153 
154   /// flags - the value of ElfXX_Ehdr::e_flags
155   virtual uint64_t flags() const = 0;
156 
157   /// entry - the symbol name of the entry point
entry()158   virtual const char* entry() const
159   { return "_start"; }
160 
161   /// sizeNamePools - compute the size of regular name pools
162   /// In ELF executable files, regular name pools are .symtab, .strtab.,
163   /// .dynsym, .dynstr, and .hash
164   virtual void sizeNamePools(const Output& pOutput,
165                              const SymbolCategory& pSymbols,
166                              const MCLDInfo& pLDInfo);
167 
168   /// emitSectionData - emit target-dependent section data
169   virtual uint64_t emitSectionData(const Output& pOutput,
170                                    const LDSection& pSection,
171                                    const MCLDInfo& pInfo,
172                                    MemoryRegion& pRegion) const = 0;
173 
174   /// emitRegNamePools - emit regular name pools - .symtab, .strtab
175   virtual void emitRegNamePools(Output& pOutput,
176                                 SymbolCategory& pSymbols,
177                                 const Layout& pLayout,
178                                 const MCLDInfo& pLDInfo);
179 
180   /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
181   virtual void emitDynNamePools(Output& pOutput,
182                                 SymbolCategory& pSymbols,
183                                 const Layout& pLayout,
184                                 const MCLDInfo& pLDInfo);
185 
186   /// getSectionOrder - compute the layout order of the section
187   /// Layout calls this function to get the default order of the pSectHdr.
188   /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
189   /// will call getTargetSectionOrder().
190   ///
191   /// If targets favors certain order for general sections, please override
192   /// this function.
193   ///
194   /// @see getTargetSectionOrder
195   virtual unsigned int getSectionOrder(const Output& pOutput,
196                                        const LDSection& pSectHdr) const;
197 
198   /// getTargetSectionOrder - compute the layout order of target section
199   /// If the target favors certain order for the given gSectHdr, please
200   /// override this function.
201   ///
202   /// By default, this function returns the maximun order, and pSectHdr
203   /// will be the last section to be laid out.
204   virtual unsigned int
getTargetSectionOrder(const Output & pOutput,const LDSection & pSectHdr)205   getTargetSectionOrder(const Output& pOutput, const LDSection& pSectHdr) const
206   { return (unsigned int)-1; }
207 
208   /// emitProgramHdrs - emit ELF program headers
209   /// if the target favors other ways to emit program header, please override
210   /// this function
211   virtual void emitProgramHdrs(Output& pOutput);
212 
213   /// numOfSegments - return the number of segments
214   /// if the target favors other ways to emit program header, please override
215   /// this function
numOfSegments()216   virtual unsigned int numOfSegments() const
217   { return m_ELFSegmentTable.size(); }
218 
219   /// pagesize - the page size of the target machine, we set it to 4K here.
220   /// If target favors tht different size of page, please override this function
pagesize()221   virtual unsigned int pagesize() const
222   { return 0x1000; }
223 
224   /// getSymbolIdx - get the symbol index of ouput symbol table
225   size_t getSymbolIdx(LDSymbol* pSymbol) const;
226 
227 private:
228   /// createProgramHdrs - base on output sections to create the program headers
229   void createProgramHdrs(LDContext& pContext);
230 
231   /// writeELF32ProgramHdrs - write out the ELF32 program headers
232   void writeELF32ProgramHdrs(Output& pOutput);
233 
234   /// writeELF64ProgramHdrs - write out the ELF64 program headers
235   void writeELF64ProgramHdrs(Output& pOutput);
236 
237   /// getSegmentFlag - give a section flag and return the corresponding segment
238   /// flag
getSegmentFlag(const uint32_t pSectionFlag)239   inline uint32_t getSegmentFlag(const uint32_t pSectionFlag)
240   {
241     uint32_t flag = llvm::ELF::PF_R;
242     if (0 != (pSectionFlag & llvm::ELF::SHF_WRITE))
243       flag |= llvm::ELF::PF_W;
244     if (0 != (pSectionFlag & llvm::ELF::SHF_EXECINSTR))
245       flag |= llvm::ELF::PF_X;
246     return flag;
247   }
248 
249   /// preLayout - Backend can do any needed modification before layout
250   void preLayout(const Output& pOutput,
251                  const MCLDInfo& pInfo,
252                  MCLinker& pLinker);
253 
254   /// postLayout -Backend can do any needed modification after layout
255   void postLayout(const Output& pOutput,
256                  const MCLDInfo& pInfo,
257                  MCLinker& pLinker);
258 
259 protected:
260   uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
261 
262   uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
263 
264   uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
265 
266   uint64_t getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const;
267 
268 private:
269   /// preLayout - Backend can do any needed modification before layout
270   virtual void doPreLayout(const Output& pOutput,
271                          const MCLDInfo& pInfo,
272                          MCLinker& pLinker) = 0;
273 
274   /// postLayout -Backend can do any needed modification after layout
275   virtual void doPostLayout(const Output& pOutput,
276                           const MCLDInfo& pInfo,
277                           MCLinker& pLinker) = 0;
278 
279   /// dynamic - the dynamic section of the target machine.
280   virtual ELFDynamic& dynamic() = 0;
281 
282   /// dynamic - the dynamic section of the target machine.
283   virtual const ELFDynamic& dynamic() const = 0;
284 
285 protected:
286   // ----- readers and writers ----- //
287   GNUArchiveReader* m_pArchiveReader;
288   ELFObjectReader* m_pObjectReader;
289   ELFDynObjReader* m_pDynObjReader;
290   ELFObjectWriter* m_pObjectWriter;
291   ELFDynObjWriter* m_pDynObjWriter;
292 
293   // -----  file formats  ----- //
294   ELFDynObjFileFormat* m_pDynObjFileFormat;
295   ELFExecFileFormat* m_pExecFileFormat;
296 
297   // -----  ELF segment factory  ----- //
298   ELFSegmentFactory m_ELFSegmentTable;
299 
300   // -----  ELF special sections  ----- //
301 
302 protected:
303   /// getHashBucketCount - calculate hash bucket count.
304   /// @ref Google gold linker, dynobj.cc:791
305   static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
306 
307   /// isDynamicSymbol
308   /// @ref Google gold linker: symtab.cc:311
309   static bool isDynamicSymbol(const LDSymbol& pSymbol, const Output& pOutput);
310 
311 protected:
312   typedef HashEntry<LDSymbol*, size_t, SymCompare> HashEntryType;
313   typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableType;
314 
315   /// m_pSymIndexMap - Map the LDSymbol to its index in the output symbol table
316   HashTableType* m_pSymIndexMap;
317 };
318 
319 } // namespace of mcld
320 
321 #endif
322 
323