ARMPLT.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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 <mcld/Support/MemoryRegion.h>
13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.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)
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::fail_allocate_memory) << "ARMPLT1";
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)
170affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::fail_allocate_memory) << "plt0";
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)
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      fatal(diag::fail_allocate_memory) << "plt1";
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}
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
251