ARMPLT.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace {
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst uint32_t arm_plt0[] = {
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe52de004, // str   lr, [sp, #-4]!
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe59fe004, // ldr   lr, [pc, #4]
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe08fe00e, // add   lr, pc, lr
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe5bef008, // ldr   pc, [lr, #8]!
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0x00000000, // &GOT[0] - .
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst uint32_t arm_plt1[] = {
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe28fc600, // add   ip, pc, #0xNN00000
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe28cca00, // add   ip, ip, #0xNN000
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  0xe5bcf000, // ldr   pc, [ip, #0xNNN]!
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // anonymous namespace
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMPLT0::ARMPLT0(SectionData& pParent)
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : PLT::Entry(sizeof(arm_plt0), pParent) {}
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMPLT1::ARMPLT1(SectionData& pParent)
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : PLT::Entry(sizeof(arm_plt1), pParent) {}
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMPLT
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT::ARMPLT(LDSection& pSection,
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao               ARMGOT &pGOTPLT)
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : PLT(pSection), m_GOT(pGOTPLT), m_PLTEntryIterator() {
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  new ARMPLT0(*m_SectionData);
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_PLTEntryIterator = m_SectionData->begin();
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMPLT::~ARMPLT()
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ARMPLT::hasPLT1() const
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return (m_SectionData->size() > 1);
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ARMPLT::finalizeSectionSize()
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = (m_SectionData->size() - 1) * sizeof(arm_plt1) +
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     sizeof(arm_plt0);
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_Section.setSize(size);
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint32_t offset = 0;
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData::iterator frag, fragEnd = m_SectionData->end();
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) {
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    frag->setOffset(offset);
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    offset += frag->size();
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMPLT::reserveEntry(size_t pNum)
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ARMPLT1* plt1_entry = 0;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t i = 0; i < pNum; ++i) {
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    plt1_entry = new (std::nothrow) ARMPLT1(*m_SectionData);
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!plt1_entry)
87cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      fatal(diag::fail_allocate_memory_plt);
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_GOT.reserveGOTPLT();
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMPLT1* ARMPLT::consume()
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ++m_PLTEntryIterator;
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(m_PLTEntryIterator != m_SectionData->end() &&
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao         "The number of PLT Entries and ResolveInfo doesn't match");
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator));
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMPLT0* ARMPLT::getPLT0() const {
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  iterator first = m_SectionData->getFragmentList().begin();
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(first != m_SectionData->getFragmentList().end() &&
10767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao         "FragmentList is empty, getPLT0 failed!");
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return plt0;
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMPLT::applyPLT0() {
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t plt_base = m_Section.addr();
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(plt_base && ".plt base address is NULL!");
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t got_base = m_GOT.addr();
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(got_base && ".got base address is NULL!");
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t offset = 0;
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (got_base > plt_base)
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset = got_base - (plt_base + 16);
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset = (plt_base + 16) - got_base;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  iterator first = m_SectionData->getFragmentList().begin();
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(first != m_SectionData->getFragmentList().end() &&
13267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao         "FragmentList is empty, applyPLT0 failed!");
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* data = 0;
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  data = static_cast<uint32_t*>(malloc(plt0->getEntrySize()));
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!data)
140cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    fatal(diag::fail_allocate_memory_plt);
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  memcpy(data, arm_plt0, plt0->getEntrySize());
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  data[4] = offset;
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  plt0->setContent(reinterpret_cast<unsigned char*>(data));
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ARMPLT::applyPLT1() {
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t plt_base = m_Section.addr();
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(plt_base && ".plt base address is NULL!");
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t got_base = m_GOT.addr();
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(got_base && ".got base address is NULL!");
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ARMPLT::iterator it = m_SectionData->begin();
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ARMPLT::iterator ie = m_SectionData->end();
15867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  assert(it != ie && "FragmentList is empty, applyPLT1 failed!");
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t GOTEntrySize = m_GOT.getEntrySize();
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t GOTEntryAddress =
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    got_base +  GOTEntrySize * 3;
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t PLTEntryAddress =
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    plt_base + llvm::cast<ARMPLT0>((*it)).getEntrySize(); //Offset of PLT0
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ++it; //skip PLT0
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t PLT1EntrySize = llvm::cast<ARMPLT1>((*it)).getEntrySize();
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ARMPLT1* plt1 = NULL;
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* Out = NULL;
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (it != ie) {
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    plt1 = &(llvm::cast<ARMPLT1>(*it));
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Out = static_cast<uint32_t*>(malloc(plt1->getEntrySize()));
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!Out)
177cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      fatal(diag::fail_allocate_memory_plt);
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // Offset is the distance between the last PLT entry and the associated
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // GOT entry.
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    int32_t Offset = (GOTEntryAddress - (PLTEntryAddress + 8));
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Out[0] = arm_plt1[0] | ((Offset >> 20) & 0xFF);
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Out[1] = arm_plt1[1] | ((Offset >> 12) & 0xFF);
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Out[2] = arm_plt1[2] | (Offset & 0xFFF);
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    plt1->setContent(reinterpret_cast<unsigned char*>(Out));
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntryAddress += GOTEntrySize;
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    PLTEntryAddress += PLT1EntrySize;
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_GOT.applyGOTPLT(plt_base);
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ARMPLT::emit(MemoryRegion& pRegion)
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t result = 0x0;
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator it = begin();
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int plt0_size = llvm::cast<ARMPLT0>((*it)).getEntrySize();
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned char* buffer = pRegion.getBuffer();
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  memcpy(buffer, llvm::cast<ARMPLT0>((*it)).getContent(), plt0_size);
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  result += plt0_size;
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ++it;
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ARMPLT1* plt1 = 0;
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ARMPLT::iterator ie = end();
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int entry_size = 0;
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (it != ie) {
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    plt1 = &(llvm::cast<ARMPLT1>(*it));
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry_size = plt1->getEntrySize();
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    memcpy(buffer + result, plt1->getContent(), entry_size);
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result += entry_size;
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
221