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