Home | History | Annotate | Download | only in X86
      1 //===- X86LDBackend.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 X86_LDBACKEND_H
     10 #define X86_LDBACKEND_H
     11 
     12 #include "X86ELFDynamic.h"
     13 #include "X86GOT.h"
     14 #include "X86PLT.h"
     15 #include <mcld/LD/LDSection.h>
     16 #include <mcld/Target/GNULDBackend.h>
     17 #include <mcld/Target/OutputRelocSection.h>
     18 
     19 namespace mcld {
     20 
     21 //===----------------------------------------------------------------------===//
     22 /// X86GNULDBackend - linker backend of X86 target of GNU ELF format
     23 ///
     24 class X86GNULDBackend : public GNULDBackend
     25 {
     26 public:
     27   /** \enum ReservedEntryType
     28    *  \brief The reserved entry type of reserved space in ResolveInfo.
     29    *
     30    *  This is used for sacnRelocation to record what kinds of entries are
     31    *  reserved for this resolved symbol
     32    *
     33    *  In X86, there are three kinds of entries, GOT, PLT, and dynamic reloction.
     34    *  GOT may needs a corresponding relocation to relocate itself, so we
     35    *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
     36    *  symbol, there might be two kinds of entries reserved for different location.
     37    *  For example, reference to the same symbol, one may use GOT and the other may
     38    *  use dynamic relocation.
     39    *
     40    *  bit:  3       2      1     0
     41    *   | PLT | GOTRel | GOT | Rel |
     42    *
     43    *  value    Name         - Description
     44    *
     45    *  0000     None         - no reserved entry
     46    *  0001     ReserveRel   - reserve an dynamic relocation entry
     47    *  0010     ReserveGOT   - reserve an GOT entry
     48    *  0011     GOTandRel    - For different relocation, we've reserved GOT and
     49    *                          Rel for different location.
     50    *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
     51    *                          relocation entry which relocate this GOT entry
     52    *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
     53    *                          and relocation entry for different location.
     54    *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
     55    *                          Dynamic relocation entries
     56    *  1001     PLTandRel    - For different relocation, we've reserved PLT and
     57    *                          Rel for different location.
     58    */
     59   enum ReservedEntryType {
     60     None         = 0,
     61     ReserveRel   = 1,
     62     ReserveGOT   = 2,
     63     GOTandRel    = 3,
     64     GOTRel       = 4,
     65     GOTRelandRel = 5,
     66     ReservePLT   = 8,
     67     PLTandRel    = 9
     68   };
     69 
     70   X86GNULDBackend();
     71 
     72   ~X86GNULDBackend();
     73 
     74   RelocationFactory* getRelocFactory();
     75 
     76   uint32_t machine() const;
     77 
     78   bool isLittleEndian() const
     79   { return true; }
     80 
     81   X86GOT& getGOT();
     82 
     83   const X86GOT& getGOT() const;
     84 
     85   X86PLT& getPLT();
     86 
     87   const X86PLT& getPLT() const;
     88 
     89   unsigned int bitclass() const;
     90 
     91   /// preLayout - Backend can do any needed modification before layout
     92   void doPreLayout(const Output& pOutput,
     93                    const MCLDInfo& pInfo,
     94                    MCLinker& pLinker);
     95 
     96   /// postLayout -Backend can do any needed modification after layout
     97   void doPostLayout(const Output& pOutput,
     98                     const MCLDInfo& pInfo,
     99                     MCLinker& pLinker);
    100 
    101   /// dynamic - the dynamic section of the target machine.
    102   /// Use co-variant return type to return its own dynamic section.
    103   X86ELFDynamic& dynamic();
    104 
    105   /// dynamic - the dynamic section of the target machine.
    106   /// Use co-variant return type to return its own dynamic section.
    107   const X86ELFDynamic& dynamic() const;
    108 
    109   /// emitSectionData - write out the section data into the memory region.
    110   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
    111   /// call back target backend to emit the data.
    112   ///
    113   /// Backends handle the target-special tables (plt, gp,...) by themselves.
    114   /// Backend can put the data of the tables in MCSectionData directly
    115   ///  - LDSection.getSectionData can get the section data.
    116   /// Or, backend can put the data into special data structure
    117   ///  - backend can maintain its own map<LDSection, table> to get the table
    118   /// from given LDSection.
    119   ///
    120   /// @param pOutput - the output file
    121   /// @param pSection - the given LDSection
    122   /// @param pInfo - all options in the command line.
    123   /// @param pRegion - the region to write out data
    124   /// @return the size of the table in the file.
    125   uint64_t emitSectionData(const Output& pOutput,
    126                            const LDSection& pSection,
    127                            const MCLDInfo& pInfo,
    128                            MemoryRegion& pRegion) const;
    129 
    130   /// OSABI - the value of e_ident[EI_OSABI]
    131   /// FIXME
    132   uint8_t OSABI() const
    133   { return llvm::ELF::ELFOSABI_NONE; }
    134 
    135   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
    136   /// FIXME
    137   uint8_t ABIVersion() const
    138   { return 0x0; }
    139 
    140   /// flags - the value of ElfXX_Ehdr::e_flags
    141   /// FIXME
    142   uint64_t flags() const
    143   { return 0x0; }
    144 
    145   /// initTargetSectionMap - initialize target dependent section mapping
    146   bool initTargetSectionMap(SectionMap& pSectionMap);
    147 
    148   // initRelocFactory - create and initialize RelocationFactory
    149   bool initRelocFactory(const MCLinker& pLinker);
    150 
    151   void initTargetSections(MCLinker& pLinker);
    152 
    153   void initTargetSymbols(MCLinker& pLinker);
    154 
    155   /// scanRelocation - determine the empty entries are needed or not and create
    156   /// the empty entries if needed.
    157   /// For X86, following entries are check to create:
    158   /// - GOT entry (for .got and .got.plt sections)
    159   /// - PLT entry (for .plt section)
    160   /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
    161   void scanRelocation(Relocation& pReloc,
    162                       const LDSymbol& pInputSym,
    163                       MCLinker& pLinker,
    164                       const MCLDInfo& pLDInfo,
    165                       const Output& pOutput);
    166 
    167   OutputRelocSection& getRelDyn();
    168 
    169   const OutputRelocSection& getRelDyn() const;
    170 
    171   OutputRelocSection& getRelPLT();
    172 
    173   const OutputRelocSection& getRelPLT() const;
    174 
    175   /// getTargetSectionOrder - compute the layout order of X86 target sections
    176   unsigned int getTargetSectionOrder(const Output& pOutput,
    177                                      const LDSection& pSectHdr) const;
    178 
    179   /// finalizeSymbol - finalize the symbol value
    180   /// If the symbol's reserved field is not zero, MCLinker will call back this
    181   /// function to ask the final value of the symbol
    182   bool finalizeSymbol(LDSymbol& pSymbol) const;
    183 
    184   /// allocateCommonSymbols - allocate common symbols in the corresponding
    185   /// sections.
    186   bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
    187 
    188 public:
    189   bool isSymbolPreemptible(const ResolveInfo& pSym,
    190                            const MCLDInfo& pLDInfo,
    191                            const Output& pOutput) const;
    192 
    193 private:
    194   void scanLocalReloc(Relocation& pReloc,
    195                       const LDSymbol& pInputSym,
    196                       MCLinker& pLinker,
    197                       const MCLDInfo& pLDInfo,
    198                       const Output& pOutput);
    199 
    200   void scanGlobalReloc(Relocation& pReloc,
    201                        const LDSymbol& pInputSym,
    202                        MCLinker& pLinker,
    203                        const MCLDInfo& pLDInfo,
    204                        const Output& pOutput);
    205 
    206   bool isSymbolNeedsPLT(const ResolveInfo& pSym,
    207                         const MCLDInfo& pLDInfo,
    208                         const Output& pOutput) const;
    209 
    210   bool isSymbolNeedsDynRel(const ResolveInfo& pSym,
    211                            const Output& pOutput,
    212                            bool isAbsReloc) const;
    213 
    214   void updateAddend(Relocation& pReloc,
    215                     const LDSymbol& pInputSym,
    216                     const Layout& pLayout) const;
    217 
    218   void createX86GOT(MCLinker& pLinker, const Output& pOutput);
    219   void createX86PLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
    220   void createX86RelDyn(MCLinker& pLinker, const Output& pOutput);
    221 
    222   ELFFileFormat* getOutputFormat(const Output& pOutput) const;
    223 
    224 private:
    225   RelocationFactory* m_pRelocFactory;
    226   X86GOT* m_pGOT;
    227   X86PLT* m_pPLT;
    228   /// m_RelDyn - dynamic relocation table of .rel.dyn
    229   OutputRelocSection* m_pRelDyn;
    230   /// m_RelPLT - dynamic relocation table of .rel.plt
    231   OutputRelocSection* m_pRelPLT;
    232 
    233   X86ELFDynamic* m_pDynamic;
    234   LDSymbol* m_pGOTSymbol;
    235 };
    236 
    237 //===----------------------------------------------------------------------===//
    238 /// X86MachOLDBackend - linker backend of X86 target of MachO format
    239 ///
    240 /**
    241 class X86MachOLDBackend : public DarwinX86LDBackend
    242 {
    243 public:
    244   X86MachOLDBackend();
    245   ~X86MachOLDBackend();
    246 
    247 private:
    248   MCMachOTargetArchiveReader *createTargetArchiveReader() const;
    249   MCMachOTargetObjectReader *createTargetObjectReader() const;
    250   MCMachOTargetObjectWriter *createTargetObjectWriter() const;
    251 
    252 };
    253 **/
    254 } // namespace of mcld
    255 
    256 #endif
    257