1 //===- X86Relocator.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_X86_X86RELOCATOR_H_ 10 #define TARGET_X86_X86RELOCATOR_H_ 11 12 #include "mcld/LD/Relocator.h" 13 #include "mcld/Target/GOT.h" 14 #include "mcld/Target/PLT.h" 15 #include "mcld/Target/KeyEntryMap.h" 16 #include "X86LDBackend.h" 17 18 namespace mcld { 19 20 class LinkerConfig; 21 class ResolveInfo; 22 23 /** \class X86Relocator 24 * \brief X86Relocator creates and destroys the X86 relocations. 25 * 26 */ 27 class X86Relocator : public Relocator { 28 public: 29 typedef KeyEntryMap<ResolveInfo, PLTEntryBase> SymPLTMap; 30 31 /** \enum ReservedEntryType 32 * \brief The reserved entry type of reserved space in ResolveInfo. 33 * 34 * This is used for sacnRelocation to record what kinds of entries are 35 * reserved for this resolved symbol. In X86, there are three kinds of 36 * entries, GOT, PLT, and dynamic reloction. 37 * 38 * bit: 3 2 1 0 39 * | | PLT | GOT | Rel | 40 * 41 * value Name - Description 42 * 43 * 0000 None - no reserved entry 44 * 0001 ReserveRel - reserve an dynamic relocation entry 45 * 0010 ReserveGOT - reserve an GOT entry 46 * 0100 ReservePLT - reserve an PLT entry and the corresponding GOT, 47 * 48 */ 49 enum ReservedEntryType { 50 None = 0, 51 ReserveRel = 1, 52 ReserveGOT = 2, 53 ReservePLT = 4, 54 }; 55 56 /** \enum EntryValue 57 * \brief The value of the entries. The symbol value will be decided at after 58 * layout, so we mark the entry during scanRelocation and fill up the actual 59 * value when applying relocations. 60 */ 61 enum EntryValue { Default = 0, SymVal = 1 }; 62 63 public: 64 explicit X86Relocator(const LinkerConfig& pConfig); 65 ~X86Relocator(); 66 67 virtual Result applyRelocation(Relocation& pRelocation) = 0; 68 69 virtual const char* getName(Relocation::Type pType) const = 0; 70 71 const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; } 72 SymPLTMap& getSymPLTMap() { return m_SymPLTMap; } 73 74 /// scanRelocation - determine the empty entries are needed or not and create 75 /// the empty entries if needed. 76 /// For X86, following entries are check to create: 77 /// - GOT entry (for .got and .got.plt sections) 78 /// - PLT entry (for .plt section) 79 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 80 void scanRelocation(Relocation& pReloc, 81 IRBuilder& pBuilder, 82 Module& pModule, 83 LDSection& pSection, 84 Input& pInput); 85 86 protected: 87 /// addCopyReloc - add a copy relocation into .rel.dyn for pSym 88 /// @param pSym - A resolved copy symbol that defined in BSS section 89 void addCopyReloc(ResolveInfo& pSym, X86GNULDBackend& pTarget); 90 91 /// defineSymbolforCopyReloc - allocate a space in BSS section and 92 /// and force define the copy of pSym to BSS section 93 /// @return the output LDSymbol of the copy symbol 94 LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker, 95 const ResolveInfo& pSym, 96 X86GNULDBackend& pTarget); 97 98 private: 99 virtual void scanLocalReloc(Relocation& pReloc, 100 IRBuilder& pBuilder, 101 Module& pModule, 102 LDSection& pSection) = 0; 103 104 virtual void scanGlobalReloc(Relocation& pReloc, 105 IRBuilder& pBuilder, 106 Module& pModule, 107 LDSection& pSection) = 0; 108 109 private: 110 SymPLTMap m_SymPLTMap; 111 }; 112 113 /** \class X86_32Relocator 114 * \brief X86_32Relocator creates and destroys the X86-32 relocations. 115 * 116 */ 117 class X86_32Relocator : public X86Relocator { 118 public: 119 typedef KeyEntryMap<ResolveInfo, X86_32GOTEntry> SymGOTMap; 120 typedef KeyEntryMap<ResolveInfo, X86_32GOTEntry> SymGOTPLTMap; 121 122 enum { 123 R_386_TLS_OPT = 44 // mcld internal relocation type 124 }; 125 126 public: 127 X86_32Relocator(X86_32GNULDBackend& pParent, const LinkerConfig& pConfig); 128 129 Result applyRelocation(Relocation& pRelocation); 130 131 X86_32GNULDBackend& getTarget() { return m_Target; } 132 133 const X86_32GNULDBackend& getTarget() const { return m_Target; } 134 135 const char* getName(Relocation::Type pType) const; 136 137 Size getSize(Relocation::Type pType) const; 138 139 const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; } 140 SymGOTMap& getSymGOTMap() { return m_SymGOTMap; } 141 142 const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; } 143 SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; } 144 145 X86_32GOTEntry& getTLSModuleID(); 146 147 /// mayHaveFunctionPointerAccess - check if the given reloc would possibly 148 /// access a function pointer. 149 virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const; 150 151 /// getDebugStringOffset - get the offset from the relocation target. This is 152 /// used to get the debug string offset. 153 uint32_t getDebugStringOffset(Relocation& pReloc) const; 154 155 /// applyDebugStringOffset - apply the relocation target to specific offset. 156 /// This is used to set the debug string offset. 157 void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset); 158 159 private: 160 void scanLocalReloc(Relocation& pReloc, 161 IRBuilder& pBuilder, 162 Module& pModule, 163 LDSection& pSection); 164 165 void scanGlobalReloc(Relocation& pReloc, 166 IRBuilder& pBuilder, 167 Module& pModule, 168 LDSection& pSection); 169 170 /// ----- tls optimization ----- /// 171 /// convert R_386_TLS_IE to R_386_TLS_LE 172 void convertTLSIEtoLE(Relocation& pReloc, LDSection& pSection); 173 174 private: 175 X86_32GNULDBackend& m_Target; 176 SymGOTMap m_SymGOTMap; 177 SymGOTPLTMap m_SymGOTPLTMap; 178 }; 179 180 /** \class X86_64Relocator 181 * \brief X86_64Relocator creates and destroys the X86-64 relocations. 182 * 183 */ 184 class X86_64Relocator : public X86Relocator { 185 public: 186 typedef KeyEntryMap<ResolveInfo, X86_64GOTEntry> SymGOTMap; 187 typedef KeyEntryMap<ResolveInfo, X86_64GOTEntry> SymGOTPLTMap; 188 typedef KeyEntryMap<Relocation, Relocation> RelRelMap; 189 190 public: 191 X86_64Relocator(X86_64GNULDBackend& pParent, const LinkerConfig& pConfig); 192 193 Result applyRelocation(Relocation& pRelocation); 194 195 X86_64GNULDBackend& getTarget() { return m_Target; } 196 197 const X86_64GNULDBackend& getTarget() const { return m_Target; } 198 199 const char* getName(Relocation::Type pType) const; 200 201 Size getSize(Relocation::Type pType) const; 202 203 const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; } 204 SymGOTMap& getSymGOTMap() { return m_SymGOTMap; } 205 206 const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; } 207 SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; } 208 209 const RelRelMap& getRelRelMap() const { return m_RelRelMap; } 210 RelRelMap& getRelRelMap() { return m_RelRelMap; } 211 212 /// mayHaveFunctionPointerAccess - check if the given reloc would possibly 213 /// access a function pointer. 214 virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const; 215 216 /// getDebugStringOffset - get the offset from the relocation target. This is 217 /// used to get the debug string offset. 218 uint32_t getDebugStringOffset(Relocation& pReloc) const; 219 220 /// applyDebugStringOffset - apply the relocation target to specific offset. 221 /// This is used to set the debug string offset. 222 void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset); 223 224 private: 225 void scanLocalReloc(Relocation& pReloc, 226 IRBuilder& pBuilder, 227 Module& pModule, 228 LDSection& pSection); 229 230 void scanGlobalReloc(Relocation& pReloc, 231 IRBuilder& pBuilder, 232 Module& pModule, 233 LDSection& pSection); 234 235 private: 236 X86_64GNULDBackend& m_Target; 237 SymGOTMap m_SymGOTMap; 238 SymGOTPLTMap m_SymGOTPLTMap; 239 RelRelMap m_RelRelMap; 240 }; 241 242 } // namespace mcld 243 244 #endif // TARGET_X86_X86RELOCATOR_H_ 245