1 //===- ARMRelocator.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 ARM_RELOCATION_FACTORY_H 10 #define ARM_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/SymbolEntryMap.h> 18 #include "ARMLDBackend.h" 19 20 namespace mcld { 21 22 /** \class ARMRelocator 23 * \brief ARMRelocator creates and destroys the ARM relocations. 24 * 25 */ 26 class ARMRelocator : public Relocator 27 { 28 public: 29 typedef SymbolEntryMap<ARMGOTEntry> SymGOTMap; 30 typedef SymbolEntryMap<ARMPLT1> 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 37 * 38 * In ARM, there are three kinds of entries, GOT, PLT, and dynamic reloction. 39 * GOT may needs a corresponding relocation to relocate itself, so we 40 * separate GOT to two situations: GOT and GOTRel. Besides, for the same 41 * symbol, there might be two kinds of entries reserved for different location. 42 * For example, reference to the same symbol, one may use GOT and the other may 43 * use dynamic relocation. 44 * 45 * bit: 3 2 1 0 46 * | PLT | GOTRel | GOT | Rel | 47 * 48 * value Name - Description 49 * 50 * 0000 None - no reserved entry 51 * 0001 ReserveRel - reserve an dynamic relocation entry 52 * 0010 ReserveGOT - reserve an GOT entry 53 * 0011 GOTandRel - For different relocation, we've reserved GOT and 54 * Rel for different location. 55 * 0100 GOTRel - reserve an GOT entry and the corresponding Dyncamic 56 * relocation entry which relocate this GOT entry 57 * 0101 GOTRelandRel - For different relocation, we've reserved GOTRel 58 * and relocation entry for different location. 59 * 1000 ReservePLT - reserve an PLT entry and the corresponding GOT, 60 * Dynamic relocation entries 61 * 1001 PLTandRel - For different relocation, we've reserved PLT and 62 * Rel for different location. 63 */ 64 enum ReservedEntryType { 65 None = 0, 66 ReserveRel = 1, 67 ReserveGOT = 2, 68 GOTandRel = 3, 69 GOTRel = 4, 70 GOTRelandRel = 5, 71 ReservePLT = 8, 72 PLTandRel = 9 73 }; 74 75 public: 76 ARMRelocator(ARMGNULDBackend& pParent, const LinkerConfig& pConfig); 77 ~ARMRelocator(); 78 79 Result applyRelocation(Relocation& pRelocation); 80 81 ARMGNULDBackend& getTarget() 82 { return m_Target; } 83 84 const ARMGNULDBackend& getTarget() const 85 { return m_Target; } 86 87 const char* getName(Relocation::Type pType) const; 88 89 Size getSize(Relocation::Type pType) const; 90 91 const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; } 92 SymGOTMap& getSymGOTMap() { return m_SymGOTMap; } 93 94 const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; } 95 SymPLTMap& getSymPLTMap() { return m_SymPLTMap; } 96 97 const SymGOTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; } 98 SymGOTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; } 99 100 /// scanRelocation - determine the empty entries are needed or not and create 101 /// the empty entries if needed. 102 /// For ARM, following entries are check to create: 103 /// - GOT entry (for .got section) 104 /// - PLT entry (for .plt section) 105 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 106 void scanRelocation(Relocation& pReloc, 107 IRBuilder& pBuilder, 108 Module& pModule, 109 LDSection& pSection); 110 111 private: 112 void scanLocalReloc(Relocation& pReloc, const LDSection& pSection); 113 114 void scanGlobalReloc(Relocation& pReloc, 115 IRBuilder& pBuilder, 116 const LDSection& pSection); 117 118 void checkValidReloc(Relocation& pReloc) const; 119 120 /// addCopyReloc - add a copy relocation into .rel.dyn for pSym 121 /// @param pSym - A resolved copy symbol that defined in BSS section 122 void addCopyReloc(ResolveInfo& pSym); 123 124 /// defineSymbolforCopyReloc - allocate a space in BSS section and 125 /// and force define the copy of pSym to BSS section 126 /// @return the output LDSymbol of the copy symbol 127 LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker, 128 const ResolveInfo& pSym); 129 130 private: 131 ARMGNULDBackend& m_Target; 132 SymGOTMap m_SymGOTMap; 133 SymPLTMap m_SymPLTMap; 134 SymGOTMap m_SymGOTPLTMap; 135 }; 136 137 } // namespace of mcld 138 139 #endif 140 141