MipsRelocator.h revision f33f6de54db174aa679a4b6d1e040d37e95541c0
1//===- MipsRelocator.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 MIPS_RELOCATION_FACTORY_H
10#define MIPS_RELOCATION_FACTORY_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <llvm/ADT/DenseMapInfo.h>
16#include <mcld/LD/Relocator.h>
17#include <mcld/Support/GCFactory.h>
18#include "MipsLDBackend.h"
19
20namespace mcld {
21
22class MipsRelocationInfo;
23
24/** \class MipsRelocator
25 *  \brief MipsRelocator creates and destroys the Mips relocations.
26 */
27class MipsRelocator : public Relocator
28{
29public:
30  enum ReservedEntryType {
31    None          = 0,  // no reserved entry
32    ReserveRel    = 1,  // reserve a dynamic relocation entry
33    ReserveGot    = 2,  // reserve a GOT entry
34    ReservePLT    = 4   // reserve a PLT entry
35  };
36
37public:
38  MipsRelocator(MipsGNULDBackend& pParent, const LinkerConfig& pConfig);
39
40  /// scanRelocation - determine the empty entries are needed or not and
41  /// create the empty entries if needed.
42  /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
43  void scanRelocation(Relocation& pReloc,
44                      IRBuilder& pBuilder,
45                      Module& pModule,
46                      LDSection& pSection,
47                      Input& pInput);
48
49  /// initializeScan - do initialization before scan relocations in pInput
50  /// @return - return true for initialization success
51  bool initializeScan(Input& pInput);
52
53  /// finalizeScan - do finalization after scan relocations in pInput
54  /// @return - return true for finalization success
55  bool finalizeScan(Input& pInput);
56
57  /// initializeApply - do initialization before apply relocations in pInput
58  /// @return - return true for initialization success
59  bool initializeApply(Input& pInput);
60
61  /// finalizeApply - do finalization after apply relocations in pInput
62  /// @return - return true for finalization success
63  bool finalizeApply(Input& pInput);
64
65  Result applyRelocation(Relocation& pReloc);
66
67  const Input& getApplyingInput() const
68  { return *m_pApplyingInput; }
69
70  MipsGNULDBackend& getTarget()
71  { return m_Target; }
72
73  const MipsGNULDBackend& getTarget() const
74  { return m_Target; }
75
76  /// postponeRelocation - save R_MIPS_LO16 paired relocations
77  /// like R_MISP_HI16 and R_MIPS_GOT16 for a future processing.
78  void postponeRelocation(Relocation& pReloc);
79
80  /// applyPostponedRelocations - apply all postponed relocations
81  /// paired with the R_MIPS_LO16 one.
82  void applyPostponedRelocations(MipsRelocationInfo& pLo16Reloc);
83
84  /// isGpDisp - return true if relocation is against _gp_disp symbol.
85  bool isGpDisp(const Relocation& pReloc) const;
86
87  /// getGPAddress - return address of _gp symbol.
88  Address getGPAddress();
89
90  /// getGP0 - the gp value used to create the relocatable objects
91  /// in the processing input.
92  Address getGP0();
93
94  /// getLocalGOTEntry - initialize and return a local GOT entry
95  /// for this relocation.
96  Fragment& getLocalGOTEntry(MipsRelocationInfo& pReloc,
97                             Relocation::DWord entryValue);
98
99  /// getGlobalGOTEntry - initialize and return a global GOT entry
100  /// for this relocation.
101  Fragment& getGlobalGOTEntry(MipsRelocationInfo& pReloc);
102
103  /// getGOTOffset - return offset of corresponded GOT entry.
104  Address getGOTOffset(MipsRelocationInfo& pReloc);
105
106  /// createDynRel - initialize dynamic relocation for the relocation.
107  void createDynRel(MipsRelocationInfo& pReloc);
108
109  /// getPLTOffset - initialize PLT-related entries for the symbol
110  /// @return - return address of PLT entry
111  uint64_t getPLTAddress(ResolveInfo& rsym);
112
113  /// calcAHL - calculate combined addend used
114  /// by R_MIPS_HI16 and R_MIPS_GOT16 relocations.
115  uint64_t calcAHL(const MipsRelocationInfo& pHiReloc);
116
117  /// isN64ABI - check current ABI
118  bool isN64ABI() const;
119
120  const char* getName(Relocation::Type pType) const;
121
122  Size getSize(Relocation::Type pType) const;
123
124protected:
125  /// setupRelDynEntry - create dynamic relocation entry.
126  virtual void setupRelDynEntry(FragmentRef& pFragRef, ResolveInfo* pSym) = 0;
127
128  /// isLocalReloc - handle relocation as a local symbol
129  bool isLocalReloc(ResolveInfo& pSym) const;
130
131private:
132  typedef std::pair<Fragment*, Fragment*> PLTDescriptor;
133  typedef llvm::DenseMap<const ResolveInfo*, PLTDescriptor> SymPLTMap;
134  typedef llvm::DenseSet<Relocation*> RelocationSet;
135  typedef llvm::DenseMap<const ResolveInfo*, RelocationSet> SymRelocSetMap;
136
137private:
138  MipsGNULDBackend& m_Target;
139  SymPLTMap m_SymPLTMap;
140  Input* m_pApplyingInput;
141  SymRelocSetMap m_PostponedRelocs;
142  MipsRelocationInfo* m_CurrentLo16Reloc;
143
144private:
145  void scanLocalReloc(MipsRelocationInfo& pReloc,
146                      IRBuilder& pBuilder,
147                      const LDSection& pSection);
148
149  void scanGlobalReloc(MipsRelocationInfo& pReloc,
150                       IRBuilder& pBuilder,
151                       const LDSection& pSection);
152
153  /// isPostponed - relocation applying needs to be postponed.
154  bool isPostponed(const Relocation& pReloc) const;
155
156  /// addCopyReloc - add a copy relocation into .rel.dyn for pSym
157  /// @param pSym - A resolved copy symbol that defined in BSS section
158  void addCopyReloc(ResolveInfo& pSym);
159
160  /// defineSymbolforCopyReloc - allocate a space in BSS section and
161  /// and force define the copy of pSym to BSS section
162  /// @return the output LDSymbol of the copy symbol
163  LDSymbol& defineSymbolforCopyReloc(IRBuilder& pBuilder,
164                                     const ResolveInfo& pSym);
165
166  /// isRel - returns true if REL relocation record format is expected
167  bool isRel() const;
168};
169
170/** \class Mips32Relocator
171 *  \brief Mips32Relocator creates and destroys the Mips 32-bit relocations.
172 */
173class Mips32Relocator : public MipsRelocator
174{
175public:
176  Mips32Relocator(Mips32GNULDBackend& pParent, const LinkerConfig& pConfig);
177
178private:
179  // MipsRelocator
180  void setupRelDynEntry(FragmentRef& pFragRef, ResolveInfo* pSym);
181};
182
183/** \class Mips64Relocator
184 *  \brief Mips64Relocator creates and destroys the Mips 64-bit relocations.
185 */
186class Mips64Relocator : public MipsRelocator
187{
188public:
189  Mips64Relocator(Mips64GNULDBackend& pParent, const LinkerConfig& pConfig);
190
191private:
192  // MipsRelocator
193  void setupRelDynEntry(FragmentRef& pFragRef, ResolveInfo* pSym);
194};
195
196} // namespace of mcld
197
198#endif
199