15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsGOT.h ----------------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_MIPS_GOT_H 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_MIPS_GOT_H 11f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <map> 12f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <vector> 13f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/ADT/DenseMap.h> 19f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <llvm/ADT/DenseSet.h> 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/ADT/SizeTraits.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GOT.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass Input; 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass LDSection; 28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass LDSymbol; 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MemoryRegion; 30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass OutputRelocSection; 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 32d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/** \class MipsGOTEntry 33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao * \brief GOT Entry with size of 4 bytes 34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao */ 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass MipsGOTEntry : public GOT::Entry<4> 36d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaopublic: 38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MipsGOTEntry(uint64_t pContent, SectionData* pParent); 39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}; 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class MipsGOT 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * \brief Mips Global Offset Table. 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MipsGOT : public GOT 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic: 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MipsGOT(LDSection& pSection); 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// Address of _gp_disp symbol. 50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SizeTraits<32>::Address getGPDispAddress() const; 51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t emit(MemoryRegion& pRegion); 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void initializeScan(const Input& pInput); 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void finalizeScan(const Input& pInput); 56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool reserveLocalEntry(ResolveInfo& pInfo); 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool reserveGlobalEntry(ResolveInfo& pInfo); 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t getLocalNum() const; ///< number of local symbols in primary GOT 61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t getGlobalNum() const; ///< total number of global symbols 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool isPrimaryGOTConsumed(); 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao MipsGOTEntry* consumeLocal(); 66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao MipsGOTEntry* consumeGlobal(); 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SizeTraits<32>::Address getGPAddr(const Input& pInput) const; 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SizeTraits<32>::Offset getGPRelOffset(const Input& pInput, 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const MipsGOTEntry& pEntry) const; 71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void recordEntry(const ResolveInfo* pInfo, MipsGOTEntry* pEntry); 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MipsGOTEntry* lookupEntry(const ResolveInfo* pInfo); 74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang void setLocal(const ResolveInfo* pInfo) { 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_GOTTypeMap[pInfo] = false; 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang void setGlobal(const ResolveInfo* pInfo) { 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_GOTTypeMap[pInfo] = true; 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bool isLocal(const ResolveInfo* pInfo) { 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return m_GOTTypeMap[pInfo] == false; 85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bool isGlobal(const ResolveInfo* pInfo) { 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return m_GOTTypeMap[pInfo] == true; 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// hasGOT1 - return if this got section has any GOT1 entry 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool hasGOT1() const; 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool hasMultipleGOT() const; 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// Create GOT entries and reserve dynrel entries. 97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void finalizeScanning(OutputRelocSection& pRelDyn); 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// Compare two symbols to define order in the .dynsym. 100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const; 101f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoprivate: 103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /** \class GOTMultipart 104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines * \brief GOTMultipart counts local and global entries in the GOT. 105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines */ 106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines struct GOTMultipart 107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GOTMultipart(size_t local = 0, size_t global = 0); 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef llvm::DenseSet<const Input*> InputSetType; 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t m_LocalNum; ///< number of reserved local entries 113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t m_GlobalNum; ///< number of reserved global entries 114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t m_ConsumedLocal; ///< consumed local entries 116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t m_ConsumedGlobal; ///< consumed global entries 117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MipsGOTEntry* m_pLastLocal; ///< the last consumed local entry 119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MipsGOTEntry* m_pLastGlobal; ///< the last consumed global entry 120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines InputSetType m_Inputs; 122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool isConsumed() const; 124f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 125f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void consumeLocal(); 126f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void consumeGlobal(); 127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }; 128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef std::vector<GOTMultipart> MultipartListType; 130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef llvm::DenseSet<const ResolveInfo*> SymbolSetType; 132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolUniqueMapType; 133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MultipartListType m_MultipartList; ///< list of GOT's descriptors 135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const Input* m_pInput; ///< current input 136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolSetType m_MergedGlobalSymbols; ///< merged global symbols from 137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolUniqueMapType m_InputGlobalSymbols; ///< input global symbols 138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolSetType m_MergedLocalSymbols; 139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolSetType m_InputLocalSymbols; 140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t m_CurrentGOTPart; 142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef llvm::DenseMap<const LDSymbol*, unsigned> SymbolOrderMapType; 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType m_SymbolOrderMap; 145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void initGOTList(); 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void changeInput(); 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool isGOTFull() const; 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void split(); 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void reserve(size_t pNum); 15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate: 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolTypeMapType; 154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolTypeMapType m_GOTTypeMap; 156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesprivate: 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines struct GotEntryKey 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t m_GOTPage; 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const ResolveInfo* m_pInfo; 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool operator<(const GotEntryKey& key) const 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_GOTPage == key.m_GOTPage) 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_pInfo < key.m_pInfo; 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_GOTPage < key.m_GOTPage; 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }; 171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines typedef std::map<GotEntryKey, MipsGOTEntry*> GotEntryMapType; 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryMapType m_GotEntriesMap; 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif 179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 180