1 //===- MipsGOT.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 MCLD_MIPS_GOT_H 10 #define MCLD_MIPS_GOT_H 11 #include <map> 12 #include <vector> 13 14 #ifdef ENABLE_UNITTEST 15 #include <gtest.h> 16 #endif 17 18 #include <llvm/ADT/DenseMap.h> 19 #include <llvm/ADT/DenseSet.h> 20 21 #include <mcld/ADT/SizeTraits.h> 22 #include <mcld/Target/GOT.h> 23 24 namespace mcld 25 { 26 class Input; 27 class LDSection; 28 class LDSymbol; 29 class MemoryRegion; 30 class OutputRelocSection; 31 32 /** \class MipsGOTEntry 33 * \brief GOT Entry with size of 4 bytes 34 */ 35 class MipsGOTEntry : public GOT::Entry<4> 36 { 37 public: 38 MipsGOTEntry(uint64_t pContent, SectionData* pParent); 39 }; 40 41 /** \class MipsGOT 42 * \brief Mips Global Offset Table. 43 */ 44 class MipsGOT : public GOT 45 { 46 public: 47 MipsGOT(LDSection& pSection); 48 49 /// Address of _gp_disp symbol. 50 SizeTraits<32>::Address getGPDispAddress() const; 51 52 uint64_t emit(MemoryRegion& pRegion); 53 54 void initializeScan(const Input& pInput); 55 void finalizeScan(const Input& pInput); 56 57 bool reserveLocalEntry(ResolveInfo& pInfo); 58 bool reserveGlobalEntry(ResolveInfo& pInfo); 59 60 size_t getLocalNum() const; ///< number of local symbols in primary GOT 61 size_t getGlobalNum() const; ///< total number of global symbols 62 63 bool isPrimaryGOTConsumed(); 64 65 MipsGOTEntry* consumeLocal(); 66 MipsGOTEntry* consumeGlobal(); 67 68 SizeTraits<32>::Address getGPAddr(const Input& pInput) const; 69 SizeTraits<32>::Offset getGPRelOffset(const Input& pInput, 70 const MipsGOTEntry& pEntry) const; 71 72 void recordEntry(const ResolveInfo* pInfo, MipsGOTEntry* pEntry); 73 MipsGOTEntry* lookupEntry(const ResolveInfo* pInfo); 74 75 void setLocal(const ResolveInfo* pInfo) { 76 m_GOTTypeMap[pInfo] = false; 77 } 78 79 void setGlobal(const ResolveInfo* pInfo) { 80 m_GOTTypeMap[pInfo] = true; 81 } 82 83 bool isLocal(const ResolveInfo* pInfo) { 84 return m_GOTTypeMap[pInfo] == false; 85 } 86 87 bool isGlobal(const ResolveInfo* pInfo) { 88 return m_GOTTypeMap[pInfo] == true; 89 } 90 91 /// hasGOT1 - return if this got section has any GOT1 entry 92 bool hasGOT1() const; 93 94 bool hasMultipleGOT() const; 95 96 /// Create GOT entries and reserve dynrel entries. 97 void finalizeScanning(OutputRelocSection& pRelDyn); 98 99 /// Compare two symbols to define order in the .dynsym. 100 bool dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const; 101 102 private: 103 /** \class GOTMultipart 104 * \brief GOTMultipart counts local and global entries in the GOT. 105 */ 106 struct GOTMultipart 107 { 108 GOTMultipart(size_t local = 0, size_t global = 0); 109 110 typedef llvm::DenseSet<const Input*> InputSetType; 111 112 size_t m_LocalNum; ///< number of reserved local entries 113 size_t m_GlobalNum; ///< number of reserved global entries 114 115 size_t m_ConsumedLocal; ///< consumed local entries 116 size_t m_ConsumedGlobal; ///< consumed global entries 117 118 MipsGOTEntry* m_pLastLocal; ///< the last consumed local entry 119 MipsGOTEntry* m_pLastGlobal; ///< the last consumed global entry 120 121 InputSetType m_Inputs; 122 123 bool isConsumed() const; 124 125 void consumeLocal(); 126 void consumeGlobal(); 127 }; 128 129 typedef std::vector<GOTMultipart> MultipartListType; 130 131 typedef llvm::DenseSet<const ResolveInfo*> SymbolSetType; 132 typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolUniqueMapType; 133 134 MultipartListType m_MultipartList; ///< list of GOT's descriptors 135 const Input* m_pInput; ///< current input 136 SymbolSetType m_MergedGlobalSymbols; ///< merged global symbols from 137 SymbolUniqueMapType m_InputGlobalSymbols; ///< input global symbols 138 SymbolSetType m_MergedLocalSymbols; 139 SymbolSetType m_InputLocalSymbols; 140 141 size_t m_CurrentGOTPart; 142 143 typedef llvm::DenseMap<const LDSymbol*, unsigned> SymbolOrderMapType; 144 SymbolOrderMapType m_SymbolOrderMap; 145 146 void initGOTList(); 147 void changeInput(); 148 bool isGOTFull() const; 149 void split(); 150 void reserve(size_t pNum); 151 152 private: 153 typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolTypeMapType; 154 155 SymbolTypeMapType m_GOTTypeMap; 156 157 private: 158 struct GotEntryKey 159 { 160 size_t m_GOTPage; 161 const ResolveInfo* m_pInfo; 162 163 bool operator<(const GotEntryKey& key) const 164 { 165 if (m_GOTPage == key.m_GOTPage) 166 return m_pInfo < key.m_pInfo; 167 else 168 return m_GOTPage < key.m_GOTPage; 169 } 170 }; 171 172 typedef std::map<GotEntryKey, MipsGOTEntry*> GotEntryMapType; 173 GotEntryMapType m_GotEntriesMap; 174 }; 175 176 } // namespace of mcld 177 178 #endif 179 180