1 //===- AArch64Relocator.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_AARCH64_AARCH64RELOCATOR_H_ 10 #define TARGET_AARCH64_AARCH64RELOCATOR_H_ 11 12 #include "mcld/LD/Relocator.h" 13 #include "mcld/Target/GOT.h" 14 #include "mcld/Target/KeyEntryMap.h" 15 #include "AArch64LDBackend.h" 16 17 namespace mcld { 18 19 /** \class AArch64Relocator 20 * \brief AArch64Relocator creates and destroys the AArch64 relocations. 21 * 22 */ 23 class AArch64Relocator : public Relocator { 24 public: 25 typedef KeyEntryMap<ResolveInfo, AArch64GOTEntry> SymGOTMap; 26 typedef KeyEntryMap<ResolveInfo, AArch64PLT1> SymPLTMap; 27 typedef KeyEntryMap<Relocation, Relocation> RelRelMap; 28 29 /** \enum ReservedEntryType 30 * \brief The reserved entry type of reserved space in ResolveInfo. 31 * 32 * This is used for sacnRelocation to record what kinds of entries are 33 * reserved for this resolved symbol In AArch64, there are three kinds of 34 * entries, GOT, PLT, and dynamic reloction. 35 * 36 * bit: 3 2 1 0 37 * | | PLT | GOT | Rel | 38 * 39 * value Name - Description 40 * 41 * 0000 None - no reserved entry 42 * 0001 ReserveRel - reserve an dynamic relocation entry 43 * 0010 ReserveGOT - reserve an GOT entry 44 * 0100 ReservePLT - reserve an PLT entry and the corresponding GOT, 45 * 46 */ 47 enum ReservedEntryType { 48 None = 0, 49 ReserveRel = 1, 50 ReserveGOT = 2, 51 ReservePLT = 4, 52 }; 53 54 /** \enum EntryValue 55 * \brief The value of the entries. The symbol value will be decided at after 56 * layout, so we mark the entry during scanRelocation and fill up the actual 57 * value when applying relocations. 58 */ 59 enum EntryValue { Default = 0, SymVal = 1 }; 60 61 enum { 62 // mcld internal relocation to rewrite an instruction. 63 R_AARCH64_REWRITE_INSN = 1, 64 }; 65 66 public: 67 AArch64Relocator(AArch64GNULDBackend& pParent, const LinkerConfig& pConfig); 68 ~AArch64Relocator(); 69 70 Result applyRelocation(Relocation& pRelocation); 71 72 AArch64GNULDBackend& getTarget() { return m_Target; } 73 74 const AArch64GNULDBackend& getTarget() const { return m_Target; } 75 76 const char* getName(Relocation::Type pType) const; 77 78 Size getSize(Relocation::Type pType) const; 79 80 const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; } 81 SymGOTMap& getSymGOTMap() { return m_SymGOTMap; } 82 83 const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; } 84 SymPLTMap& getSymPLTMap() { return m_SymPLTMap; } 85 86 const SymGOTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; } 87 SymGOTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; } 88 89 const RelRelMap& getRelRelMap() const { return m_RelRelMap; } 90 RelRelMap& getRelRelMap() { return m_RelRelMap; } 91 92 /// scanRelocation - determine the empty entries are needed or not and create 93 /// the empty entries if needed. 94 /// For AArch64, following entries are check to create: 95 /// - GOT entry (for .got section) 96 /// - PLT entry (for .plt section) 97 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 98 void scanRelocation(Relocation& pReloc, 99 IRBuilder& pBuilder, 100 Module& pModule, 101 LDSection& pSection, 102 Input& pInput); 103 104 /// mayHaveFunctionPointerAccess - check if the given reloc would possibly 105 /// access a function pointer. 106 virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const; 107 108 /// getDebugStringOffset - get the offset from the relocation target. This is 109 /// used to get the debug string offset. 110 uint32_t getDebugStringOffset(Relocation& pReloc) const; 111 112 /// applyDebugStringOffset - apply the relocation target to specific offset. 113 /// This is used to set the debug string offset. 114 void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset); 115 116 private: 117 void scanLocalReloc(Relocation& pReloc, const LDSection& pSection); 118 119 void scanGlobalReloc(Relocation& pReloc, 120 IRBuilder& pBuilder, 121 const LDSection& pSection); 122 123 /// addCopyReloc - add a copy relocation into .rel.dyn for pSym 124 /// @param pSym - A resolved copy symbol that defined in BSS section 125 void addCopyReloc(ResolveInfo& pSym); 126 127 /// defineSymbolforCopyReloc - allocate a space in BSS section and 128 /// and force define the copy of pSym to BSS section 129 /// @return the output LDSymbol of the copy symbol 130 LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker, 131 const ResolveInfo& pSym); 132 133 private: 134 AArch64GNULDBackend& m_Target; 135 SymGOTMap m_SymGOTMap; 136 SymPLTMap m_SymPLTMap; 137 SymGOTMap m_SymGOTPLTMap; 138 RelRelMap m_RelRelMap; 139 }; 140 141 } // namespace mcld 142 143 #endif // TARGET_AARCH64_AARCH64RELOCATOR_H_ 144