Home | History | Annotate | Download | only in Target
      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 {
     36   bool operator()(const LDSymbol* X, const LDSymbol* Y) const
     37   { return (X==Y); }
     38 };
     39 
     40 struct 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 
     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]
    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 
    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
    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