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> 14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 15f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Target/OutputRelocSection.h> 16f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 17f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "MipsGOT.h" 18f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "MipsRelocator.h" 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const uint32_t Mips32ModulePtr = 1 << 31; 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const uint64_t Mips64ModulePtr = 1ull << 63; 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const size_t MipsGOT0Num = 2; 24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const size_t MipsGOTGpOffset = 0x7FF0; 25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const size_t MipsGOTSize = MipsGOTGpOffset + 0x7FFF; 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOT::GOTMultipart 32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOT::GOTMultipart::GOTMultipart(size_t local, size_t global) 34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines : m_LocalNum(local), 35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_GlobalNum(global), 36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_ConsumedLocal(0), 37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_ConsumedGlobal(0), 38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pLastLocal(NULL), 39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pLastGlobal(NULL) 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::GOTMultipart::isConsumed() const 44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_LocalNum == m_ConsumedLocal && 46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_GlobalNum == m_ConsumedGlobal; 47f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::GOTMultipart::consumeLocal() 50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_ConsumedLocal < m_LocalNum && 52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "Consumed too many local GOT entries"); 53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_ConsumedLocal; 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pLastLocal = m_pLastLocal->getNextNode(); 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::GOTMultipart::consumeGlobal() 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_ConsumedGlobal < m_GlobalNum && 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "Consumed too many global GOT entries"); 61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_ConsumedGlobal; 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pLastGlobal = m_pLastGlobal->getNextNode(); 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 64f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// MipsGOT::LocalEntry 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesMipsGOT::LocalEntry::LocalEntry(const ResolveInfo* pInfo, 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::DWord addend, bool isGot16) 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines : m_pInfo(pInfo), 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Addend(addend), 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_IsGot16(isGot16) 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool MipsGOT::LocalEntry::operator<(const LocalEntry &O) const 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_pInfo != O.m_pInfo) 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_pInfo < O.m_pInfo; 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_Addend != O.m_Addend) 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_Addend < O.m_Addend; 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_IsGot16 < O.m_IsGot16; 85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOT 89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOT::MipsGOT(LDSection& pSection) 91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines : GOT(pSection), 92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput(NULL), 93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_CurrentGOTPart(0) 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t MipsGOT::getGPDispAddress() const 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return addr() + MipsGOTGpOffset; 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid MipsGOT::reserve(size_t pNum) 103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (size_t i = 0; i < pNum; i++) 105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(0, m_SectionData); 106d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 107d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::hasGOT1() const 109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return !m_MultipartList.empty(); 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 112d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::hasMultipleGOT() const 114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList.size() > 1; 116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::finalizeScanning(OutputRelocSection& pRelDyn) 119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (MultipartListType::iterator it = m_MultipartList.begin(); 121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != m_MultipartList.end(); ++it) { 122f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reserveHeader(); 123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines it->m_pLastLocal = &m_SectionData->back(); 124f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(it->m_LocalNum); 125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines it->m_pLastGlobal = &m_SectionData->back(); 126f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(it->m_GlobalNum); 127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it == m_MultipartList.begin()) 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Reserve entries in the second part of the primary GOT. 130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // These entries correspond to the global symbols in all 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // non-primary GOTs. 132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(getGlobalNum() - it->m_GlobalNum); 133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Reserve reldyn entries for R_MIPS_REL32 relocations 135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for all global entries of secondary GOTs. 136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: (simon) Do not count local entries for non-pic. 137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t count = it->m_GlobalNum + it->m_LocalNum; 138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (size_t i = 0; i < count; ++i) 139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pRelDyn.reserveEntry(); 140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType::const_iterator itX = m_SymbolOrderMap.find(pX); 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType::const_iterator itY = m_SymbolOrderMap.find(pY); 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (itX != m_SymbolOrderMap.end() && itY != m_SymbolOrderMap.end()) 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return itX->second < itY->second; 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return itX == m_SymbolOrderMap.end() && itY != m_SymbolOrderMap.end(); 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::initGOTList() 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SymbolOrderMap.clear(); 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.clear(); 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.push_back(GOTMultipart()); 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.clear(); 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.clear(); 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.clear(); 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.clear(); 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::changeInput() 171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 174f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (LocalSymbolSetType::iterator it = m_InputLocalSymbols.begin(), 175f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines end = m_InputLocalSymbols.end(); 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != end; ++it) 177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.insert(*it); 178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.clear(); 180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolUniqueMapType::iterator it = m_InputGlobalSymbols.begin(), 182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputGlobalSymbols.end(); 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != end; ++it) 184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.insert(it->first); 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.clear(); 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::isGOTFull() const 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t gotCount = MipsGOT0Num + 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_LocalNum + 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_GlobalNum; 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotCount += 1; 196f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 197f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return gotCount * getEntrySize() > MipsGOTSize; 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::split() 201f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 202f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.clear(); 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.clear(); 204f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 205f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t uniqueCount = 0; 206f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolUniqueMapType::const_iterator it = m_InputGlobalSymbols.begin(), 207f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputGlobalSymbols.end(); 208f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != end; ++it) { 209f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it->second) 210f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++uniqueCount; 211f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 212f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 213f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_LocalNum -= m_InputLocalSymbols.size(); 214f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_GlobalNum -= uniqueCount; 215f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.erase(m_pInput); 216f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 217f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.push_back(GOTMultipart(m_InputLocalSymbols.size(), 218f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.size())); 219f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 220f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 221f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 222f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::initializeScan(const Input& pInput) 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 224f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pInput == NULL) { 225f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput = &pInput; 226f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines initGOTList(); 227f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 228f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 229f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput = &pInput; 230f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines changeInput(); 231f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 232f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 233f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 234f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid MipsGOT::finalizeScan(const Input& pInput) 235f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 236f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 237f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 238f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool MipsGOT::reserveLocalEntry(ResolveInfo& pInfo, int reloc, 239f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::DWord pAddend) 240f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 241f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LocalEntry entry(&pInfo, pAddend, reloc == llvm::ELF::R_MIPS_GOT16); 242f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 243f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_InputLocalSymbols.count(entry)) 244f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Do nothing, if we have seen this symbol 245f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // in the current input already. 246f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 248f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_MergedLocalSymbols.count(entry)) { 249f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // We have seen this symbol in previous inputs. 250f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Remember that it exists in the current input too. 251f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_InputLocalSymbols.insert(entry); 252f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 253f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 254f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isGOTFull()) 256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines split(); 257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 258f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_InputLocalSymbols.insert(entry); 259f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_MultipartList.back().m_LocalNum; 261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 263f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 264f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::reserveGlobalEntry(ResolveInfo& pInfo) 265f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 266f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_InputGlobalSymbols.count(&pInfo)) 267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MergedGlobalSymbols.count(&pInfo)) { 270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols[&pInfo] = false; 271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isGOTFull()) 275f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines split(); 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols[&pInfo] = true; 278f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_MultipartList.back().m_GlobalNum; 279f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 280f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!(pInfo.reserved() & MipsRelocator::ReserveGot)) { 281f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SymbolOrderMap[pInfo.outSymbol()] = m_SymbolOrderMap.size(); 282f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pInfo.setReserved(pInfo.reserved() | MipsRelocator::ReserveGot); 283f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 284f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool MipsGOT::isPrimaryGOTConsumed() 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 290f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_CurrentGOTPart > 0; 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 293f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* MipsGOT::consumeLocal() 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 295f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && "GOT number is out of range!"); 296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 297f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 298f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_CurrentGOTPart; 299f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 300f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeLocal(); 301f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 302f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastLocal; 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 305f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* MipsGOT::consumeGlobal() 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 307f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && "GOT number is out of range!"); 308f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 309f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 310f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_CurrentGOTPart; 311f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 312f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeGlobal(); 313f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 314f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastGlobal; 3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 317f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t MipsGOT::getGPAddr(const Input& pInput) const 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 319f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t gotSize = 0; 320f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (MultipartListType::const_iterator it = m_MultipartList.begin(); 321f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines it != m_MultipartList.end(); ++it) { 322f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it->m_Inputs.count(&pInput)) 323f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 324f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 325f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotSize += (MipsGOT0Num + it->m_LocalNum + it->m_GlobalNum); 326f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it == m_MultipartList.begin()) 327f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotSize += getGlobalNum() - it->m_GlobalNum; 328f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 329f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 330f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return addr() + gotSize * getEntrySize() + MipsGOTGpOffset; 331f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 332f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 333f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t MipsGOT::getGPRelOffset(const Input& pInput, 334f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const Fragment& pEntry) const 335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 336f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return addr() + pEntry.getOffset() - getGPAddr(pInput); 337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 339f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid MipsGOT::recordGlobalEntry(const ResolveInfo* pInfo, Fragment* pEntry) 340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryKey key; 342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_pInfo = pInfo; 344f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = 0; 345f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_GotGlobalEntriesMap[key] = pEntry; 346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 348f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* MipsGOT::lookupGlobalEntry(const ResolveInfo* pInfo) 349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryKey key; 351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_GOTPage= m_CurrentGOTPart; 352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_pInfo = pInfo; 353f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = 0; 354f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryMapType::iterator it = m_GotGlobalEntriesMap.find(key); 355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 356f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (it == m_GotGlobalEntriesMap.end()) 357f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 358f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 359f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return it->second; 360f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 361f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 362f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid MipsGOT::recordLocalEntry(const ResolveInfo* pInfo, 363f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::DWord pAddend, 364f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Fragment* pEntry) 365f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 366f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryKey key; 367f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 368f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_pInfo = pInfo; 369f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = pAddend; 370f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_GotLocalEntriesMap[key] = pEntry; 371f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 372f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 373f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* MipsGOT::lookupLocalEntry(const ResolveInfo* pInfo, 374f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::DWord pAddend) 375f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 376f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryKey key; 377f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_GOTPage= m_CurrentGOTPart; 378f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_pInfo = pInfo; 379f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = pAddend; 380f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryMapType::iterator it = m_GotLocalEntriesMap.find(key); 381f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 382f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (it == m_GotLocalEntriesMap.end()) 383f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return NULL; 384f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 385f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return it->second; 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t MipsGOT::getLocalNum() const 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 390f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(!m_MultipartList.empty() && "GOT is empty!"); 391f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[0].m_LocalNum + MipsGOT0Num; 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 393affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 394f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinessize_t MipsGOT::getGlobalNum() const 395f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 396f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_SymbolOrderMap.size(); 397f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 398f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 399f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 400f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// Mips32GOT 401f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 402f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesMips32GOT::Mips32GOT(LDSection& pSection) 403f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines : MipsGOT(pSection) 404f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{} 405f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 406f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid Mips32GOT::setEntryValue(Fragment* entry, uint64_t pValue) 407f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 408f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<Mips32GOTEntry>(entry)->setValue(pValue); 409f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 410f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 411f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t Mips32GOT::emit(MemoryRegion& pRegion) 412f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 413f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 414f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 415f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t result = 0; 416f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 417f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Mips32GOTEntry* got = &(llvm::cast<Mips32GOTEntry>((*it))); 418f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 419f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result += got->size(); 420f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 421f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 422f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 423f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 424f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* Mips32GOT::createEntry(uint64_t pValue, SectionData* pParent) 425f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 426f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return new Mips32GOTEntry(pValue, pParent); 427f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 428f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 429f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinessize_t Mips32GOT::getEntrySize() const 430f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 431f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return Mips32GOTEntry::EntrySize; 432f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 433f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 434f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid Mips32GOT::reserveHeader() 435f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 436f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(0, m_SectionData); 437f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(Mips32ModulePtr, m_SectionData); 438f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 439f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 440f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 441f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// Mips64GOT 442f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 443f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesMips64GOT::Mips64GOT(LDSection& pSection) 444f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines : MipsGOT(pSection) 445f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{} 446f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 447f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid Mips64GOT::setEntryValue(Fragment* entry, uint64_t pValue) 448f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 449f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<Mips64GOTEntry>(entry)->setValue(pValue); 450f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 451f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 452f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t Mips64GOT::emit(MemoryRegion& pRegion) 453f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 454f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 455f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 456f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t result = 0; 457f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 458f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Mips64GOTEntry* got = &(llvm::cast<Mips64GOTEntry>((*it))); 459f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 460f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result += got->size(); 461f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 462f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 463f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 464f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 465f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* Mips64GOT::createEntry(uint64_t pValue, SectionData* pParent) 466f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 467f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return new Mips64GOTEntry(pValue, pParent); 468f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 469f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 470f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinessize_t Mips64GOT::getEntrySize() const 471f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 472f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return Mips64GOTEntry::EntrySize; 473f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 474f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 475f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid Mips64GOT::reserveHeader() 476f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 477f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(0, m_SectionData); 478f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(Mips64ModulePtr, m_SectionData); 479f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 480