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