1 //===- X86PLT.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_X86_X86PLT_H_
10 #define TARGET_X86_X86PLT_H_
11 
12 #include "mcld/Target/PLT.h"
13 
14 const uint8_t x86_32_dyn_plt0[] = {
15     0xff, 0xb3, 0x04, 0, 0, 0,  // pushl  0x4(%ebx)
16     0xff, 0xa3, 0x08, 0, 0, 0,  // jmp    *0x8(%ebx)
17     0x0f, 0x1f, 0x4,  0         // nopl   0(%eax)
18 };
19 
20 const uint8_t x86_32_dyn_plt1[] = {
21     0xff, 0xa3, 0, 0, 0, 0,  // jmp    *sym@GOT(%ebx)
22     0x68, 0, 0, 0, 0,        // pushl  $offset
23     0xe9, 0, 0, 0, 0         // jmp    plt0
24 };
25 
26 const uint8_t x86_32_exec_plt0[] = {
27     0xff, 0x35, 0, 0, 0, 0,  // pushl  .got + 4
28     0xff, 0x25, 0, 0, 0, 0,  // jmp    *(.got + 8)
29     0x0f, 0x1f, 0x4, 0       // nopl   0(%eax)
30 };
31 
32 const uint8_t x86_32_exec_plt1[] = {
33     0xff, 0x25, 0, 0, 0, 0,  // jmp    *(sym in .got)
34     0x68, 0, 0, 0, 0,        // pushl  $offset
35     0xe9, 0, 0, 0, 0         // jmp    plt0
36 };
37 
38 const uint8_t x86_64_plt0[] = {
39     0xff, 0x35, 0x8, 0, 0, 0,   // pushq  GOT + 8(%rip)
40     0xff, 0x25, 0x16, 0, 0, 0,  // jmq    *GOT + 16(%rip)
41     0x0f, 0x1f, 0x40, 0         // nopl   0(%rax)
42 };
43 
44 const uint8_t x86_64_plt1[] = {
45     0xff, 0x25, 0, 0, 0, 0,  // jmpq   *sym@GOTPCREL(%rip)
46     0x68, 0, 0, 0, 0,        // pushq  $index
47     0xe9, 0, 0, 0, 0         // jmpq   plt0
48 };
49 
50 namespace mcld {
51 
52 class X86_32GOTPLT;
53 class GOTEntry;
54 class LinkerConfig;
55 
56 //===----------------------------------------------------------------------===//
57 // X86_32PLT Entry
58 //===----------------------------------------------------------------------===//
59 class X86_32DynPLT0 : public PLT::Entry<sizeof(x86_32_dyn_plt0)> {
60  public:
61   X86_32DynPLT0(SectionData& pParent);
62 };
63 
64 class X86_32DynPLT1 : public PLT::Entry<sizeof(x86_32_dyn_plt1)> {
65  public:
66   X86_32DynPLT1(SectionData& pParent);
67 };
68 
69 class X86_32ExecPLT0 : public PLT::Entry<sizeof(x86_32_exec_plt0)> {
70  public:
71   X86_32ExecPLT0(SectionData& pParent);
72 };
73 
74 class X86_32ExecPLT1 : public PLT::Entry<sizeof(x86_32_exec_plt1)> {
75  public:
76   X86_32ExecPLT1(SectionData& pParent);
77 };
78 
79 //===----------------------------------------------------------------------===//
80 // X86_64PLT Entry
81 //===----------------------------------------------------------------------===//
82 class X86_64PLT0 : public PLT::Entry<sizeof(x86_64_plt0)> {
83  public:
84   X86_64PLT0(SectionData& pParent);
85 };
86 
87 class X86_64PLT1 : public PLT::Entry<sizeof(x86_64_plt1)> {
88  public:
89   X86_64PLT1(SectionData& pParent);
90 };
91 
92 //===----------------------------------------------------------------------===//
93 // X86PLT
94 //===----------------------------------------------------------------------===//
95 /** \class X86PLT
96  *  \brief X86 Procedure Linkage Table
97  */
98 class X86PLT : public PLT {
99  public:
100   X86PLT(LDSection& pSection, const LinkerConfig& pConfig, int got_size);
101   ~X86PLT();
102 
103   // finalizeSectionSize - set LDSection size
104   void finalizeSectionSize();
105 
106   // hasPLT1 - return if this PLT has any PLT1 entry
107   bool hasPLT1() const;
108 
109   PLTEntryBase* create();
110 
111   virtual void applyPLT0() = 0;
112 
113   virtual void applyPLT1() = 0;
114 
getPLT0Size()115   unsigned int getPLT0Size() const { return m_PLT0Size; }
getPLT1Size()116   unsigned int getPLT1Size() const { return m_PLT1Size; }
117 
118  protected:
119   PLTEntryBase* getPLT0() const;
120 
121  protected:
122   const uint8_t* m_PLT0;
123   const uint8_t* m_PLT1;
124   unsigned int m_PLT0Size;
125   unsigned int m_PLT1Size;
126 
127   const LinkerConfig& m_Config;
128 };
129 
130 //===----------------------------------------------------------------------===//
131 // X86_32PLT
132 //===----------------------------------------------------------------------===//
133 /** \class X86_32PLT
134  *  \brief X86_32 Procedure Linkage Table
135  */
136 class X86_32PLT : public X86PLT {
137  public:
138   X86_32PLT(LDSection& pSection,
139             X86_32GOTPLT& pGOTPLT,
140             const LinkerConfig& pConfig);
141 
142   void applyPLT0();
143 
144   void applyPLT1();
145 
146  private:
147   X86_32GOTPLT& m_GOTPLT;
148 };
149 
150 //===----------------------------------------------------------------------===//
151 // X86_64PLT
152 //===----------------------------------------------------------------------===//
153 /** \class X86_64PLT
154  *  \brief X86_64 Procedure Linkage Table
155  */
156 class X86_64PLT : public X86PLT {
157  public:
158   X86_64PLT(LDSection& pSection,
159             X86_64GOTPLT& pGOTPLT,
160             const LinkerConfig& pConfig);
161 
162   void applyPLT0();
163 
164   void applyPLT1();
165 
166  private:
167   X86_64GOTPLT& m_GOTPLT;
168 };
169 
170 }  // namespace mcld
171 
172 #endif  // TARGET_X86_X86PLT_H_
173