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/Support/MemoryRegion.h"
13 #include "mcld/Target/GOT.h"
14 #include "mcld/Target/PLT.h"
15 
16 const uint8_t aarch64_plt0[] = {
17     0xf0, 0x7b, 0xbf, 0xa9,  /* stp x16, x30, [sp, #-16]! */
18     0x10, 0x00, 0x00, 0x90,  /* adrp x16, (GOT+16) */
19     0x11, 0x0A, 0x40, 0xf9,  /* ldr x17, [x16, #PLT_GOT+0x10] */
20     0x10, 0x42, 0x00, 0x91,  /* add x16, x16,#PLT_GOT+0x10 */
21     0x20, 0x02, 0x1f, 0xd6,  /* br x17 */
22     0x1f, 0x20, 0x03, 0xd5,  /* nop */
23     0x1f, 0x20, 0x03, 0xd5,  /* nop */
24     0x1f, 0x20, 0x03, 0xd5   /* nop */
25 };
26 
27 const uint8_t aarch64_plt1[] = {
28     0x10, 0x00, 0x00, 0x90,  /* adrp x16, PLTGOT + n * 8 */
29     0x11, 0x02, 0x40, 0xf9,  /* ldr x17, [x16, PLTGOT + n * 8] */
30     0x10, 0x02, 0x00, 0x91,  /* add x16, x16, :lo12:PLTGOT + n * 8 */
31     0x20, 0x02, 0x1f, 0xd6   /* br x17.  */
32 };
33 
34 namespace mcld {
35 
36 class AArch64GOT;
37 
38 class AArch64PLT0 : public PLT::Entry<sizeof(aarch64_plt0)> {
39  public:
40   AArch64PLT0(SectionData& pParent);
41 };
42 
43 class AArch64PLT1 : public PLT::Entry<sizeof(aarch64_plt1)> {
44  public:
45   AArch64PLT1(SectionData& pParent);
46 };
47 
48 /** \class AArch64PLT
49  *  \brief AArch64 Procedure Linkage Table
50  */
51 class AArch64PLT : public PLT {
52  public:
53   AArch64PLT(LDSection& pSection, AArch64GOT& pGOTPLT);
54   ~AArch64PLT();
55 
56   // finalizeSectionSize - set LDSection size
57   void finalizeSectionSize();
58 
59   // hasPLT1 - return if this plt section has any plt1 entry
60   bool hasPLT1() const;
61 
62   AArch64PLT1* create();
63 
64   AArch64PLT0* getPLT0() const;
65 
66   void applyPLT0();
67 
68   void applyPLT1();
69 
70   uint64_t emit(MemoryRegion& pRegion);
71 
72  private:
73   AArch64GOT& m_GOT;
74 };
75 
76 }  // namespace mcld
77 
78 #endif  // TARGET_AARCH64_AARCH64PLT_H_
79