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