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 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/OutputRelocSection.h" 13f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 14f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "MipsGOT.h" 15f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "MipsRelocator.h" 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Casting.h> 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/ELF.h> 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst uint32_t Mips32ModulePtr = 1 << 31; 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst uint64_t Mips64ModulePtr = 1ull << 63; 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst size_t MipsGOT0Num = 2; 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst size_t MipsGOTGpOffset = 0x7FF0; 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst size_t MipsGOTSize = MipsGOTGpOffset + 0x7FFF; 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOT::GOTMultipart 32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOT::GOTMultipart::GOTMultipart(size_t local, size_t global) 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_LocalNum(local), 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_GlobalNum(global), 36cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_TLSNum(0), 37cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_TLSDynNum(0), 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ConsumedLocal(0), 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_ConsumedGlobal(0), 40cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_ConsumedTLS(0), 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pLastLocal(NULL), 42cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pLastGlobal(NULL), 43cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pLastTLS(NULL) { 44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::GOTMultipart::isConsumed() const { 47cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return m_LocalNum == m_ConsumedLocal && m_GlobalNum == m_ConsumedGlobal && 48cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_TLSNum == m_ConsumedTLS; 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::GOTMultipart::consumeLocal() { 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_ConsumedLocal < m_LocalNum && "Consumed too many local GOT entries"); 53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_ConsumedLocal; 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pLastLocal = m_pLastLocal->getNextNode(); 55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::GOTMultipart::consumeGlobal() { 58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_ConsumedGlobal < m_GlobalNum && 59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "Consumed too many global GOT entries"); 60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_ConsumedGlobal; 61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pLastGlobal = m_pLastGlobal->getNextNode(); 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 64cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesvoid MipsGOT::GOTMultipart::consumeTLS(Relocation::Type pType) { 65cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines assert(m_ConsumedTLS < m_TLSNum && 66cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines "Consumed too many TLS GOT entries"); 67cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_ConsumedTLS += pType == llvm::ELF::R_MIPS_TLS_GOTTPREL ? 1 : 2; 68cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pLastTLS = m_pLastTLS->getNextNode(); 69cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 70cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// MipsGOT::LocalEntry 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesMipsGOT::LocalEntry::LocalEntry(const ResolveInfo* pInfo, 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Relocation::DWord addend, 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool isGot16) 7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_pInfo(pInfo), m_Addend(addend), m_IsGot16(isGot16) { 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::LocalEntry::operator<(const LocalEntry& O) const { 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_pInfo != O.m_pInfo) 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_pInfo < O.m_pInfo; 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_Addend != O.m_Addend) 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_Addend < O.m_Addend; 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_IsGot16 < O.m_IsGot16; 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// MipsGOT 92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesMipsGOT::MipsGOT(LDSection& pSection) 94cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines : GOT(pSection), 95cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_pInput(NULL), 96cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_HasTLSLdmSymbol(false), 97cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_CurrentGOTPart(0), 98cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_GotTLSLdmEntry(nullptr) { 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t MipsGOT::getGPDispAddress() const { 102f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return addr() + MipsGOTGpOffset; 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::reserve(size_t pNum) { 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (size_t i = 0; i < pNum; ++i) 107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(0, m_SectionData); 108d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::hasGOT1() const { 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return !m_MultipartList.empty(); 112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 11437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::hasMultipleGOT() const { 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList.size() > 1; 116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 11837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::finalizeScanning(OutputRelocSection& pRelDyn) { 119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (MultipartListType::iterator it = m_MultipartList.begin(); 12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != m_MultipartList.end(); 12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++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); 127cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines it->m_pLastTLS = &m_SectionData->back(); 128cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines reserve(it->m_TLSNum); 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (it == m_MultipartList.begin()) { 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Reserve entries in the second part of the primary GOT. 132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // These entries correspond to the global symbols in all 133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // non-primary GOTs. 134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines reserve(getGlobalNum() - it->m_GlobalNum); 13537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Reserve reldyn entries for R_MIPS_REL32 relocations 137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for all global entries of secondary GOTs. 138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: (simon) Do not count local entries for non-pic. 139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t count = it->m_GlobalNum + it->m_LocalNum; 140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (size_t i = 0; i < count; ++i) 141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pRelDyn.reserveEntry(); 142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 143cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 144cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (size_t i = 0; i < it->m_TLSDynNum; ++i) 145cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pRelDyn.reserveEntry(); 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const { 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType::const_iterator itX = m_SymbolOrderMap.find(pX); 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolOrderMapType::const_iterator itY = m_SymbolOrderMap.find(pY); 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (itX != m_SymbolOrderMap.end() && itY != m_SymbolOrderMap.end()) 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return itX->second < itY->second; 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return itX == m_SymbolOrderMap.end() && itY != m_SymbolOrderMap.end(); 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::initGOTList() { 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_SymbolOrderMap.clear(); 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.clear(); 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.push_back(GOTMultipart()); 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.clear(); 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.clear(); 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.clear(); 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.clear(); 171cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_InputTLSGdSymbols.clear(); 172cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_HasTLSLdmSymbol = false; 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 17537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::changeInput() { 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 178f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (LocalSymbolSetType::iterator it = m_InputLocalSymbols.begin(), 179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines end = m_InputLocalSymbols.end(); 18037b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != end; 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) 182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.insert(*it); 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputLocalSymbols.clear(); 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolUniqueMapType::iterator it = m_InputGlobalSymbols.begin(), 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputGlobalSymbols.end(); 18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != end; 18937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.insert(it->first); 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_InputGlobalSymbols.clear(); 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 19537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::isGOTFull() const { 19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t gotCount = MipsGOT0Num + m_MultipartList.back().m_LocalNum + 197f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_GlobalNum; 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotCount += 1; 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 201f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return gotCount * getEntrySize() > MipsGOTSize; 202f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 20437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::split() { 205f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedLocalSymbols.clear(); 206f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MergedGlobalSymbols.clear(); 207f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 208f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t uniqueCount = 0; 209f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (SymbolUniqueMapType::const_iterator it = m_InputGlobalSymbols.begin(), 210f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines end = m_InputGlobalSymbols.end(); 21137b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != end; 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 213f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it->second) 214f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++uniqueCount; 215f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 216f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 217f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_LocalNum -= m_InputLocalSymbols.size(); 218f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_GlobalNum -= uniqueCount; 219f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.erase(m_pInput); 220f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_MultipartList.push_back( 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines GOTMultipart(m_InputLocalSymbols.size(), m_InputGlobalSymbols.size())); 223f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList.back().m_Inputs.insert(m_pInput); 224f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 225f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 22637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::initializeScan(const Input& pInput) { 227f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pInput == NULL) { 228f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput = &pInput; 229f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines initGOTList(); 23037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 231f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pInput = &pInput; 232f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines changeInput(); 233f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 234f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 235f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 23637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::finalizeScan(const Input& pInput) { 237f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 238f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 23937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::reserveLocalEntry(ResolveInfo& pInfo, 24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines int reloc, 24137b74a387bb3993387029859c2d9d051c41c724eStephen Hines Relocation::DWord pAddend) { 242f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LocalEntry entry(&pInfo, pAddend, reloc == llvm::ELF::R_MIPS_GOT16); 243f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 244f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_InputLocalSymbols.count(entry)) 245f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Do nothing, if we have seen this symbol 246f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // in the current input already. 247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 248f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 249f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (m_MergedLocalSymbols.count(entry)) { 250f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // We have seen this symbol in previous inputs. 251f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Remember that it exists in the current input too. 252f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_InputLocalSymbols.insert(entry); 253f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 254f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isGOTFull()) 257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines split(); 258f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 259f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_InputLocalSymbols.insert(entry); 260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_MultipartList.back().m_LocalNum; 262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 263f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 264f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 26537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::reserveGlobalEntry(ResolveInfo& pInfo) { 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 288cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesbool MipsGOT::reserveTLSGdEntry(ResolveInfo& pInfo) { 289cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (m_InputTLSGdSymbols.count(&pInfo)) 290cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 291cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 292cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_InputTLSGdSymbols.insert(&pInfo); 293cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList.back().m_TLSNum += 2; 294cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList.back().m_TLSDynNum += 2; 295cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 296cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 297cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 298cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 299cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesbool MipsGOT::reserveTLSLdmEntry() { 300cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (m_HasTLSLdmSymbol) 301cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 302cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 303cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_HasTLSLdmSymbol = true; 304cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList.back().m_TLSNum += 2; 305cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList.back().m_TLSDynNum += 1; 306cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 307cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 308cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 309cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 310cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesbool MipsGOT::reserveTLSGotEntry(ResolveInfo& pInfo) { 311cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (m_InputTLSGotSymbols.count(&pInfo)) 312cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 313cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 314cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_InputTLSGotSymbols.insert(&pInfo); 315cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList.back().m_TLSNum += 1; 316cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList.back().m_TLSDynNum += 1; 317cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 318cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return true; 319cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 320cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 32137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool MipsGOT::isPrimaryGOTConsumed() { 322f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_CurrentGOTPart > 0; 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 32537b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* MipsGOT::consumeLocal() { 32637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && 32737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "GOT number is out of range!"); 328f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 329f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 330f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_CurrentGOTPart; 331f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 332f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeLocal(); 333f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastLocal; 33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 33737b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* MipsGOT::consumeGlobal() { 33837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && 33937b74a387bb3993387029859c2d9d051c41c724eStephen Hines "GOT number is out of range!"); 340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++m_CurrentGOTPart; 343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeGlobal(); 345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastGlobal; 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 349cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen HinesFragment* MipsGOT::consumeTLS(Relocation::Type pType) { 350cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines assert(m_CurrentGOTPart < m_MultipartList.size() && 351cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines "GOT number is out of range!"); 352cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 353cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (m_MultipartList[m_CurrentGOTPart].isConsumed()) 354cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ++m_CurrentGOTPart; 355cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 356cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_MultipartList[m_CurrentGOTPart].consumeTLS(pType); 357cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 358cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return m_MultipartList[m_CurrentGOTPart].m_pLastTLS; 359cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 360cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 36137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t MipsGOT::getGPAddr(const Input& pInput) const { 362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t gotSize = 0; 36337b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (MultipartListType::const_iterator it = m_MultipartList.begin(), 36437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ie = m_MultipartList.end(); 36537b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 36637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 367f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it->m_Inputs.count(&pInput)) 368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 369f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 370f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotSize += (MipsGOT0Num + it->m_LocalNum + it->m_GlobalNum); 371f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (it == m_MultipartList.begin()) 372f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines gotSize += getGlobalNum() - it->m_GlobalNum; 373f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 374f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 375f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return addr() + gotSize * getEntrySize() + MipsGOTGpOffset; 376f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 378f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t MipsGOT::getGPRelOffset(const Input& pInput, 37937b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Fragment& pEntry) const { 380f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return addr() + pEntry.getOffset() - getGPAddr(pInput); 381f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 382f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 38337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid MipsGOT::recordGlobalEntry(const ResolveInfo* pInfo, Fragment* pEntry) { 384f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryKey key; 385f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 386f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_pInfo = pInfo; 387f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = 0; 388f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_GotGlobalEntriesMap[key] = pEntry; 389f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 390f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 39137b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* MipsGOT::lookupGlobalEntry(const ResolveInfo* pInfo) { 392f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines GotEntryKey key; 39337b74a387bb3993387029859c2d9d051c41c724eStephen Hines key.m_GOTPage = m_CurrentGOTPart; 394f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines key.m_pInfo = pInfo; 395f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = 0; 396f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryMapType::iterator it = m_GotGlobalEntriesMap.find(key); 397f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 398f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (it == m_GotGlobalEntriesMap.end()) 399f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 400f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 401f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return it->second; 402f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 403cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 404cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hinesvoid MipsGOT::recordTLSEntry(const ResolveInfo* pInfo, Fragment* pEntry, 405cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines Relocation::Type pType) { 406cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (pType == llvm::ELF::R_MIPS_TLS_LDM) { 407cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_GotTLSLdmEntry = pEntry; 408cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } else if (pType == llvm::ELF::R_MIPS_TLS_GD) { 409cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines GotEntryKey key; 410cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 411cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_pInfo = pInfo; 412cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_Addend = 0; 413cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_GotTLSGdEntriesMap[key] = pEntry; 414cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } else if (pType == llvm::ELF::R_MIPS_TLS_GOTTPREL) { 415cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines GotEntryKey key; 416cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 417cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_pInfo = pInfo; 418cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_Addend = 0; 419cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines m_GotTLSGotEntriesMap[key] = pEntry; 420cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } else { 421cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm_unreachable("Unexpected relocation"); 422cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 423cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 424cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 425cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen HinesFragment* MipsGOT::lookupTLSEntry(const ResolveInfo* pInfo, 426cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines Relocation::Type pType) { 427cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (pType == llvm::ELF::R_MIPS_TLS_LDM) 428cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return m_GotTLSLdmEntry; 429cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (pType == llvm::ELF::R_MIPS_TLS_GD) { 430cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines GotEntryKey key; 431cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 432cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_pInfo = pInfo; 433cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_Addend = 0; 434cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines GotEntryMapType::iterator it = m_GotTLSGdEntriesMap.find(key); 435cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return it == m_GotTLSGdEntriesMap.end() ? nullptr : it->second; 436cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 437cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (pType == llvm::ELF::R_MIPS_TLS_GOTTPREL) { 438cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines GotEntryKey key; 439cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 440cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_pInfo = pInfo; 441cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines key.m_Addend = 0; 442cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines GotEntryMapType::iterator it = m_GotTLSGotEntriesMap.find(key); 443cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return it == m_GotTLSGotEntriesMap.end() ? nullptr : it->second; 444cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 445cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines llvm_unreachable("Unexpected relocation"); 446cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines} 447f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 448f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid MipsGOT::recordLocalEntry(const ResolveInfo* pInfo, 449f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::DWord pAddend, 45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines Fragment* pEntry) { 451f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryKey key; 452f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_GOTPage = m_CurrentGOTPart; 453f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_pInfo = pInfo; 454f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = pAddend; 455f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_GotLocalEntriesMap[key] = pEntry; 456f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 457f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 458f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* MipsGOT::lookupLocalEntry(const ResolveInfo* pInfo, 45937b74a387bb3993387029859c2d9d051c41c724eStephen Hines Relocation::DWord pAddend) { 460f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryKey key; 46137b74a387bb3993387029859c2d9d051c41c724eStephen Hines key.m_GOTPage = m_CurrentGOTPart; 462f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_pInfo = pInfo; 463f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines key.m_Addend = pAddend; 464f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GotEntryMapType::iterator it = m_GotLocalEntriesMap.find(key); 465f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 466f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (it == m_GotLocalEntriesMap.end()) 467f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return NULL; 468f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 469f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return it->second; 4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 47237b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t MipsGOT::getLocalNum() const { 473f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(!m_MultipartList.empty() && "GOT is empty!"); 474f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_MultipartList[0].m_LocalNum + MipsGOT0Num; 4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 476affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 47737b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t MipsGOT::getGlobalNum() const { 478f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return m_SymbolOrderMap.size(); 479f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 480f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 481f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 482f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// Mips32GOT 483f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 48437b74a387bb3993387029859c2d9d051c41c724eStephen HinesMips32GOT::Mips32GOT(LDSection& pSection) : MipsGOT(pSection) { 48537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 486f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 48737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Mips32GOT::setEntryValue(Fragment* entry, uint64_t pValue) { 488f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<Mips32GOTEntry>(entry)->setValue(pValue); 489f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 490f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 49137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t Mips32GOT::emit(MemoryRegion& pRegion) { 492f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 493f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 494f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t result = 0; 495f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 496f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Mips32GOTEntry* got = &(llvm::cast<Mips32GOTEntry>((*it))); 497f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 498f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result += got->size(); 499f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 500f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 501f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 502f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 50337b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* Mips32GOT::createEntry(uint64_t pValue, SectionData* pParent) { 504f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return new Mips32GOTEntry(pValue, pParent); 505f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 506f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 50737b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t Mips32GOT::getEntrySize() const { 508f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return Mips32GOTEntry::EntrySize; 509f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 510f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 51137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Mips32GOT::reserveHeader() { 512f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(0, m_SectionData); 513f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(Mips32ModulePtr, m_SectionData); 514f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 515f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 516f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 517f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// Mips64GOT 518f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 51937b74a387bb3993387029859c2d9d051c41c724eStephen HinesMips64GOT::Mips64GOT(LDSection& pSection) : MipsGOT(pSection) { 52037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} 521f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 52237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Mips64GOT::setEntryValue(Fragment* entry, uint64_t pValue) { 523f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<Mips64GOTEntry>(entry)->setValue(pValue); 524f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 525f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 52637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t Mips64GOT::emit(MemoryRegion& pRegion) { 527f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin()); 528f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 529f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t result = 0; 530f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 531f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Mips64GOTEntry* got = &(llvm::cast<Mips64GOTEntry>((*it))); 532f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *buffer = static_cast<uint64_t>(got->getValue()); 533f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result += got->size(); 534f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 535f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 536f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 537f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 53837b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* Mips64GOT::createEntry(uint64_t pValue, SectionData* pParent) { 539f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return new Mips64GOTEntry(pValue, pParent); 540f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 541f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 54237b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t Mips64GOT::getEntrySize() const { 543f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return Mips64GOTEntry::EntrySize; 544f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 545f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 54637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Mips64GOT::reserveHeader() { 547f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(0, m_SectionData); 548f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines createEntry(Mips64ModulePtr, m_SectionData); 549f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 55037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 55137b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 552