HexagonLDBackend.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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 HEXAGON_LDBACKEND_H
10#define HEXAGON_LDBACKEND_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  Relocator* getRelocator();
87
88  ResolveInfo::Desc getSymDesc(uint16_t shndx) const
89  {
90    if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON &&
91        shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8)
92      return ResolveInfo::Common;
93    return ResolveInfo::NoneDesc;
94  }
95
96  void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
97
98  void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
99
100  bool initBRIslandFactory();
101
102  bool initStubFactory();
103
104  bool mayRelax() { return true; }
105
106  bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
107
108  bool initTargetStubs();
109
110  OutputRelocSection& getRelaDyn();
111
112  const OutputRelocSection& getRelaDyn() const;
113
114  HexagonGOTPLT& getGOTPLT();
115
116  const HexagonGOTPLT& getGOTPLT() const;
117
118  OutputRelocSection& getRelaPLT();
119
120  const OutputRelocSection& getRelaPLT() const;
121
122  /// getTargetSectionOrder - compute the layout order of Hexagon target section
123  unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
124
125  /// finalizeTargetSymbols - finalize the symbol value
126  bool finalizeTargetSymbols();
127
128  /// mergeSection - merge target dependent sections
129  bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
130
131  /// readSection - read target dependent sections
132  bool readSection(Input& pInput, SectionData& pSD);
133
134  bool MoveCommonData(SectionData &pFrom, SectionData &pTo);
135
136  bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo);
137
138  bool SetSDataSection();
139
140  uint32_t getGP() { return m_psdata->addr(); }
141
142  Relocation::Type getCopyRelType()    const { return m_CopyRel;    }
143
144  virtual uint32_t getGOTSymbolAddr() {
145    return m_pGOTSymbol->value();
146  }
147
148
149protected:
150  void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
151
152private:
153  /// getRelEntrySize - the size in BYTE of rela type relocation
154  size_t getRelEntrySize()
155  { return 0; }
156
157  /// getRelaEntrySize - the size in BYTE of rela type relocation
158  size_t getRelaEntrySize()
159  { return 12; }
160
161  /// doCreateProgramHdrs - backend can implement this function to create the
162  /// target-dependent segments
163  void doCreateProgramHdrs(Module& pModule);
164
165  uint64_t maxBranchOffset() { return ~(~0 << 6); }
166
167  virtual void setGOTSectionSize(IRBuilder& pBuilder);
168
169  virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
170
171  virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
172					 const ELFFileFormat* FileFormat) const;
173
174  virtual void setRelaDynSize();
175  virtual void setRelaPLTSize();
176
177private:
178  Relocator* m_pRelocator;
179  HexagonGOT* m_pGOT;
180  HexagonGOTPLT* m_pGOTPLT;
181  HexagonPLT* m_pPLT;
182  /// m_RelaDyn - dynamic relocation table of .rela.dyn
183  OutputRelocSection* m_pRelaDyn;
184  /// m_RelaPLT - dynamic relocation table of .rela.plt
185  OutputRelocSection* m_pRelaPLT;
186
187  HexagonELFDynamic* m_pDynamic;
188
189  LDSection* m_psdata;
190  LDSection* m_pscommon_1;
191  LDSection* m_pscommon_2;
192  LDSection* m_pscommon_4;
193  LDSection* m_pscommon_8;
194  LDSection* m_pstart;
195  LDSymbol* m_psdabase;
196
197  LDSymbol* m_pGOTSymbol;
198  LDSymbol* m_pBSSEnd;
199  Relocation::Type m_CopyRel;
200};
201} // namespace of mcld
202
203#endif
204
205