ARMPLT.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ARMPLT.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 "ARMPLT.h" 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/raw_ostream.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <new> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst uint32_t arm_plt0[] = { 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe52de004, // str lr, [sp, #-4]! 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe59fe004, // ldr lr, [pc, #4] 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe08fe00e, // add lr, pc, lr 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe5bef008, // ldr pc, [lr, #8]! 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x00000000, // &GOT[0] - . 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst uint32_t arm_plt1[] = { 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe28fc600, // add ip, pc, #0xNN00000 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe28cca00, // add ip, ip, #0xNN000 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0xe5bcf000, // ldr pc, [ip, #0xNNN]! 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // anonymous namespace 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT0::ARMPLT0(llvm::MCSectionData* pParent) 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : PLTEntry(sizeof(arm_plt0), pParent) {} 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT1::ARMPLT1(llvm::MCSectionData* pParent) 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : PLTEntry(sizeof(arm_plt1), pParent) {} 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMPLT 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT::ARMPLT(LDSection& pSection, 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::MCSectionData& pSectionData, 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT &pGOTPLT) 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : PLT(pSection, pSectionData), m_GOT(pGOTPLT), m_PLTEntryIterator() { 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT0* plt0_entry = new ARMPLT0(&m_SectionData); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Section.setSize(m_Section.size() + plt0_entry->getEntrySize()); 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_PLTEntryIterator = pSectionData.begin(); 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT::~ARMPLT() 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMPLT::reserveEntry(size_t pNum) 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT1* plt1_entry = 0; 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (size_t i = 0; i < pNum; ++i) { 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1_entry = new (std::nothrow) ARMPLT1(&m_SectionData); 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!plt1_entry) 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("Allocating new memory for ARMPLT1 failed!"); 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Section.setSize(m_Section.size() + plt1_entry->getEntrySize()); 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GOT.reserveGOTPLTEntry(); 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPLTEntry* ARMPLT::getPLTEntry(const ResolveInfo& pSymbol, bool& pExist) 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT1 *&PLTEntry = m_PLTEntryMap[&pSymbol]; 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pExist = 1; 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!PLTEntry) { 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry *&GOTPLTEntry = m_GOT.lookupGOTPLTMap(pSymbol); 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!GOTPLTEntry && "PLT entry and got.plt entry doesn't match!"); 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pExist = 0; 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // This will skip PLT0. 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++m_PLTEntryIterator; 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_PLTEntryIterator != m_SectionData.end() && 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "The number of PLT Entries and ResolveInfo doesn't match"); 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT::iterator got_it = m_GOT.getNextGOTPLTEntry(); 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT::iterator got_ie = m_GOT.getGOTPLTEnd(); 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(got_it != got_ie && "The number of GOTPLT and PLT doesn't match"); 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao PLTEntry = llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator)); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTPLTEntry = llvm::cast<GOTEntry>(&(*got_it)); 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return PLTEntry; 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGOTEntry* ARMPLT::getGOTPLTEntry(const ResolveInfo& pSymbol, bool& pExist) 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntry *&GOTPLTEntry = m_GOT.lookupGOTPLTMap(pSymbol); 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pExist = 1; 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!GOTPLTEntry) { 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT1 *&PLTEntry = m_PLTEntryMap[&pSymbol]; 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(!PLTEntry && "PLT entry and got.plt entry doesn't match!"); 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pExist = 0; 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // This will skip PLT0. 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++m_PLTEntryIterator; 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_PLTEntryIterator != m_SectionData.end() && 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao "The number of PLT Entries and ResolveInfo doesn't match"); 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT::iterator got_it = m_GOT.getNextGOTPLTEntry(); 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMGOT::iterator got_ie = m_GOT.getGOTPLTEnd(); 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(got_it != got_ie && "The number of GOTPLT and PLT doesn't match"); 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao PLTEntry = llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator)); 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTPLTEntry = llvm::cast<GOTEntry>(&(*got_it)); 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return GOTPLTEntry; 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT0* ARMPLT::getPLT0() const { 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator first = m_SectionData.getFragmentList().begin(); 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator end = m_SectionData.getFragmentList().end(); 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(first!=end && "FragmentList is empty, getPLT0 failed!"); 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first)); 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return plt0; 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMPLT::applyPLT0() { 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t plt_base = m_Section.addr(); 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(plt_base && ".plt base address is NULL!"); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t got_base = m_GOT.getSection().addr(); 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(got_base && ".got base address is NULL!"); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t offset = 0; 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (got_base > plt_base) 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = got_base - (plt_base + 16); 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao offset = (plt_base + 16) - got_base; 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator first = m_SectionData.getFragmentList().begin(); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator end = m_SectionData.getFragmentList().end(); 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(first!=end && "FragmentList is empty, applyPLT0 failed!"); 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first)); 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* data = 0; 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao data = static_cast<uint32_t*>(malloc(plt0->getEntrySize())); 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!data) 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("Allocating new memory for plt0 failed!"); 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(data, arm_plt0, plt0->getEntrySize()); 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao data[4] = offset; 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt0->setContent(reinterpret_cast<unsigned char*>(data)); 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMPLT::applyPLT1() { 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t plt_base = m_Section.addr(); 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(plt_base && ".plt base address is NULL!"); 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t got_base = m_GOT.getSection().addr(); 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(got_base && ".got base address is NULL!"); 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT::iterator it = m_SectionData.begin(); 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT::iterator ie = m_SectionData.end(); 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(it!=ie && "FragmentList is empty, applyPLT1 failed!"); 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t GOTEntrySize = m_GOT.getEntrySize(); 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t GOTEntryAddress = 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao got_base + GOTEntrySize * 3; 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t PLTEntryAddress = 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt_base + llvm::cast<ARMPLT0>((*it)).getEntrySize(); //Offset of PLT0 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; //skip PLT0 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t PLT1EntrySize = llvm::cast<ARMPLT1>((*it)).getEntrySize(); 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT1* plt1 = NULL; 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t* Out = NULL; 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (it != ie) { 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1 = &(llvm::cast<ARMPLT1>(*it)); 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Out = static_cast<uint32_t*>(malloc(plt1->getEntrySize())); 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!Out) 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("Allocating new memory for plt1 failed!"); 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Offset is the distance between the last PLT entry and the associated 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // GOT entry. 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao int32_t Offset = (GOTEntryAddress - (PLTEntryAddress + 8)); 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Out[0] = arm_plt1[0] | ((Offset >> 20) & 0xFF); 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Out[1] = arm_plt1[1] | ((Offset >> 12) & 0xFF); 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Out[2] = arm_plt1[2] | (Offset & 0xFFF); 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1->setContent(reinterpret_cast<unsigned char*>(Out)); 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao GOTEntryAddress += GOTEntrySize; 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao PLTEntryAddress += PLT1EntrySize; 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_GOT.applyAllGOTPLT(plt_base); 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ARMPLT::emit(MemoryRegion& pRegion) 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = 0x0; 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao iterator it = begin(); 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int plt0_size = llvm::cast<ARMPLT0>((*it)).getEntrySize(); 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* buffer = pRegion.getBuffer(); 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer, llvm::cast<ARMPLT0>((*it)).getContent(), plt0_size); 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result += plt0_size; 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT1* plt1 = 0; 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ARMPLT::iterator ie = end(); 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int entry_size = 0; 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (it != ie) { 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao plt1 = &(llvm::cast<ARMPLT1>(*it)); 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry_size = plt1->getEntrySize(); 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(buffer + result, plt1->getContent(), entry_size); 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result += entry_size; 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++it; 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 251