15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- impl.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#include "ARMGOT.h" 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <new> 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDFileFormat.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const size_t ARMGOTEntrySize = 4; 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // end of anonymous namespace 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMGOT 27cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoARMGOT::ARMGOT(LDSection& pSection, SectionData& pSectionData) 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : GOT(pSection, pSectionData, ARMGOTEntrySize), 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_NormalGOTIterator(), m_GOTPLTIterator(), 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GOTPLTBegin(), m_GOTPLTEnd() 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* Entry = 0; 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Create GOT0 entries. 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (int i = 0; i < 3; i++) { 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Entry = new (std::nothrow) GOTEntry(0, ARMGOTEntrySize, 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &m_SectionData); 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!Entry) 40cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao fatal(diag::fail_allocate_memory_got); 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Section.setSize(m_Section.size() + ARMGOTEntrySize); 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Skip GOT0 entries. 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator it = m_SectionData.begin(); 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (int i = 1; i < ARMGOT0Num; ++i) { 4967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao assert((it != m_SectionData.end()) && "Generation of GOT0 entries is incomplete!"); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_NormalGOTIterator = it; 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GOTPLTIterator = it; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GOTPLTBegin = it; 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GOTPLTEnd = it; 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::~ARMGOT() 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMGOT::reserveEntry(size_t pNum) 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* Entry = 0; 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t i = 0; i < pNum; i++) { 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Entry = new (std::nothrow) GOTEntry(0, ARMGOTEntrySize, 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao &m_SectionData); 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!Entry) 73cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao fatal(diag::fail_allocate_memory_got); 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Section.setSize(m_Section.size() + ARMGOTEntrySize); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMGOT::reserveGOTPLTEntry() 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* got_entry = 0; 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got_entry= new GOTEntry(0, getEntrySize(),&(getSectionData())); 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!got_entry) 86cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao fatal(diag::fail_allocate_memory_got); 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Section.setSize(m_Section.size() + getEntrySize()); 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++m_GOTPLTEnd; 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++m_NormalGOTIterator; 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGOTEntry* ARMGOT::getEntry(const ResolveInfo& pInfo, bool& pExist) 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry *&Entry = m_NormalGOTMap[&pInfo]; 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pExist = 1; 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!Entry) { 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pExist = 0; 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++m_NormalGOTIterator; 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_NormalGOTIterator != m_SectionData.getFragmentList().end() 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao && "The number of GOT Entries and ResolveInfo doesn't match!"); 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Entry = llvm::cast<GOTEntry>(&(*m_NormalGOTIterator)); 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return Entry; 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMGOT::applyGOT0(uint64_t pAddress) 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::cast<GOTEntry> 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (*(m_SectionData.getFragmentList().begin())).setContent(pAddress); 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMGOT::applyAllGOTPLT(uint64_t pPLTBase) 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator begin = getGOTPLTBegin(); 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator end = getGOTPLTEnd(); 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (;begin != end ;++begin) 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::cast<GOTEntry>(*begin).setContent(pPLTBase); 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGOTEntry*& ARMGOT::lookupGOTPLTMap(const ResolveInfo& pSymbol) 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_GOTPLTMap[&pSymbol]; 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::iterator ARMGOT::begin() 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_SectionData.getFragmentList().begin(); 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::const_iterator ARMGOT::begin() const 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_SectionData.getFragmentList().begin(); 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::iterator ARMGOT::end() 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_SectionData.getFragmentList().end(); 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::const_iterator ARMGOT::end() const 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_SectionData.getFragmentList().end(); 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::iterator ARMGOT::getNextGOTPLTEntry() 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ++m_GOTPLTIterator; 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::iterator ARMGOT::getGOTPLTBegin() 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Move to the first GOTPLT entry from last GOT0 entry. 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator begin = m_GOTPLTBegin; 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ++begin; 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst ARMGOT::iterator ARMGOT::getGOTPLTEnd() 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Move to end or the first normal GOT entry from the last GOTPLT entry. 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator end = m_GOTPLTEnd; 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return ++end; 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ARMGOT::emit(MemoryRegion& pRegion) 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry* got = 0; 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int entry_size = getEntrySize(); 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = 0x0; 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (iterator it = begin(), ie = end(); 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao it != ie; ++it, ++buffer) { 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got = &(llvm::cast<GOTEntry>((*it))); 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *buffer = static_cast<uint32_t>(got->getContent()); 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result += entry_size; 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 187