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