Home | History | Annotate | Download | only in X86
      1 //===-  X86Relocator.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_X86RELOCATOR_H_
     10 #define TARGET_X86_X86RELOCATOR_H_
     11 
     12 #include "mcld/LD/Relocator.h"
     13 #include "mcld/Target/GOT.h"
     14 #include "mcld/Target/PLT.h"
     15 #include "mcld/Target/KeyEntryMap.h"
     16 #include "X86LDBackend.h"
     17 
     18 namespace mcld {
     19 
     20 class LinkerConfig;
     21 class ResolveInfo;
     22 
     23 /** \class X86Relocator
     24  *  \brief X86Relocator creates and destroys the X86 relocations.
     25  *
     26  */
     27 class X86Relocator : public Relocator {
     28  public:
     29   typedef KeyEntryMap<ResolveInfo, PLTEntryBase> SymPLTMap;
     30 
     31   /** \enum ReservedEntryType
     32    *  \brief The reserved entry type of reserved space in ResolveInfo.
     33    *
     34    *  This is used for sacnRelocation to record what kinds of entries are
     35    *  reserved for this resolved symbol. In X86, there are three kinds of
     36    *  entries, GOT, PLT, and dynamic reloction.
     37    *
     38    *  bit:  3     2     1     0
     39    *   |    | PLT | GOT | Rel |
     40    *
     41    *  value    Name         - Description
     42    *
     43    *  0000     None         - no reserved entry
     44    *  0001     ReserveRel   - reserve an dynamic relocation entry
     45    *  0010     ReserveGOT   - reserve an GOT entry
     46    *  0100     ReservePLT   - reserve an PLT entry and the corresponding GOT,
     47    *
     48    */
     49   enum ReservedEntryType {
     50     None = 0,
     51     ReserveRel = 1,
     52     ReserveGOT = 2,
     53     ReservePLT = 4,
     54   };
     55 
     56   /** \enum EntryValue
     57    *  \brief The value of the entries. The symbol value will be decided at after
     58    *  layout, so we mark the entry during scanRelocation and fill up the actual
     59    *  value when applying relocations.
     60    */
     61   enum EntryValue { Default = 0, SymVal = 1 };
     62 
     63  public:
     64   explicit X86Relocator(const LinkerConfig& pConfig);
     65   ~X86Relocator();
     66 
     67   virtual Result applyRelocation(Relocation& pRelocation) = 0;
     68 
     69   virtual const char* getName(Relocation::Type pType) const = 0;
     70 
     71   const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; }
     72   SymPLTMap& getSymPLTMap() { return m_SymPLTMap; }
     73 
     74   /// scanRelocation - determine the empty entries are needed or not and create
     75   /// the empty entries if needed.
     76   /// For X86, following entries are check to create:
     77   /// - GOT entry (for .got and .got.plt sections)
     78   /// - PLT entry (for .plt section)
     79   /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
     80   void scanRelocation(Relocation& pReloc,
     81                       IRBuilder& pBuilder,
     82                       Module& pModule,
     83                       LDSection& pSection,
     84                       Input& pInput);
     85 
     86  protected:
     87   /// addCopyReloc - add a copy relocation into .rel.dyn for pSym
     88   /// @param pSym - A resolved copy symbol that defined in BSS section
     89   void addCopyReloc(ResolveInfo& pSym, X86GNULDBackend& pTarget);
     90 
     91   /// defineSymbolforCopyReloc - allocate a space in BSS section and
     92   /// and force define the copy of pSym to BSS section
     93   /// @return the output LDSymbol of the copy symbol
     94   LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker,
     95                                      const ResolveInfo& pSym,
     96                                      X86GNULDBackend& pTarget);
     97 
     98  private:
     99   virtual void scanLocalReloc(Relocation& pReloc,
    100                               IRBuilder& pBuilder,
    101                               Module& pModule,
    102                               LDSection& pSection) = 0;
    103 
    104   virtual void scanGlobalReloc(Relocation& pReloc,
    105                                IRBuilder& pBuilder,
    106                                Module& pModule,
    107                                LDSection& pSection) = 0;
    108 
    109  private:
    110   SymPLTMap m_SymPLTMap;
    111 };
    112 
    113 /** \class X86_32Relocator
    114  *  \brief X86_32Relocator creates and destroys the X86-32 relocations.
    115  *
    116  */
    117 class X86_32Relocator : public X86Relocator {
    118  public:
    119   typedef KeyEntryMap<ResolveInfo, X86_32GOTEntry> SymGOTMap;
    120   typedef KeyEntryMap<ResolveInfo, X86_32GOTEntry> SymGOTPLTMap;
    121 
    122   enum {
    123     R_386_TLS_OPT = 44  // mcld internal relocation type
    124   };
    125 
    126  public:
    127   X86_32Relocator(X86_32GNULDBackend& pParent, const LinkerConfig& pConfig);
    128 
    129   Result applyRelocation(Relocation& pRelocation);
    130 
    131   X86_32GNULDBackend& getTarget() { return m_Target; }
    132 
    133   const X86_32GNULDBackend& getTarget() const { return m_Target; }
    134 
    135   const char* getName(Relocation::Type pType) const;
    136 
    137   Size getSize(Relocation::Type pType) const;
    138 
    139   const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; }
    140   SymGOTMap& getSymGOTMap() { return m_SymGOTMap; }
    141 
    142   const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
    143   SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; }
    144 
    145   X86_32GOTEntry& getTLSModuleID();
    146 
    147   /// mayHaveFunctionPointerAccess - check if the given reloc would possibly
    148   /// access a function pointer.
    149   virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const;
    150 
    151   /// getDebugStringOffset - get the offset from the relocation target. This is
    152   /// used to get the debug string offset.
    153   uint32_t getDebugStringOffset(Relocation& pReloc) const;
    154 
    155   /// applyDebugStringOffset - apply the relocation target to specific offset.
    156   /// This is used to set the debug string offset.
    157   void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset);
    158 
    159  private:
    160   void scanLocalReloc(Relocation& pReloc,
    161                       IRBuilder& pBuilder,
    162                       Module& pModule,
    163                       LDSection& pSection);
    164 
    165   void scanGlobalReloc(Relocation& pReloc,
    166                        IRBuilder& pBuilder,
    167                        Module& pModule,
    168                        LDSection& pSection);
    169 
    170   /// -----  tls optimization  ----- ///
    171   /// convert R_386_TLS_IE to R_386_TLS_LE
    172   void convertTLSIEtoLE(Relocation& pReloc, LDSection& pSection);
    173 
    174  private:
    175   X86_32GNULDBackend& m_Target;
    176   SymGOTMap m_SymGOTMap;
    177   SymGOTPLTMap m_SymGOTPLTMap;
    178 };
    179 
    180 /** \class X86_64Relocator
    181  *  \brief X86_64Relocator creates and destroys the X86-64 relocations.
    182  *
    183  */
    184 class X86_64Relocator : public X86Relocator {
    185  public:
    186   typedef KeyEntryMap<ResolveInfo, X86_64GOTEntry> SymGOTMap;
    187   typedef KeyEntryMap<ResolveInfo, X86_64GOTEntry> SymGOTPLTMap;
    188   typedef KeyEntryMap<Relocation, Relocation> RelRelMap;
    189 
    190  public:
    191   X86_64Relocator(X86_64GNULDBackend& pParent, const LinkerConfig& pConfig);
    192 
    193   Result applyRelocation(Relocation& pRelocation);
    194 
    195   X86_64GNULDBackend& getTarget() { return m_Target; }
    196 
    197   const X86_64GNULDBackend& getTarget() const { return m_Target; }
    198 
    199   const char* getName(Relocation::Type pType) const;
    200 
    201   Size getSize(Relocation::Type pType) const;
    202 
    203   const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; }
    204   SymGOTMap& getSymGOTMap() { return m_SymGOTMap; }
    205 
    206   const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
    207   SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; }
    208 
    209   const RelRelMap& getRelRelMap() const { return m_RelRelMap; }
    210   RelRelMap& getRelRelMap() { return m_RelRelMap; }
    211 
    212   /// mayHaveFunctionPointerAccess - check if the given reloc would possibly
    213   /// access a function pointer.
    214   virtual bool mayHaveFunctionPointerAccess(const Relocation& pReloc) const;
    215 
    216   /// getDebugStringOffset - get the offset from the relocation target. This is
    217   /// used to get the debug string offset.
    218   uint32_t getDebugStringOffset(Relocation& pReloc) const;
    219 
    220   /// applyDebugStringOffset - apply the relocation target to specific offset.
    221   /// This is used to set the debug string offset.
    222   void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset);
    223 
    224  private:
    225   void scanLocalReloc(Relocation& pReloc,
    226                       IRBuilder& pBuilder,
    227                       Module& pModule,
    228                       LDSection& pSection);
    229 
    230   void scanGlobalReloc(Relocation& pReloc,
    231                        IRBuilder& pBuilder,
    232                        Module& pModule,
    233                        LDSection& pSection);
    234 
    235  private:
    236   X86_64GNULDBackend& m_Target;
    237   SymGOTMap m_SymGOTMap;
    238   SymGOTPLTMap m_SymGOTPLTMap;
    239   RelRelMap m_RelRelMap;
    240 };
    241 
    242 }  // namespace mcld
    243 
    244 #endif  // TARGET_X86_X86RELOCATOR_H_
    245