• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getTarget()81   ARMGNULDBackend& getTarget()
82   { return m_Target; }
83 
getTarget()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 
getSymGOTMap()91   const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; }
getSymGOTMap()92   SymGOTMap&       getSymGOTMap()       { return m_SymGOTMap; }
93 
getSymPLTMap()94   const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; }
getSymPLTMap()95   SymPLTMap&       getSymPLTMap()       { return m_SymPLTMap; }
96 
getSymGOTPLTMap()97   const SymGOTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
getSymGOTPLTMap()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