Home | History | Annotate | Download | only in Mips
      1 //===- MipsRelocator.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_MIPSRELOCATOR_H_
     10 #define TARGET_MIPS_MIPSRELOCATOR_H_
     11 
     12 #include "mcld/LD/Relocator.h"
     13 #include "mcld/Support/GCFactory.h"
     14 #include "mcld/Target/KeyEntryMap.h"
     15 #include "MipsLDBackend.h"
     16 
     17 #include <llvm/ADT/DenseMapInfo.h>
     18 
     19 namespace mcld {
     20 
     21 class MipsRelocationInfo;
     22 
     23 /** \class MipsRelocator
     24  *  \brief MipsRelocator creates and destroys the Mips relocations.
     25  */
     26 class MipsRelocator : public Relocator {
     27  public:
     28   enum ReservedEntryType {
     29     None = 0,        // no reserved entry
     30     ReserveRel = 1,  // reserve a dynamic relocation entry
     31     ReserveGot = 2,  // reserve a GOT entry
     32     ReservePLT = 4   // reserve a PLT entry
     33   };
     34 
     35   typedef KeyEntryMap<ResolveInfo, PLTEntryBase> SymPLTMap;
     36   typedef KeyEntryMap<ResolveInfo, Fragment> SymGOTPLTMap;
     37 
     38  public:
     39   MipsRelocator(MipsGNULDBackend& pParent, const LinkerConfig& pConfig);
     40 
     41   /// scanRelocation - determine the empty entries are needed or not and
     42   /// create the empty entries if needed.
     43   /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
     44   void scanRelocation(Relocation& pReloc,
     45                       IRBuilder& pBuilder,
     46                       Module& pModule,
     47                       LDSection& pSection,
     48                       Input& pInput);
     49 
     50   /// initializeScan - do initialization before scan relocations in pInput
     51   /// @return - return true for initialization success
     52   bool initializeScan(Input& pInput);
     53 
     54   /// finalizeScan - do finalization after scan relocations in pInput
     55   /// @return - return true for finalization success
     56   bool finalizeScan(Input& pInput);
     57 
     58   /// initializeApply - do initialization before apply relocations in pInput
     59   /// @return - return true for initialization success
     60   bool initializeApply(Input& pInput);
     61 
     62   /// finalizeApply - do finalization after apply relocations in pInput
     63   /// @return - return true for finalization success
     64   bool finalizeApply(Input& pInput);
     65 
     66   Result applyRelocation(Relocation& pReloc);
     67 
     68   /// getDebugStringOffset - get the offset from the relocation target. This is
     69   /// used to get the debug string offset.
     70   uint32_t getDebugStringOffset(Relocation& pReloc) const;
     71 
     72   /// applyDebugStringOffset - apply the relocation target to specific offset.
     73   /// This is used to set the debug string offset.
     74   void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset);
     75 
     76   const Input& getApplyingInput() const { return *m_pApplyingInput; }
     77 
     78   MipsGNULDBackend& getTarget() { return m_Target; }
     79 
     80   const MipsGNULDBackend& getTarget() const { return m_Target; }
     81 
     82   /// postponeRelocation - save R_MIPS_LO16 paired relocations
     83   /// like R_MISP_HI16 and R_MIPS_GOT16 for a future processing.
     84   void postponeRelocation(Relocation& pReloc);
     85 
     86   /// applyPostponedRelocations - apply all postponed relocations
     87   /// paired with the R_MIPS_LO16 one.
     88   void applyPostponedRelocations(MipsRelocationInfo& pLo16Reloc);
     89 
     90   /// isGpDisp - return true if relocation is against _gp_disp symbol.
     91   bool isGpDisp(const Relocation& pReloc) const;
     92 
     93   /// getGPAddress - return address of _gp symbol.
     94   Address getGPAddress();
     95 
     96   /// getTPOffset - return TP_OFFSET against the SHF_TLS
     97   /// section in the processing input.
     98   Address getTPOffset();
     99 
    100   /// getDTPOffset - return DTP_OFFSET against the SHF_TLS
    101   /// section in the processing input.
    102   Address getDTPOffset();
    103 
    104   /// getGP0 - the gp value used to create the relocatable objects
    105   /// in the processing input.
    106   Address getGP0();
    107 
    108   /// getLocalGOTEntry - initialize and return a local GOT entry
    109   /// for this relocation.
    110   Fragment& getLocalGOTEntry(MipsRelocationInfo& pReloc,
    111                              Relocation::DWord entryValue);
    112 
    113   /// getGlobalGOTEntry - initialize and return a global GOT entry
    114   /// for this relocation.
    115   Fragment& getGlobalGOTEntry(MipsRelocationInfo& pReloc);
    116 
    117   /// getTLSGOTEntry - initialize and return a TLS GOT entry
    118   /// for this relocation.
    119   Fragment& getTLSGOTEntry(MipsRelocationInfo& pReloc);
    120 
    121   /// getGOTOffset - return offset of corresponded GOT entry.
    122   Address getGOTOffset(MipsRelocationInfo& pReloc);
    123 
    124   /// getTLSGOTOffset - return offset of corresponded TLS GOT entry.
    125   Address getTLSGOTOffset(MipsRelocationInfo& pReloc);
    126 
    127   /// createDynRel - initialize dynamic relocation for the relocation.
    128   void createDynRel(MipsRelocationInfo& pReloc);
    129 
    130   /// calcAHL - calculate combined addend used
    131   /// by R_MIPS_HI16 and R_MIPS_GOT16 relocations.
    132   uint64_t calcAHL(const MipsRelocationInfo& pHiReloc);
    133 
    134   /// isN64ABI - check current ABI
    135   bool isN64ABI() const;
    136 
    137   const char* getName(Relocation::Type pType) const;
    138 
    139   const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; }
    140   SymPLTMap& getSymPLTMap() { return m_SymPLTMap; }
    141 
    142   const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
    143   SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; }
    144 
    145  protected:
    146   /// setupRelDynEntry - create dynamic relocation entry.
    147   virtual void setupRel32DynEntry(FragmentRef& pFragRef, ResolveInfo* pSym) = 0;
    148   /// setupTLSDynEntry - create DTPMOD / DTPREL relocation entries
    149   virtual void setupTLSDynEntry(Fragment& pFrag, ResolveInfo* pSym,
    150                                 Relocation::Type pType) = 0;
    151 
    152   /// isLocalReloc - handle relocation as a local symbol
    153   bool isLocalReloc(ResolveInfo& pSym) const;
    154 
    155   /// setupRelDynEntry - create dynamic relocation entry with specified type.
    156   void setupRelDynEntry(FragmentRef& pFragRef, ResolveInfo* pSym,
    157                         Relocation::Type pType);
    158 
    159  private:
    160   typedef llvm::DenseSet<Relocation*> RelocationSet;
    161   typedef llvm::DenseMap<const ResolveInfo*, RelocationSet> SymRelocSetMap;
    162 
    163  private:
    164   MipsGNULDBackend& m_Target;
    165   SymPLTMap m_SymPLTMap;
    166   SymGOTPLTMap m_SymGOTPLTMap;
    167   Input* m_pApplyingInput;
    168   SymRelocSetMap m_PostponedRelocs;
    169   MipsRelocationInfo* m_CurrentLo16Reloc;
    170 
    171  private:
    172   void scanLocalReloc(MipsRelocationInfo& pReloc,
    173                       IRBuilder& pBuilder,
    174                       const LDSection& pSection);
    175 
    176   void scanGlobalReloc(MipsRelocationInfo& pReloc,
    177                        IRBuilder& pBuilder,
    178                        const LDSection& pSection);
    179 
    180   /// isPostponed - relocation applying needs to be postponed.
    181   bool isPostponed(const Relocation& pReloc) const;
    182 
    183   /// addCopyReloc - add a copy relocation into .rel.dyn for pSym
    184   /// @param pSym - A resolved copy symbol that defined in BSS section
    185   void addCopyReloc(ResolveInfo& pSym);
    186 
    187   /// defineSymbolforCopyReloc - allocate a space in BSS section and
    188   /// and force define the copy of pSym to BSS section
    189   /// @return the output LDSymbol of the copy symbol
    190   LDSymbol& defineSymbolforCopyReloc(IRBuilder& pBuilder,
    191                                      const ResolveInfo& pSym);
    192 
    193   /// isRel - returns true if REL relocation record format is expected
    194   bool isRel() const;
    195 };
    196 
    197 /** \class Mips32Relocator
    198  *  \brief Mips32Relocator creates and destroys the Mips 32-bit relocations.
    199  */
    200 class Mips32Relocator : public MipsRelocator {
    201  public:
    202   Mips32Relocator(Mips32GNULDBackend& pParent, const LinkerConfig& pConfig);
    203 
    204  private:
    205   // MipsRelocator
    206   void setupRel32DynEntry(FragmentRef& pFragRef, ResolveInfo* pSym);
    207   void setupTLSDynEntry(Fragment& pFrag, ResolveInfo* pSym,
    208                         Relocation::Type pType);
    209   Size getSize(Relocation::Type pType) const;
    210 };
    211 
    212 /** \class Mips64Relocator
    213  *  \brief Mips64Relocator creates and destroys the Mips 64-bit relocations.
    214  */
    215 class Mips64Relocator : public MipsRelocator {
    216  public:
    217   Mips64Relocator(Mips64GNULDBackend& pParent, const LinkerConfig& pConfig);
    218 
    219  private:
    220   // MipsRelocator
    221   void setupRel32DynEntry(FragmentRef& pFragRef, ResolveInfo* pSym);
    222   void setupTLSDynEntry(Fragment& pFrag, ResolveInfo* pSym,
    223                         Relocation::Type pType);
    224   Size getSize(Relocation::Type pType) const;
    225 };
    226 
    227 }  // namespace mcld
    228 
    229 #endif  // TARGET_MIPS_MIPSRELOCATOR_H_
    230