1//===-  HexagonRelocator.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_HEXAGON_HEXAGONRELOCATOR_H_
10#define TARGET_HEXAGON_HEXAGONRELOCATOR_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 "HexagonLDBackend.h"
17
18namespace mcld {
19
20class LinkerConfig;
21class ResolveInfo;
22
23/** \class HexagonRelocator
24 *  \brief HexagonRelocator creates and destroys the Hexagon relocations.
25 *
26 */
27class HexagonRelocator : public Relocator {
28 public:
29  typedef KeyEntryMap<ResolveInfo, PLTEntryBase> SymPLTMap;
30  typedef KeyEntryMap<ResolveInfo, HexagonGOTEntry> SymGOTMap;
31  typedef KeyEntryMap<ResolveInfo, HexagonGOTEntry> SymGOTPLTMap;
32  typedef KeyEntryMap<Relocation, Relocation> RelRelMap;
33
34 public:
35  /** \enum ReservedEntryType
36   *  \brief The reserved entry type of reserved space in ResolveInfo.
37   *
38   *  This is used for sacnRelocation to record what kinds of entries are
39   *  reserved for this resolved symbol. In Hexagon, there are three kinds
40   *  of entries, GOT, PLT, and dynamic relocation.
41   *
42   *  bit:  3     2     1     0
43   *   |    | PLT | GOT | Rel |
44   *
45   *  value    Name         - Description
46   *
47   *  0000     None         - no reserved entry
48   *  0001     ReserveRel   - reserve an dynamic relocation entry
49   *  0010     ReserveGOT   - reserve an GOT entry
50   *  0100     ReservePLT   - reserve an PLT entry and the corresponding GOT,
51   *
52   */
53  enum ReservedEntryType {
54    None = 0,
55    ReserveRel = 1,
56    ReserveGOT = 2,
57    ReservePLT = 4,
58  };
59
60  /** \enum EntryValue
61   *  \brief The value of the entries. The symbol value will be decided at after
62   *  layout, so we mark the entry during scanRelocation and fill up the actual
63   *  value when applying relocations.
64   */
65  enum EntryValue { Default = 0, SymVal = 1 };
66
67  HexagonRelocator(HexagonLDBackend& pParent, const LinkerConfig& pConfig);
68  ~HexagonRelocator();
69
70  Result applyRelocation(Relocation& pRelocation);
71
72  /// scanRelocation - determine the empty entries are needed or not and create
73  /// the empty entries if needed.
74  /// For Hexagon, following entries are check to create:
75  /// - GOT entry (for .got and .got.plt sections)
76  /// - PLT entry (for .plt section)
77  /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
78  void scanRelocation(Relocation& pReloc,
79                      IRBuilder& pBuilder,
80                      Module& pModule,
81                      LDSection& pSection,
82                      Input& pInput);
83
84  // Handle partial linking
85  void partialScanRelocation(Relocation& pReloc,
86                             Module& pModule);
87
88  HexagonLDBackend& getTarget() { return m_Target; }
89
90  const HexagonLDBackend& getTarget() const { return m_Target; }
91
92  const char* getName(Relocation::Type pType) const;
93
94  Size getSize(Relocation::Type pType) const;
95
96  const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; }
97  SymPLTMap& getSymPLTMap() { return m_SymPLTMap; }
98
99  const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; }
100  SymGOTMap& getSymGOTMap() { return m_SymGOTMap; }
101
102  const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; }
103  SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; }
104
105  const RelRelMap& getRelRelMap() const { return m_RelRelMap; }
106  RelRelMap& getRelRelMap() { return m_RelRelMap; }
107
108  /// getDebugStringOffset - get the offset from the relocation target. This is
109  /// used to get the debug string offset.
110  uint32_t getDebugStringOffset(Relocation& pReloc) const { return 0; }
111
112  /// applyDebugStringOffset - apply the relocation target to specific offset.
113  /// This is used to set the debug string offset.
114  void applyDebugStringOffset(Relocation& pReloc, uint32_t pOffset) {}
115
116 protected:
117  /// addCopyReloc - add a copy relocation into .rela.dyn for pSym
118  /// @param pSym - A resolved copy symbol that defined in BSS section
119  void addCopyReloc(ResolveInfo& pSym, HexagonLDBackend& pTarget);
120
121  /// defineSymbolforCopyReloc - allocate a space in BSS section and
122  /// and force define the copy of pSym to BSS section
123  /// @return the output LDSymbol of the copy symbol
124  LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker,
125                                     const ResolveInfo& pSym,
126                                     HexagonLDBackend& pTarget);
127
128 private:
129  virtual void scanLocalReloc(Relocation& pReloc,
130                              IRBuilder& pBuilder,
131                              Module& pModule,
132                              LDSection& pSection);
133
134  virtual void scanGlobalReloc(Relocation& pReloc,
135                               IRBuilder& pBuilder,
136                               Module& pModule,
137                               LDSection& pSection);
138
139  HexagonLDBackend& m_Target;
140  SymPLTMap m_SymPLTMap;
141  SymGOTMap m_SymGOTMap;
142  SymGOTPLTMap m_SymGOTPLTMap;
143  RelRelMap m_RelRelMap;
144};
145
146}  // namespace mcld
147
148#endif  // TARGET_HEXAGON_HEXAGONRELOCATOR_H_
149