GNULDBackend.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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
31namespace mcld
32{
33
34struct SymCompare
35{
36  bool operator()(const LDSymbol* X, const LDSymbol* Y) const
37  { return (X==Y); }
38};
39
40struct PtrHash
41{
42  size_t operator()(const LDSymbol* pKey) const
43  {
44    return (unsigned((uintptr_t)pKey) >> 4) ^
45           (unsigned((uintptr_t)pKey) >> 9);
46  }
47};
48
49class MCLDInfo;
50class Layout;
51class SymbolCategory;
52
53/** \class GNULDBackend
54 *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
55 *  LDBackend.
56 */
57class 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
70protected:
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
101protected:
102  GNULDBackend();
103
104public:
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]
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
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
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
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
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
227private:
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
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
259protected:
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
268private:
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
285protected:
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
302protected:
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
311protected:
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