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
14const 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
20const 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
26const 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
32const 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
38const 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
44const 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
50namespace mcld {
51
52class X86_32GOTPLT;
53class GOTEntry;
54class LinkerConfig;
55
56//===----------------------------------------------------------------------===//
57// X86_32PLT Entry
58//===----------------------------------------------------------------------===//
59class X86_32DynPLT0 : public PLT::Entry<sizeof(x86_32_dyn_plt0)> {
60 public:
61  X86_32DynPLT0(SectionData& pParent);
62};
63
64class X86_32DynPLT1 : public PLT::Entry<sizeof(x86_32_dyn_plt1)> {
65 public:
66  X86_32DynPLT1(SectionData& pParent);
67};
68
69class X86_32ExecPLT0 : public PLT::Entry<sizeof(x86_32_exec_plt0)> {
70 public:
71  X86_32ExecPLT0(SectionData& pParent);
72};
73
74class 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//===----------------------------------------------------------------------===//
82class X86_64PLT0 : public PLT::Entry<sizeof(x86_64_plt0)> {
83 public:
84  X86_64PLT0(SectionData& pParent);
85};
86
87class 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 */
98class 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
115  unsigned int getPLT0Size() const { return m_PLT0Size; }
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 */
136class 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 */
156class 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