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