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 
16 namespace {
17 
18 const 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 
29 const 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 
38 namespace mcld {
39 
40 class AArch64GOT;
41 
42 class AArch64PLT0 : public PLT::Entry<sizeof(aarch64_plt0)>
43 {
44 public:
45   AArch64PLT0(SectionData& pParent);
46 };
47 
48 class AArch64PLT1 : public PLT::Entry<sizeof(aarch64_plt1)>
49 {
50 public:
51   AArch64PLT1(SectionData& pParent);
52 };
53 
54 /** \class AArch64PLT
55  *  \brief AArch64 Procedure Linkage Table
56  */
57 class AArch64PLT : public PLT
58 {
59 public:
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 
79 private:
80   AArch64GOT& m_GOT;
81 };
82 
83 } // namespace of mcld
84 
85 #endif
86 
87