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 MCLD_TARGET_X86_PLT_H 10 #define MCLD_TARGET_X86_PLT_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 void reserveEntry(size_t pNum = 1) ; 123 124 PLTEntryBase* consume(); 125 126 virtual void applyPLT0() = 0; 127 128 virtual void applyPLT1() = 0; 129 130 unsigned int getPLT0Size() const { return m_PLT0Size; } 131 unsigned int getPLT1Size() const { return m_PLT1Size; } 132 133 protected: 134 PLTEntryBase* getPLT0() const; 135 136 protected: 137 // the last consumed entry. 138 SectionData::iterator m_Last; 139 140 const uint8_t *m_PLT0; 141 const uint8_t *m_PLT1; 142 unsigned int m_PLT0Size; 143 unsigned int m_PLT1Size; 144 145 const LinkerConfig& m_Config; 146 }; 147 148 //===----------------------------------------------------------------------===// 149 // X86_32PLT 150 //===----------------------------------------------------------------------===// 151 /** \class X86_32PLT 152 * \brief X86_32 Procedure Linkage Table 153 */ 154 class X86_32PLT : public X86PLT 155 { 156 public: 157 X86_32PLT(LDSection& pSection, 158 X86_32GOTPLT& pGOTPLT, 159 const LinkerConfig& pConfig); 160 161 void applyPLT0(); 162 163 void applyPLT1(); 164 165 private: 166 X86_32GOTPLT& m_GOTPLT; 167 }; 168 169 //===----------------------------------------------------------------------===// 170 // X86_64PLT 171 //===----------------------------------------------------------------------===// 172 /** \class X86_64PLT 173 * \brief X86_64 Procedure Linkage Table 174 */ 175 class X86_64PLT : public X86PLT 176 { 177 public: 178 X86_64PLT(LDSection& pSection, 179 X86_64GOTPLT& pGOTPLT, 180 const LinkerConfig& pConfig); 181 182 void applyPLT0(); 183 184 void applyPLT1(); 185 186 private: 187 X86_64GOTPLT& m_GOTPLT; 188 }; 189 190 } // namespace of mcld 191 192 #endif 193 194