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