C++程序  |  88行  |  1.71 KB

//===- ARMPLT.h -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_ARM_PLT_H
#define MCLD_ARM_PLT_H

#include <mcld/Target/GOT.h>
#include <mcld/Target/PLT.h>

namespace {

const uint32_t arm_plt0[] = {
  0xe52de004, // str   lr, [sp, #-4]!
  0xe59fe004, // ldr   lr, [pc, #4]
  0xe08fe00e, // add   lr, pc, lr
  0xe5bef008, // ldr   pc, [lr, #8]!
  0x00000000, // &GOT[0] - .
};

const uint32_t arm_plt1[] = {
  0xe28fc600, // add   ip, pc, #0xNN00000
  0xe28cca00, // add   ip, ip, #0xNN000
  0xe5bcf000, // ldr   pc, [ip, #0xNNN]!
};

} // anonymous namespace

namespace mcld {

class ARMGOT;
class MemoryRegion;

class ARMPLT0 : public PLT::Entry<sizeof(arm_plt0)>
{
public:
  ARMPLT0(SectionData& pParent);
};

class ARMPLT1 : public PLT::Entry<sizeof(arm_plt1)>
{
public:
  ARMPLT1(SectionData& pParent);
};

/** \class ARMPLT
 *  \brief ARM Procedure Linkage Table
 */
class ARMPLT : public PLT
{
public:
  ARMPLT(LDSection& pSection, ARMGOT& pGOTPLT);
  ~ARMPLT();

  // finalizeSectionSize - set LDSection size
  void finalizeSectionSize();

  // hasPLT1 - return if this plt section has any plt1 entry
  bool hasPLT1() const;

  void reserveEntry(size_t pNum = 1) ;

  ARMPLT1* consume();

  ARMPLT0* getPLT0() const;

  void applyPLT0();

  void applyPLT1();

  uint64_t emit(MemoryRegion& pRegion);

private:
  ARMGOT& m_GOT;

  // Used by getEntry() for mapping a ResolveInfo instance to a PLT1 Entry.
  iterator m_PLTEntryIterator;
};

} // namespace of mcld

#endif