1//===- AArch64PLT.h -------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef TARGET_AARCH64_AARCH64PLT_H
10#define TARGET_AARCH64_AARCH64PLT_H
11
12#include <mcld/Target/GOT.h>
13#include <mcld/Target/PLT.h>
14#include <mcld/Support/MemoryRegion.h>
15
16namespace {
17
18const uint8_t aarch64_plt0[] = {
19  0xf0, 0x7b, 0xbf, 0xa9,  /* stp x16, x30, [sp, #-16]!  */
20  0x10, 0x00, 0x00, 0x90,  /* adrp x16, (GOT+16)  */
21  0x11, 0x0A, 0x40, 0xf9,  /* ldr x17, [x16, #PLT_GOT+0x10]  */
22  0x10, 0x42, 0x00, 0x91,  /* add x16, x16,#PLT_GOT+0x10   */
23  0x20, 0x02, 0x1f, 0xd6,  /* br x17  */
24  0x1f, 0x20, 0x03, 0xd5,  /* nop */
25  0x1f, 0x20, 0x03, 0xd5,  /* nop */
26  0x1f, 0x20, 0x03, 0xd5   /* nop */
27};
28
29const uint8_t aarch64_plt1[] = {
30  0x10, 0x00, 0x00, 0x90,  /* adrp x16, PLTGOT + n * 8  */
31  0x11, 0x02, 0x40, 0xf9,  /* ldr x17, [x16, PLTGOT + n * 8] */
32  0x10, 0x02, 0x00, 0x91,  /* add x16, x16, :lo12:PLTGOT + n * 8  */
33  0x20, 0x02, 0x1f, 0xd6   /* br x17.  */
34};
35
36} // anonymous namespace
37
38namespace mcld {
39
40class AArch64GOT;
41
42class AArch64PLT0 : public PLT::Entry<sizeof(aarch64_plt0)>
43{
44public:
45  AArch64PLT0(SectionData& pParent);
46};
47
48class AArch64PLT1 : public PLT::Entry<sizeof(aarch64_plt1)>
49{
50public:
51  AArch64PLT1(SectionData& pParent);
52};
53
54/** \class AArch64PLT
55 *  \brief AArch64 Procedure Linkage Table
56 */
57class AArch64PLT : public PLT
58{
59public:
60  AArch64PLT(LDSection& pSection, AArch64GOT& pGOTPLT);
61  ~AArch64PLT();
62
63  // finalizeSectionSize - set LDSection size
64  void finalizeSectionSize();
65
66  // hasPLT1 - return if this plt section has any plt1 entry
67  bool hasPLT1() const;
68
69  AArch64PLT1* create();
70
71  AArch64PLT0* getPLT0() const;
72
73  void applyPLT0();
74
75  void applyPLT1();
76
77  uint64_t emit(MemoryRegion& pRegion);
78
79private:
80  AArch64GOT& m_GOT;
81};
82
83} // namespace of mcld
84
85#endif
86
87