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