Home | History | Annotate | Download | only in ARM
      1 //===-  ARMRelocator.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 ARM_RELOCATION_FACTORY_H
     10 #define ARM_RELOCATION_FACTORY_H
     11 #ifdef ENABLE_UNITTEST
     12 #include <gtest.h>
     13 #endif
     14 
     15 #include <mcld/LD/Relocator.h>
     16 #include <mcld/Target/GOT.h>
     17 #include <mcld/Target/SymbolEntryMap.h>
     18 #include "ARMLDBackend.h"
     19 
     20 namespace mcld {
     21 
     22 /** \class ARMRelocator
     23  *  \brief ARMRelocator creates and destroys the ARM relocations.
     24  *
     25  */
     26 class ARMRelocator : public Relocator
     27 {
     28 public:
     29   typedef SymbolEntryMap<ARMGOTEntry> SymGOTMap;
     30   typedef SymbolEntryMap<ARMPLT1> SymPLTMap;
     31 
     32   /** \enum ReservedEntryType
     33    *  \brief The reserved entry type of reserved space in ResolveInfo.
     34    *
     35    *  This is used for sacnRelocation to record what kinds of entries are
     36    *  reserved for this resolved symbol
     37    *
     38    *  In ARM, there are three kinds of entries, GOT, PLT, and dynamic reloction.
     39    *  GOT may needs a corresponding relocation to relocate itself, so we
     40    *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
     41    *  symbol, there might be two kinds of entries reserved for different location.
     42    *  For example, reference to the same symbol, one may use GOT and the other may
     43    *  use dynamic relocation.
     44    *
     45    *  bit:  3       2      1     0
     46    *   | PLT | GOTRel | GOT | Rel |
     47    *
     48    *  value    Name         - Description
     49    *
     50    *  0000     None         - no reserved entry
     51    *  0001     ReserveRel   - reserve an dynamic relocation entry
     52    *  0010     ReserveGOT   - reserve an GOT entry
     53    *  0011     GOTandRel    - For different relocation, we've reserved GOT and
     54    *                          Rel for different location.
     55    *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
     56    *                          relocation entry which relocate this GOT entry
     57    *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
     58    *                          and relocation entry for different location.
     59    *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
     60    *                          Dynamic relocation entries
     61    *  1001     PLTandRel    - For different relocation, we've reserved PLT and
     62    *                          Rel for different location.
     63    */
     64   enum ReservedEntryType {
     65     None         = 0,
     66     ReserveRel   = 1,
     67     ReserveGOT   = 2,
     68     GOTandRel    = 3,
     69     GOTRel       = 4,
     70     GOTRelandRel = 5,
     71     ReservePLT   = 8,
     72     PLTandRel    = 9
     73   };
     74 
     75 public:
     76   ARMRelocator(ARMGNULDBackend& pParent, const LinkerConfig& pConfig);
     77   ~ARMRelocator();
     78 
     79   Result applyRelocation(Relocation& pRelocation);
     80 
     81   ARMGNULDBackend& getTarget()
     82   { return m_Target; }
     83 
     84   const ARMGNULDBackend& getTarget() const
     85   { return m_Target; }
     86 
     87   const char* getName(Relocation::Type pType) const;
     88 
     89   Size getSize(Relocation::Type pType) const;
     90 
     91   const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; }
     92   SymGOTMap&       getSymGOTMap()       { return m_SymGOTMap; }
     93 
     94   const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; }
     95   SymPLTMap&       getSymPLTMap()       { return m_SymPLTMap; }
     96 
     97   const SymGOTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
     98   SymGOTMap&       getSymGOTPLTMap()       { return m_SymGOTPLTMap; }
     99 
    100   /// scanRelocation - determine the empty entries are needed or not and create
    101   /// the empty entries if needed.
    102   /// For ARM, following entries are check to create:
    103   /// - GOT entry (for .got section)
    104   /// - PLT entry (for .plt section)
    105   /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
    106   void scanRelocation(Relocation& pReloc,
    107                       IRBuilder& pBuilder,
    108                       Module& pModule,
    109                       LDSection& pSection);
    110 
    111 private:
    112   void scanLocalReloc(Relocation& pReloc, const LDSection& pSection);
    113 
    114   void scanGlobalReloc(Relocation& pReloc,
    115                        IRBuilder& pBuilder,
    116                        const LDSection& pSection);
    117 
    118   void checkValidReloc(Relocation& pReloc) const;
    119 
    120   /// addCopyReloc - add a copy relocation into .rel.dyn for pSym
    121   /// @param pSym - A resolved copy symbol that defined in BSS section
    122   void addCopyReloc(ResolveInfo& pSym);
    123 
    124   /// defineSymbolforCopyReloc - allocate a space in BSS section and
    125   /// and force define the copy of pSym to BSS section
    126   /// @return the output LDSymbol of the copy symbol
    127   LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker,
    128                                      const ResolveInfo& pSym);
    129 
    130 private:
    131   ARMGNULDBackend& m_Target;
    132   SymGOTMap m_SymGOTMap;
    133   SymPLTMap m_SymPLTMap;
    134   SymGOTMap m_SymGOTPLTMap;
    135 };
    136 
    137 } // namespace of mcld
    138 
    139 #endif
    140 
    141