blob: 8e320620bdb30f389ef2d421ad7c4774d9c823c7 [file] [log] [blame]
Stephen Hines6f757552013-03-04 19:51:03 -08001//===- 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//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -08009#ifndef TARGET_HEXAGON_HEXAGONLDBACKEND_H_
10#define TARGET_HEXAGON_HEXAGONLDBACKEND_H_
Stephen Hines6f757552013-03-04 19:51:03 -080011
12#include "HexagonELFDynamic.h"
13#include "HexagonGOT.h"
14#include "HexagonPLT.h"
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070015#include "HexagonGOTPLT.h"
Stephen Hines37b74a32014-11-26 18:48:20 -080016#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"
Stephen Hines6f757552013-03-04 19:51:03 -080022
23namespace mcld {
24
Stephen Hines6f757552013-03-04 19:51:03 -080025class HexagonGNUInfo;
Stephen Hines37b74a32014-11-26 18:48:20 -080026class LinkerConfig;
Stephen Hines6f757552013-03-04 19:51:03 -080027
28//===----------------------------------------------------------------------===//
29/// HexagonLDBackend - linker backend of Hexagon target of GNU ELF format
30///
Stephen Hines37b74a32014-11-26 18:48:20 -080031class HexagonLDBackend : public GNULDBackend {
32 public:
Stephen Hines6f757552013-03-04 19:51:03 -080033 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
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070050 bool allocateCommonSymbols(Module& pModule);
51
Stephen Hines6f757552013-03-04 19:51:03 -080052 /// 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.
Stephen Hines0dea6bc2014-07-15 18:33:32 -070085 const Relocator* getRelocator() const;
Stephen Hines6f757552013-03-04 19:51:03 -080086 Relocator* getRelocator();
87
Stephen Hines37b74a32014-11-26 18:48:20 -080088 ResolveInfo::Desc getSymDesc(uint16_t shndx) const {
Stephen Hines6f757552013-03-04 19:51:03 -080089 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
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070099 bool initBRIslandFactory();
Stephen Hines6f757552013-03-04 19:51:03 -0800100
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700101 bool initStubFactory();
Stephen Hines6f757552013-03-04 19:51:03 -0800102
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700103 bool mayRelax() { return true; }
Stephen Hines6f757552013-03-04 19:51:03 -0800104
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700105 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
Stephen Hines6f757552013-03-04 19:51:03 -0800106
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700107 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;
Stephen Hines6f757552013-03-04 19:51:03 -0800120
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
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700127 /// mergeSection - merge target dependent sections
Stephen Hines87f34652014-02-14 18:00:16 -0800128 bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700129
130 /// readSection - read target dependent sections
131 bool readSection(Input& pInput, SectionData& pSD);
132
Stephen Hines37b74a32014-11-26 18:48:20 -0800133 bool MoveCommonData(SectionData& pFrom, SectionData& pTo);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700134
135 bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo);
136
137 bool SetSDataSection();
138
139 uint32_t getGP() { return m_psdata->addr(); }
140
Stephen Hines37b74a32014-11-26 18:48:20 -0800141 Relocation::Type getCopyRelType() const { return m_CopyRel; }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700142
Stephen Hines37b74a32014-11-26 18:48:20 -0800143 virtual uint32_t getGOTSymbolAddr() { return m_pGOTSymbol->value(); }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700144
Stephen Hines37b74a32014-11-26 18:48:20 -0800145 protected:
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700146 void defineGOTSymbol(IRBuilder& pBuilder, Fragment&);
147
Stephen Hines37b74a32014-11-26 18:48:20 -0800148 private:
Stephen Hines6f757552013-03-04 19:51:03 -0800149 /// getRelEntrySize - the size in BYTE of rela type relocation
Stephen Hines37b74a32014-11-26 18:48:20 -0800150 size_t getRelEntrySize() { return 0; }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700151
152 /// getRelaEntrySize - the size in BYTE of rela type relocation
Stephen Hines37b74a32014-11-26 18:48:20 -0800153 size_t getRelaEntrySize() { return 12; }
Stephen Hines6f757552013-03-04 19:51:03 -0800154
155 /// doCreateProgramHdrs - backend can implement this function to create the
156 /// target-dependent segments
157 void doCreateProgramHdrs(Module& pModule);
158
Stephen Hines0dea6bc2014-07-15 18:33:32 -0700159 /// maxFwdBranchOffset
Stephen Hinescfcb2242016-03-08 00:18:09 -0800160 int64_t maxFwdBranchOffset() const { return ~(~0U << 6); }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700161
162 virtual void setGOTSectionSize(IRBuilder& pBuilder);
163
164 virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const;
165
166 virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion,
Stephen Hines551ae4e2014-04-24 14:41:24 -0700167 const ELFFileFormat* FileFormat) const;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700168
169 virtual void setRelaDynSize();
170 virtual void setRelaPLTSize();
171
Stephen Hines37b74a32014-11-26 18:48:20 -0800172 private:
Stephen Hines6f757552013-03-04 19:51:03 -0800173 Relocator* m_pRelocator;
174 HexagonGOT* m_pGOT;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700175 HexagonGOTPLT* m_pGOTPLT;
Stephen Hines6f757552013-03-04 19:51:03 -0800176 HexagonPLT* m_pPLT;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700177 /// 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;
Stephen Hines6f757552013-03-04 19:51:03 -0800181
182 HexagonELFDynamic* m_pDynamic;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700183
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
Stephen Hines6f757552013-03-04 19:51:03 -0800192 LDSymbol* m_pGOTSymbol;
193 LDSymbol* m_pBSSEnd;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700194 Relocation::Type m_CopyRel;
Stephen Hines6f757552013-03-04 19:51:03 -0800195};
Stephen Hines6f757552013-03-04 19:51:03 -0800196
Stephen Hines37b74a32014-11-26 18:48:20 -0800197} // namespace mcld
Stephen Hines6f757552013-03-04 19:51:03 -0800198
Stephen Hines37b74a32014-11-26 18:48:20 -0800199#endif // TARGET_HEXAGON_HEXAGONLDBACKEND_H_