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