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
14namespace {
15
16const 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
22const 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
28const 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
34const 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
40const 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
46const 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
54namespace mcld {
55
56class X86_32GOTPLT;
57class GOTEntry;
58class LinkerConfig;
59
60//===----------------------------------------------------------------------===//
61// X86_32PLT Entry
62//===----------------------------------------------------------------------===//
63class X86_32DynPLT0 : public PLT::Entry<sizeof(x86_32_dyn_plt0)>
64{
65public:
66  X86_32DynPLT0(SectionData& pParent);
67};
68
69class X86_32DynPLT1 : public PLT::Entry<sizeof(x86_32_dyn_plt1)>
70{
71public:
72  X86_32DynPLT1(SectionData& pParent);
73};
74
75class X86_32ExecPLT0 : public PLT::Entry<sizeof(x86_32_exec_plt0)>
76{
77public:
78  X86_32ExecPLT0(SectionData& pParent);
79};
80
81class X86_32ExecPLT1 : public PLT::Entry<sizeof(x86_32_exec_plt1)>
82{
83public:
84  X86_32ExecPLT1(SectionData& pParent);
85};
86
87//===----------------------------------------------------------------------===//
88// X86_64PLT Entry
89//===----------------------------------------------------------------------===//
90class X86_64PLT0 : public PLT::Entry<sizeof(x86_64_plt0)>
91{
92public:
93  X86_64PLT0(SectionData& pParent);
94};
95
96class X86_64PLT1 : public PLT::Entry<sizeof(x86_64_plt1)>
97{
98public:
99  X86_64PLT1(SectionData& pParent);
100};
101
102//===----------------------------------------------------------------------===//
103// X86PLT
104//===----------------------------------------------------------------------===//
105/** \class X86PLT
106 *  \brief X86 Procedure Linkage Table
107 */
108class X86PLT : public PLT
109{
110public:
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
128  unsigned int getPLT0Size() const { return m_PLT0Size; }
129  unsigned int getPLT1Size() const { return m_PLT1Size; }
130
131protected:
132  PLTEntryBase* getPLT0() const;
133
134protected:
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 */
149class X86_32PLT : public X86PLT
150{
151public:
152  X86_32PLT(LDSection& pSection,
153            X86_32GOTPLT& pGOTPLT,
154            const LinkerConfig& pConfig);
155
156  void applyPLT0();
157
158  void applyPLT1();
159
160private:
161  X86_32GOTPLT& m_GOTPLT;
162};
163
164//===----------------------------------------------------------------------===//
165// X86_64PLT
166//===----------------------------------------------------------------------===//
167/** \class X86_64PLT
168 *  \brief X86_64 Procedure Linkage Table
169 */
170class X86_64PLT : public X86PLT
171{
172public:
173  X86_64PLT(LDSection& pSection,
174            X86_64GOTPLT& pGOTPLT,
175            const LinkerConfig& pConfig);
176
177  void applyPLT0();
178
179  void applyPLT1();
180
181private:
182  X86_64GOTPLT& m_GOTPLT;
183};
184
185} // namespace of mcld
186
187#endif
188
189