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