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