1//===- HexagonLDBackend.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_HEXAGONLDBACKEND_H_
10#define TARGET_HEXAGON_HEXAGONLDBACKEND_H_
11
12#include "HexagonELFDynamic.h"
13#include "HexagonGOT.h"
14#include "HexagonPLT.h"
15#include "HexagonGOTPLT.h"
16#include "mcld/IRBuilder.h"
17#include "mcld/LinkerConfig.h"
18#include "mcld/LD/LDSection.h"
19#include "mcld/Object/ObjectBuilder.h"
20#include "mcld/Target/GNULDBackend.h"
21#include "mcld/Target/OutputRelocSection.h"
22
23namespace mcld {
24
25class HexagonGNUInfo;
26class LinkerConfig;
27
28//===----------------------------------------------------------------------===//
29/// HexagonLDBackend - linker backend of Hexagon target of GNU ELF format
30///
31class HexagonLDBackend : public GNULDBackend {
32 public:
33  HexagonLDBackend(const LinkerConfig& pConfig, HexagonGNUInfo* pInfo);
34
35  ~HexagonLDBackend();
36
37  uint32_t machine() const;
38
39  HexagonGOT& getGOT();
40
41  const HexagonGOT& getGOT() const;
42
43  HexagonPLT& getPLT();
44
45  const HexagonPLT& getPLT() const;
46
47  /// preLayout - Backend can do any needed modification before layout
48  void doPreLayout(IRBuilder& pBuilder);
49
50  bool allocateCommonSymbols(Module& pModule);
51
52  /// postLayout - Backend can do any needed modification after layout
53  void doPostLayout(Module& pModule, IRBuilder& pBuilder);
54
55  /// dynamic - the dynamic section of the target machine.
56  /// Use co-variant return type to return its own dynamic section.
57  HexagonELFDynamic& dynamic();
58
59  /// dynamic - the dynamic section of the target machine.
60  /// Use co-variant return type to return its own dynamic section.
61  const HexagonELFDynamic& dynamic() const;
62
63  /// emitSectionData - write out the section data into the memory region.
64  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
65  /// call back target backend to emit the data.
66  ///
67  /// Backends handle the target-special tables (plt, gp,...) by themselves.
68  /// Backend can put the data of the tables in MCSectionData directly
69  ///  - LDSection.getSectionData can get the section data.
70  /// Or, backend can put the data into special data structure
71  ///  - backend can maintain its own map<LDSection, table> to get the table
72  /// from given LDSection.
73  ///
74  /// @param pSection - the given LDSection
75  /// @param pLayout - for comouting the size of fragment
76  /// @param pRegion - the region to write out data
77  /// @return the size of the table in the file.
78  uint64_t emitSectionData(const LDSection& pSection,
79                           MemoryRegion& pRegion) const;
80
81  /// initRelocator - create and initialize Relocator.
82  bool initRelocator();
83
84  /// getRelocator - return relocator.
85  const Relocator* getRelocator() const;
86  Relocator* getRelocator();
87
88  ResolveInfo::Desc getSymDesc(uint16_t shndx) const {
89    if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON &&
90        shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8)
91      return ResolveInfo::Common;
92    return ResolveInfo::NoneDesc;
93  }
94
95  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
96
97  void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
98
99  bool initBRIslandFactory();
100
101  bool initStubFactory();
102
103  bool mayRelax() { return true; }
104
105  bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
106
107  bool initTargetStubs();
108
109  OutputRelocSection& getRelaDyn();
110
111  const OutputRelocSection& getRelaDyn() const;
112
113  HexagonGOTPLT& getGOTPLT();
114
115  const HexagonGOTPLT& getGOTPLT() const;
116
117  OutputRelocSection& getRelaPLT();
118
119  const OutputRelocSection& getRelaPLT() const;
120
121  /// getTargetSectionOrder - compute the layout order of Hexagon target section
122  unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
123
124  /// finalizeTargetSymbols - finalize the symbol value
125  bool finalizeTargetSymbols();
126
127  /// mergeSection - merge target dependent sections
128  bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
129
130  /// readSection - read target dependent sections
131  bool readSection(Input& pInput, SectionData& pSD);
132
133  bool MoveCommonData(SectionData& pFrom, SectionData& pTo);
134
135  bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo);
136
137  bool SetSDataSection();
138
139  uint32_t getGP() { return m_psdata->addr(); }
140
141  Relocation::Type getCopyRelType() const { return m_CopyRel; }
142
143  virtual uint32_t getGOTSymbolAddr() { return m_pGOTSymbol->value(); }
144
145 protected:
146  void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
147
148 private:
149  /// getRelEntrySize - the size in BYTE of rela type relocation
150  size_t getRelEntrySize() { return 0; }
151
152  /// getRelaEntrySize - the size in BYTE of rela type relocation
153  size_t getRelaEntrySize() { return 12; }
154
155  /// doCreateProgramHdrs - backend can implement this function to create the
156  /// target-dependent segments
157  void doCreateProgramHdrs(Module& pModule);
158
159  /// maxFwdBranchOffset
160  int64_t maxFwdBranchOffset() const { return ~(~0U << 6); }
161
162  virtual void setGOTSectionSize(IRBuilder& pBuilder);
163
164  virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
165
166  virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
167                                         const ELFFileFormat* FileFormat) const;
168
169  virtual void setRelaDynSize();
170  virtual void setRelaPLTSize();
171
172 private:
173  Relocator* m_pRelocator;
174  HexagonGOT* m_pGOT;
175  HexagonGOTPLT* m_pGOTPLT;
176  HexagonPLT* m_pPLT;
177  /// m_RelaDyn - dynamic relocation table of .rela.dyn
178  OutputRelocSection* m_pRelaDyn;
179  /// m_RelaPLT - dynamic relocation table of .rela.plt
180  OutputRelocSection* m_pRelaPLT;
181
182  HexagonELFDynamic* m_pDynamic;
183
184  LDSection* m_psdata;
185  LDSection* m_pscommon_1;
186  LDSection* m_pscommon_2;
187  LDSection* m_pscommon_4;
188  LDSection* m_pscommon_8;
189  LDSection* m_pstart;
190  LDSymbol* m_psdabase;
191
192  LDSymbol* m_pGOTSymbol;
193  LDSymbol* m_pBSSEnd;
194  Relocation::Type m_CopyRel;
195};
196
197}  // namespace mcld
198
199#endif  // TARGET_HEXAGON_HEXAGONLDBACKEND_H_
200