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