15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsGOT.cpp --------------------------------------------------------===// 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 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 11f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <llvm/Support/ELF.h> 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ResolveInfo.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 16f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Target/OutputRelocSection.h> 17f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 18f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "MipsGOT.h" 19f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "MipsRelocator.h" 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const size_t MipsGOT0Num = 1; 23f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const size_t MipsGOTGpOffset = 0x7FF0; 24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const size_t MipsGOTSize = MipsGOTGpOffset + 0x7FFF; 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOTEntry 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOTEntry::MipsGOTEntry(uint64_t pContent, SectionData* pParent) 33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines : GOT::Entry<4>(pContent, pParent) 34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{} 35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOT::GOTMultipart 38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOT::GOTMultipart::GOTMultipart(size_t local, size_t global) 40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines : m_LocalNum(local), 41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_GlobalNum(global), 42f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_ConsumedLocal(0), 43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_ConsumedGlobal(0), 44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pLastLocal(NULL), 45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pLastGlobal(NULL) 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::GOTMultipart::isConsumed() const 50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_LocalNum == m_ConsumedLocal && 52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_GlobalNum == m_ConsumedGlobal; 53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::GOTMultipart::consumeLocal() 56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_ConsumedLocal < m_LocalNum && 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "Consumed too many local GOT entries"); 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_ConsumedLocal; 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pLastLocal = llvm::cast<MipsGOTEntry>(m_pLastLocal->getNextNode()); 61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::GOTMultipart::consumeGlobal() 64f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 65f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_ConsumedGlobal < m_GlobalNum && 66f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "Consumed too many global GOT entries"); 67f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_ConsumedGlobal; 68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pLastGlobal = llvm::cast<MipsGOTEntry>(m_pLastGlobal->getNextNode()); 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOT 73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOT::MipsGOT(LDSection& pSection) 75f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines : GOT(pSection), 76f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput(NULL), 77f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_CurrentGOTPart(0) 78f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 81f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesSizeTraits<32>::Address MipsGOT::getGPDispAddress() const 82f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 83f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return addr() + MipsGOTGpOffset; 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 86d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid MipsGOT::reserve(size_t pNum) 87d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 88d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao for (size_t i = 0; i < pNum; i++) { 89d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao new MipsGOTEntry(0, m_SectionData); 90d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 91d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 92d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::hasGOT1() const 94d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return !m_MultipartList.empty(); 96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::hasMultipleGOT() const 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList.size() > 1; 101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::finalizeScanning(OutputRelocSection& pRelDyn) 104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (MultipartListType::iterator it = m_MultipartList.begin(); 106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != m_MultipartList.end(); ++it) { 107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(MipsGOT0Num); 108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it->m_pLastLocal = llvm::cast<MipsGOTEntry>(&m_SectionData->back()); 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(it->m_LocalNum); 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it->m_pLastGlobal = llvm::cast<MipsGOTEntry>(&m_SectionData->back()); 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(it->m_GlobalNum); 112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it == m_MultipartList.begin()) 114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Reserve entries in the second part of the primary GOT. 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // These entries correspond to the global symbols in all 116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // non-primary GOTs. 117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(getGlobalNum() - it->m_GlobalNum); 118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Reserve reldyn entries for R_MIPS_REL32 relocations 120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for all global entries of secondary GOTs. 121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: (simon) Do not count local entries for non-pic. 122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t count = it->m_GlobalNum + it->m_LocalNum; 123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (size_t i = 0; i < count; ++i) 124f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pRelDyn.reserveEntry(); 125f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 126f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType::const_iterator itX = m_SymbolOrderMap.find(pX); 132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType::const_iterator itY = m_SymbolOrderMap.find(pY); 133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (itX != m_SymbolOrderMap.end() && itY != m_SymbolOrderMap.end()) 135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return itX->second < itY->second; 136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return itX == m_SymbolOrderMap.end() && itY != m_SymbolOrderMap.end(); 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGOT::emit(MemoryRegion& pRegion) 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = 0; 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (iterator it = begin(), ie = end(); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao it != ie; ++it, ++buffer) { 147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao MipsGOTEntry* got = &(llvm::cast<MipsGOTEntry>((*it))); 148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao *buffer = static_cast<uint32_t>(got->getValue()); 149d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao result += got->size(); 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::initGOTList() 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SymbolOrderMap.clear(); 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.clear(); 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.push_back(GOTMultipart()); 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.clear(); 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.clear(); 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.clear(); 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.clear(); 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::changeInput() 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolSetType::iterator it = m_InputLocalSymbols.begin(), 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputLocalSymbols.end(); 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != end; ++it) 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.insert(*it); 177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.clear(); 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolUniqueMapType::iterator it = m_InputGlobalSymbols.begin(), 181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputGlobalSymbols.end(); 182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != end; ++it) 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.insert(it->first); 184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.clear(); 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::isGOTFull() const 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t gotCount = MipsGOT0Num + 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_LocalNum + 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_GlobalNum; 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotCount += 1; 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 196f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return (gotCount * mcld::MipsGOTEntry::EntrySize) > MipsGOTSize; 197f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::split() 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 201f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.clear(); 202f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.clear(); 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 204f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t uniqueCount = 0; 205f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolUniqueMapType::const_iterator it = m_InputGlobalSymbols.begin(), 206f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputGlobalSymbols.end(); 207f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != end; ++it) { 208f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it->second) 209f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++uniqueCount; 210f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 211f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 212f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_LocalNum -= m_InputLocalSymbols.size(); 213f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_GlobalNum -= uniqueCount; 214f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.erase(m_pInput); 215f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 216f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.push_back(GOTMultipart(m_InputLocalSymbols.size(), 217f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.size())); 218f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 219f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 220f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 221f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::initializeScan(const Input& pInput) 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 223f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pInput == NULL) { 224f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput = &pInput; 225f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines initGOTList(); 226f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 227f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 228f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput = &pInput; 229f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines changeInput(); 230f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 231f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 232f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 233f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::finalizeScan(const Input& pInput) 234f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 235f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 236f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 237f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::reserveLocalEntry(ResolveInfo& pInfo) 238f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 239f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pInfo.type() != ResolveInfo::Section) { 240f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_InputLocalSymbols.count(&pInfo)) 241f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 242f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 243f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MergedLocalSymbols.count(&pInfo)) { 244f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.insert(&pInfo); 245f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 246f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 247f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 248f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 249f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isGOTFull()) 250f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines split(); 251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 252f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pInfo.type() != ResolveInfo::Section) 253f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.insert(&pInfo); 254f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_MultipartList.back().m_LocalNum; 256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 258f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 259f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::reserveGlobalEntry(ResolveInfo& pInfo) 260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_InputGlobalSymbols.count(&pInfo)) 262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 263f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 264f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MergedGlobalSymbols.count(&pInfo)) { 265f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols[&pInfo] = false; 266f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isGOTFull()) 270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines split(); 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols[&pInfo] = true; 273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_MultipartList.back().m_GlobalNum; 274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 275f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!(pInfo.reserved() & MipsRelocator::ReserveGot)) { 276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SymbolOrderMap[pInfo.outSymbol()] = m_SymbolOrderMap.size(); 277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pInfo.setReserved(pInfo.reserved() | MipsRelocator::ReserveGot); 278f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 279f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 280f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 283f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::isPrimaryGOTConsumed() 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_CurrentGOTPart > 0; 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 288d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsGOTEntry* MipsGOT::consumeLocal() 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 290f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && "GOT number is out of range!"); 291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 292f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 293f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_CurrentGOTPart; 294f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 295f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeLocal(); 296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 297f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastLocal; 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 300d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoMipsGOTEntry* MipsGOT::consumeGlobal() 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 302f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && "GOT number is out of range!"); 303f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 304f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 305f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_CurrentGOTPart; 306f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 307f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeGlobal(); 308f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 309f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastGlobal; 3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 312f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesSizeTraits<32>::Address MipsGOT::getGPAddr(const Input& pInput) const 3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 314f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t gotSize = 0; 315f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (MultipartListType::const_iterator it = m_MultipartList.begin(); 316f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != m_MultipartList.end(); ++it) { 317f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it->m_Inputs.count(&pInput)) 318f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 319f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 320f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotSize += (MipsGOT0Num + it->m_LocalNum + it->m_GlobalNum); 321f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it == m_MultipartList.begin()) 322f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotSize += getGlobalNum() - it->m_GlobalNum; 323f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 324f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 325f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return addr() + gotSize * MipsGOTEntry::EntrySize + MipsGOTGpOffset; 326f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 327f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 328f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesSizeTraits<32>::Offset MipsGOT::getGPRelOffset(const Input& pInput, 329f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const MipsGOTEntry& pEntry) const 330f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 331f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SizeTraits<32>::Address gpAddr = getGPAddr(pInput); 332f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return addr() + pEntry.getOffset() - gpAddr; 333f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::recordEntry(const ResolveInfo* pInfo, MipsGOTEntry* pEntry) 336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryKey key; 338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_pInfo = pInfo; 340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_GotEntriesMap[key] = pEntry; 341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOTEntry* MipsGOT::lookupEntry(const ResolveInfo* pInfo) 344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryKey key; 346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_GOTPage= m_CurrentGOTPart; 347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_pInfo = pInfo; 348f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryMapType::iterator it = m_GotEntriesMap.find(key); 349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it == m_GotEntriesMap.end()) 351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return NULL; 352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return it->second; 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t MipsGOT::getLocalNum() const 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(!m_MultipartList.empty() && "GOT is empty!"); 359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[0].m_LocalNum + MipsGOT0Num; 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinessize_t MipsGOT::getGlobalNum() const 363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 364f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_SymbolOrderMap.size(); 365f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 366