Home | History | Annotate | Download | only in Mips
      1 //===- MipsLDBackend.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_MIPS_MIPSLDBACKEND_H
     10 #define TARGET_MIPS_MIPSLDBACKEND_H
     11 #include <mcld/Target/GNULDBackend.h>
     12 #include "MipsELFDynamic.h"
     13 #include "MipsGOT.h"
     14 #include "MipsGOTPLT.h"
     15 #include "MipsPLT.h"
     16 
     17 namespace mcld {
     18 
     19 class LinkerConfig;
     20 class OutputRelocSection;
     21 class SectionMap;
     22 class MemoryArea;
     23 class MipsGNUInfo;
     24 
     25 /** \class MipsGNULDBackend
     26  *  \brief Base linker backend of Mips target of GNU ELF format.
     27  */
     28 class MipsGNULDBackend : public GNULDBackend
     29 {
     30 public:
     31   typedef std::vector<LDSymbol*> SymbolListType;
     32 
     33 public:
     34   MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
     35   ~MipsGNULDBackend();
     36 
     37   bool needsLA25Stub(Relocation::Type pType, const mcld::ResolveInfo* pSym);
     38 
     39   void addNonPICBranchSym(ResolveInfo* rsym);
     40   bool hasNonPICBranch(const ResolveInfo* rsym) const;
     41 
     42 public:
     43   /// initTargetSections - initialize target dependent sections in output
     44   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
     45 
     46   /// initTargetSymbols - initialize target dependent symbols in output.
     47   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     48 
     49   /// getRelocator - return relocator.
     50   const Relocator* getRelocator() const;
     51   Relocator* getRelocator();
     52 
     53   /// preLayout - Backend can do any needed modification before layout
     54   void doPreLayout(IRBuilder& pBuilder);
     55 
     56   /// postLayout - Backend can do any needed modification after layout
     57   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
     58 
     59   /// dynamic - the dynamic section of the target machine.
     60   /// Use co-variant return type to return its own dynamic section.
     61   MipsELFDynamic& dynamic();
     62 
     63   /// dynamic - the dynamic section of the target machine.
     64   /// Use co-variant return type to return its own dynamic section.
     65   const MipsELFDynamic& dynamic() const;
     66 
     67   /// emitSectionData - write out the section data into the memory region.
     68   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     69   /// call back target backend to emit the data.
     70   ///
     71   /// Backends handle the target-special tables (plt, gp,...) by themselves.
     72   /// Backend can put the data of the tables in SectionData directly
     73   ///  - LDSection.getSectionData can get the section data.
     74   /// Or, backend can put the data into special data structure
     75   ///  - backend can maintain its own map<LDSection, table> to get the table
     76   /// from given LDSection.
     77   ///
     78   /// @param pSection - the given LDSection
     79   /// @param pRegion - the region to write out data
     80   /// @return the size of the table in the file.
     81   uint64_t emitSectionData(const LDSection& pSection,
     82                            MemoryRegion& pRegion) const;
     83 
     84   /// hasEntryInStrTab - symbol has an entry in a .strtab
     85   bool hasEntryInStrTab(const LDSymbol& pSym) const;
     86 
     87   /// orderSymbolTable - order symbol table before emitting
     88   void orderSymbolTable(Module& pModule);
     89 
     90   /// readSection - read a target dependent section.
     91   bool readSection(Input& pInput, SectionData& pSD);
     92 
     93   MipsGOT& getGOT();
     94   const MipsGOT& getGOT() const;
     95 
     96   MipsPLT& getPLT();
     97   const MipsPLT& getPLT() const;
     98 
     99   MipsGOTPLT& getGOTPLT();
    100   const MipsGOTPLT& getGOTPLT() const;
    101 
    102   OutputRelocSection& getRelPLT();
    103   const OutputRelocSection& getRelPLT() const;
    104 
    105   OutputRelocSection& getRelDyn();
    106   const OutputRelocSection& getRelDyn() const;
    107 
    108   LDSymbol*             getGOTSymbol()           { return m_pGOTSymbol;    }
    109   const LDSymbol*       getGOTSymbol() const     { return m_pGOTSymbol;    }
    110 
    111   LDSymbol*             getGpDispSymbol()        { return m_pGpDispSymbol; }
    112   const LDSymbol*       getGpDispSymbol() const  { return m_pGpDispSymbol; }
    113 
    114   SymbolListType&       getGlobalGOTSyms()       { return m_GlobalGOTSyms; }
    115   const SymbolListType& getGlobalGOTSyms() const { return m_GlobalGOTSyms; }
    116 
    117   /// getTargetSectionOrder - compute the layout order of ARM target sections
    118   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
    119 
    120   /// finalizeSymbol - finalize the symbol value
    121   bool finalizeTargetSymbols();
    122 
    123   /// allocateCommonSymbols - allocate common symbols in the corresponding
    124   /// sections.
    125   bool allocateCommonSymbols(Module& pModule);
    126 
    127   /// getGP0 - the gp value used to create the relocatable objects
    128   /// in the specified input.
    129   uint64_t getGP0(const Input& pInput) const;
    130 
    131 private:
    132   void defineGOTSymbol(IRBuilder& pBuilder);
    133   void defineGOTPLTSymbol(IRBuilder& pBuilder);
    134 
    135   bool relaxRelocation(IRBuilder& pBuilder, Relocation& pRel);
    136 
    137   /// emitSymbol32 - emit an ELF32 symbol, override parent's function
    138   void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
    139                     LDSymbol& pSymbol,
    140                     char* pStrtab,
    141                     size_t pStrtabsize,
    142                     size_t pSymtabIdx);
    143 
    144   /// doCreateProgramHdrs - backend can implement this function to create the
    145   /// target-dependent segments
    146   void doCreateProgramHdrs(Module& pModule);
    147 
    148   /// mayRelax - Backends should override this function if they need relaxation
    149   bool mayRelax() { return true; }
    150 
    151   /// doRelax - Backend can orevride this function to add its relaxation
    152   /// implementation. Return true if the output (e.g., .text) is "relaxed"
    153   /// (i.e. layout is changed), and set pFinished to true if everything is fit,
    154   /// otherwise set it to false.
    155   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
    156 
    157   /// initTargetStubs
    158   bool initTargetStubs();
    159 
    160   /// readRelocation - read ELF32_Rel entry
    161   bool readRelocation(const llvm::ELF::Elf32_Rel& pRel,
    162                       Relocation::Type& pType,
    163                       uint32_t& pSymIdx,
    164                       uint32_t& pOffset) const;
    165 
    166   /// readRelocation - read ELF32_Rela entry
    167   bool readRelocation(const llvm::ELF::Elf32_Rela& pRel,
    168                       Relocation::Type& pType,
    169                       uint32_t& pSymIdx,
    170                       uint32_t& pOffset,
    171                       int32_t& pAddend) const;
    172 
    173   /// readRelocation - read ELF64_Rel entry
    174   bool readRelocation(const llvm::ELF::Elf64_Rel& pRel,
    175                       Relocation::Type& pType,
    176                       uint32_t& pSymIdx,
    177                       uint64_t& pOffset) const;
    178 
    179   /// readRel - read ELF64_Rela entry
    180   bool readRelocation(const llvm::ELF::Elf64_Rela& pRel,
    181                       Relocation::Type& pType,
    182                       uint32_t& pSymIdx,
    183                       uint64_t& pOffset,
    184                       int64_t& pAddend) const;
    185 
    186   /// emitRelocation - write data to the ELF32_Rel entry
    187   void emitRelocation(llvm::ELF::Elf32_Rel& pRel,
    188                       Relocation::Type pType,
    189                       uint32_t pSymIdx,
    190                       uint32_t pOffset) const;
    191 
    192   /// emitRelocation - write data to the ELF32_Rela entry
    193   void emitRelocation(llvm::ELF::Elf32_Rela& pRel,
    194                       Relocation::Type pType,
    195                       uint32_t pSymIdx,
    196                       uint32_t pOffset,
    197                       int32_t pAddend) const;
    198 
    199   /// emitRelocation - write data to the ELF64_Rel entry
    200   void emitRelocation(llvm::ELF::Elf64_Rel& pRel,
    201                       Relocation::Type pType,
    202                       uint32_t pSymIdx,
    203                       uint64_t pOffset) const;
    204 
    205   /// emitRelocation - write data to the ELF64_Rela entry
    206   void emitRelocation(llvm::ELF::Elf64_Rela& pRel,
    207                       Relocation::Type pType,
    208                       uint32_t pSymIdx,
    209                       uint64_t pOffset,
    210                       int64_t pAddend) const;
    211 
    212 private:
    213   typedef llvm::DenseSet<const ResolveInfo*> ResolveInfoSetType;
    214   typedef llvm::DenseMap<const Input*, llvm::ELF::Elf64_Addr> GP0MapType;
    215 
    216 protected:
    217   Relocator* m_pRelocator;
    218   MipsGOT* m_pGOT;                      // .got
    219   MipsPLT* m_pPLT;                      // .plt
    220   MipsGOTPLT* m_pGOTPLT;                // .got.plt
    221 
    222 private:
    223   MipsGNUInfo& m_pInfo;
    224 
    225   OutputRelocSection* m_pRelPlt;        // .rel.plt
    226   OutputRelocSection* m_pRelDyn;        // .rel.dyn
    227 
    228   MipsELFDynamic* m_pDynamic;
    229   LDSymbol* m_pGOTSymbol;
    230   LDSymbol* m_pPLTSymbol;
    231   LDSymbol* m_pGpDispSymbol;
    232 
    233   SymbolListType m_GlobalGOTSyms;
    234   ResolveInfoSetType m_HasNonPICBranchSyms;
    235   GP0MapType m_GP0Map;
    236 };
    237 
    238 /** \class Mips32GNULDBackend
    239  *  \brief Base linker backend of Mips 32-bit target of GNU ELF format.
    240  */
    241 class Mips32GNULDBackend : public MipsGNULDBackend
    242 {
    243 public:
    244   Mips32GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
    245 
    246 private:
    247   // MipsGNULDBackend
    248 
    249   bool initRelocator();
    250   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
    251   size_t getRelEntrySize();
    252   size_t getRelaEntrySize();
    253 };
    254 
    255 /** \class Mips64GNULDBackend
    256  *  \brief Base linker backend of Mips 64-bit target of GNU ELF format.
    257  */
    258 class Mips64GNULDBackend : public MipsGNULDBackend
    259 {
    260 public:
    261   Mips64GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo);
    262 
    263 private:
    264   // MipsGNULDBackend
    265 
    266   bool initRelocator();
    267   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
    268   size_t getRelEntrySize();
    269   size_t getRelaEntrySize();
    270 };
    271 
    272 } // namespace of mcld
    273 
    274 #endif
    275