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 TARGET_X86_X86LDBACKEND_H_
     10 #define TARGET_X86_X86LDBACKEND_H_
     11 
     12 #include "X86ELFDynamic.h"
     13 #include "X86GOT.h"
     14 #include "X86GOTPLT.h"
     15 #include "X86PLT.h"
     16 
     17 #include "mcld/LD/LDSection.h"
     18 #include "mcld/Target/GNULDBackend.h"
     19 #include "mcld/Target/OutputRelocSection.h"
     20 
     21 namespace mcld {
     22 
     23 class LinkerConfig;
     24 class GNUInfo;
     25 
     26 //===----------------------------------------------------------------------===//
     27 /// X86GNULDBackend - linker backend of X86 target of GNU ELF format
     28 ///
     29 class X86GNULDBackend : public GNULDBackend {
     30  public:
     31   X86GNULDBackend(const LinkerConfig& pConfig,
     32                   GNUInfo* pInfo,
     33                   Relocation::Type pCopyRel);
     34 
     35   ~X86GNULDBackend();
     36 
     37   uint32_t machine() const;
     38 
     39   X86PLT& getPLT();
     40 
     41   const X86PLT& getPLT() const;
     42 
     43   /// preLayout - Backend can do any needed modification before layout
     44   void doPreLayout(IRBuilder& pBuilder);
     45 
     46   /// postLayout -Backend can do any needed modification after layout
     47   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
     48 
     49   /// dynamic - the dynamic section of the target machine.
     50   /// Use co-variant return type to return its own dynamic section.
     51   X86ELFDynamic& dynamic();
     52 
     53   /// dynamic - the dynamic section of the target machine.
     54   /// Use co-variant return type to return its own dynamic section.
     55   const X86ELFDynamic& dynamic() const;
     56 
     57   /// emitSectionData - write out the section data into the memory region.
     58   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     59   /// call back target backend to emit the data.
     60   ///
     61   /// Backends handle the target-special tables (plt, gp,...) by themselves.
     62   /// Backend can put the data of the tables in MCSectionData directly
     63   ///  - LDSection.getSectionData can get the section data.
     64   /// Or, backend can put the data into special data structure
     65   ///  - backend can maintain its own map<LDSection, table> to get the table
     66   /// from given LDSection.
     67   ///
     68   /// @param pSection - the given LDSection
     69   /// @param pLayout - for comouting the size of fragment
     70   /// @param pRegion - the region to write out data
     71   /// @return the size of the table in the file.
     72   uint64_t emitSectionData(const LDSection& pSection,
     73                            MemoryRegion& pRegion) const;
     74 
     75   /// initRelocator - create and initialize Relocator.
     76   virtual bool initRelocator() = 0;
     77 
     78   /// getRelocator - return relocator.
     79   const Relocator* getRelocator() const;
     80   Relocator* getRelocator();
     81 
     82   virtual void initTargetSections(Module& pModule, ObjectBuilder& pBuilder) = 0;
     83 
     84   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     85 
     86   OutputRelocSection& getRelDyn();
     87   const OutputRelocSection& getRelDyn() const;
     88 
     89   OutputRelocSection& getRelPLT();
     90   const OutputRelocSection& getRelPLT() const;
     91 
     92   LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
     93   const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; }
     94 
     95   /// getTargetSectionOrder - compute the layout order of X86 target sections
     96   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
     97 
     98   /// finalizeTargetSymbols - finalize the symbol value
     99   bool finalizeTargetSymbols();
    100 
    101   /// getPointerRel - get pointer relocation type.
    102   Relocation::Type getPointerRel() { return m_PointerRel; }
    103 
    104   Relocation::Type getCopyRelType() const { return m_CopyRel; }
    105   Relocation::Type getPointerRelType() const { return m_PointerRel; }
    106 
    107  protected:
    108   void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
    109 
    110   /// getRelEntrySize - the size in BYTE of rel type relocation
    111   size_t getRelEntrySize() { return m_RelEntrySize; }
    112 
    113   /// getRelEntrySize - the size in BYTE of rela type relocation
    114   size_t getRelaEntrySize() { return m_RelaEntrySize; }
    115 
    116  private:
    117   /// doCreateProgramHdrs - backend can implement this function to create the
    118   /// target-dependent segments
    119   void doCreateProgramHdrs(Module& pModule);
    120 
    121   virtual void setGOTSectionSize(IRBuilder& pBuilder) = 0;
    122 
    123   virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const = 0;
    124 
    125   virtual uint64_t emitGOTPLTSectionData(
    126       MemoryRegion& pRegion,
    127       const ELFFileFormat* FileFormat) const = 0;
    128 
    129   virtual void setRelDynSize() = 0;
    130   virtual void setRelPLTSize() = 0;
    131 
    132   void addEhFrameForPLT(Module& pModule);
    133   virtual llvm::StringRef createCIERegionForPLT() = 0;
    134   virtual llvm::StringRef createFDERegionForPLT() = 0;
    135 
    136  protected:
    137   Relocator* m_pRelocator;
    138   X86PLT* m_pPLT;
    139   /// m_RelDyn - dynamic relocation table of .rel.dyn
    140   OutputRelocSection* m_pRelDyn;
    141   /// m_RelPLT - dynamic relocation table of .rel.plt
    142   OutputRelocSection* m_pRelPLT;
    143 
    144   X86ELFDynamic* m_pDynamic;
    145   LDSymbol* m_pGOTSymbol;
    146 
    147   size_t m_RelEntrySize;
    148   size_t m_RelaEntrySize;
    149 
    150   Relocation::Type m_CopyRel;
    151   Relocation::Type m_PointerRel;
    152 };
    153 
    154 //
    155 //===----------------------------------------------------------------------===//
    156 /// X86_32GNULDBackend - linker backend of X86-32 target of GNU ELF format
    157 ///
    158 class X86_32GNULDBackend : public X86GNULDBackend {
    159  public:
    160   X86_32GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
    161 
    162   ~X86_32GNULDBackend();
    163 
    164   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
    165 
    166   X86_32GOT& getGOT();
    167 
    168   const X86_32GOT& getGOT() const;
    169 
    170   X86_32GOTPLT& getGOTPLT();
    171 
    172   const X86_32GOTPLT& getGOTPLT() const;
    173 
    174  private:
    175   /// initRelocator - create and initialize Relocator.
    176   bool initRelocator();
    177 
    178   void setGOTSectionSize(IRBuilder& pBuilder);
    179 
    180   uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
    181 
    182   uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
    183                                  const ELFFileFormat* FileFormat) const;
    184 
    185   void setRelDynSize();
    186   void setRelPLTSize();
    187 
    188   llvm::StringRef createCIERegionForPLT();
    189   llvm::StringRef createFDERegionForPLT();
    190 
    191  private:
    192   X86_32GOT* m_pGOT;
    193   X86_32GOTPLT* m_pGOTPLT;
    194 };
    195 
    196 //
    197 //===----------------------------------------------------------------------===//
    198 /// X86_64GNULDBackend - linker backend of X86-64 target of GNU ELF format
    199 ///
    200 class X86_64GNULDBackend : public X86GNULDBackend {
    201  public:
    202   X86_64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
    203 
    204   ~X86_64GNULDBackend();
    205 
    206   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
    207 
    208   X86_64GOT& getGOT();
    209 
    210   const X86_64GOT& getGOT() const;
    211 
    212   X86_64GOTPLT& getGOTPLT();
    213 
    214   const X86_64GOTPLT& getGOTPLT() const;
    215 
    216  private:
    217   /// initRelocator - create and initialize Relocator.
    218   bool initRelocator();
    219 
    220   void setGOTSectionSize(IRBuilder& pBuilder);
    221 
    222   uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
    223 
    224   uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
    225                                  const ELFFileFormat* FileFormat) const;
    226 
    227   void setRelDynSize();
    228   void setRelPLTSize();
    229 
    230   llvm::StringRef createCIERegionForPLT();
    231   llvm::StringRef createFDERegionForPLT();
    232 
    233  private:
    234   X86_64GOT* m_pGOT;
    235   X86_64GOTPLT* m_pGOTPLT;
    236 };
    237 
    238 }  // namespace mcld
    239 
    240 #endif  // TARGET_X86_X86LDBACKEND_H_
    241