blob: 9554f0cdfa42692f548c2e14fea64e5a89c35d97 [file] [log] [blame]
//===- 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