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