blob: b46de994c20ccec48c139a373a6ece865e095c86 [file] [log] [blame]
Stephen Hines6f757552013-03-04 19:51:03 -08001//===- HexagonLDBackend.cpp -----------------------------------------------===//
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#include "Hexagon.h"
10#include "HexagonELFDynamic.h"
11#include "HexagonLDBackend.h"
12#include "HexagonRelocator.h"
13#include "HexagonGNUInfo.h"
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070014#include "HexagonAbsoluteStub.h"
Stephen Hines6f757552013-03-04 19:51:03 -080015
Stephen Hines37b74a32014-11-26 18:48:20 -080016#include "mcld/IRBuilder.h"
17#include "mcld/LinkerConfig.h"
18#include "mcld/Fragment/AlignFragment.h"
19#include "mcld/Fragment/FillFragment.h"
20#include "mcld/Fragment/RegionFragment.h"
21#include "mcld/Fragment/Stub.h"
22#include "mcld/LD/BranchIslandFactory.h"
23#include "mcld/LD/ELFFileFormat.h"
24#include "mcld/LD/ELFSegmentFactory.h"
25#include "mcld/LD/ELFSegment.h"
26#include "mcld/LD/LDContext.h"
27#include "mcld/LD/StubFactory.h"
28#include "mcld/Object/ObjectBuilder.h"
29#include "mcld/Support/MemoryArea.h"
30#include "mcld/Support/MsgHandling.h"
31#include "mcld/Support/TargetRegistry.h"
32
Stephen Hines6f757552013-03-04 19:51:03 -080033#include <llvm/ADT/Triple.h>
34#include <llvm/Support/Casting.h>
35
Stephen Hines6f757552013-03-04 19:51:03 -080036#include <cstring>
Stephen Hinescfcb2242016-03-08 00:18:09 -080037#include <vector>
Stephen Hines6f757552013-03-04 19:51:03 -080038
Stephen Hines37b74a32014-11-26 18:48:20 -080039namespace mcld {
Stephen Hines6f757552013-03-04 19:51:03 -080040
41//===----------------------------------------------------------------------===//
42// HexagonLDBackend
43//===----------------------------------------------------------------------===//
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070044HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig,
Stephen Hines6f757552013-03-04 19:51:03 -080045 HexagonGNUInfo* pInfo)
Stephen Hines37b74a32014-11-26 18:48:20 -080046 : GNULDBackend(pConfig, pInfo),
47 m_pRelocator(NULL),
48 m_pGOT(NULL),
49 m_pGOTPLT(NULL),
50 m_pPLT(NULL),
51 m_pRelaDyn(NULL),
52 m_pRelaPLT(NULL),
53 m_pDynamic(NULL),
54 m_pGOTSymbol(NULL),
55 m_CopyRel(llvm::ELF::R_HEX_COPY) {
Stephen Hines6f757552013-03-04 19:51:03 -080056}
57
Stephen Hines37b74a32014-11-26 18:48:20 -080058HexagonLDBackend::~HexagonLDBackend() {
Stephen Hines6f757552013-03-04 19:51:03 -080059 delete m_pRelocator;
60 delete m_pGOT;
61 delete m_pPLT;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070062 delete m_pRelaDyn;
63 delete m_pRelaPLT;
Stephen Hines6f757552013-03-04 19:51:03 -080064 delete m_pDynamic;
65}
66
Stephen Hines37b74a32014-11-26 18:48:20 -080067bool HexagonLDBackend::initRelocator() {
68 if (m_pRelocator == NULL) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070069 m_pRelocator = new HexagonRelocator(*this, config());
Stephen Hines6f757552013-03-04 19:51:03 -080070 }
71 return true;
72}
73
Stephen Hines37b74a32014-11-26 18:48:20 -080074const Relocator* HexagonLDBackend::getRelocator() const {
75 assert(m_pRelocator != NULL);
Stephen Hines0dea6bc2014-07-15 18:33:32 -070076 return m_pRelocator;
77}
78
Stephen Hines37b74a32014-11-26 18:48:20 -080079Relocator* HexagonLDBackend::getRelocator() {
80 assert(m_pRelocator != NULL);
Stephen Hines6f757552013-03-04 19:51:03 -080081 return m_pRelocator;
82}
83
Stephen Hines37b74a32014-11-26 18:48:20 -080084void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) {
Stephen Hines6f757552013-03-04 19:51:03 -080085 // initialize .dynamic data
Stephen Hines37b74a32014-11-26 18:48:20 -080086 if (!config().isCodeStatic() && m_pDynamic == NULL)
Stephen Hines6f757552013-03-04 19:51:03 -080087 m_pDynamic = new HexagonELFDynamic(*this, config());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070088
89 // set .got.plt and .got sizes
90 // when building shared object, the .got section is must
91 if ((LinkerConfig::Object != config().codeGenType()) &&
92 (!config().isCodeStatic())) {
93 setGOTSectionSize(pBuilder);
94
95 // set .plt size
96 if (m_pPLT->hasPLT1())
97 m_pPLT->finalizeSectionSize();
98
99 // set .rela.dyn size
100 if (!m_pRelaDyn->empty()) {
Stephen Hines37b74a32014-11-26 18:48:20 -0800101 assert(
102 !config().isCodeStatic() &&
103 "static linkage should not result in a dynamic relocation section");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700104 setRelaDynSize();
105 }
106 // set .rela.plt size
107 if (!m_pRelaPLT->empty()) {
Stephen Hines37b74a32014-11-26 18:48:20 -0800108 assert(
109 !config().isCodeStatic() &&
110 "static linkage should not result in a dynamic relocation section");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700111 setRelaPLTSize();
112 }
113 }
114 // Shared libraries are compiled with -G0 so there is no need to set SData.
115 if (LinkerConfig::Object == config().codeGenType())
116 SetSDataSection();
Stephen Hines6f757552013-03-04 19:51:03 -0800117}
118
Stephen Hines37b74a32014-11-26 18:48:20 -0800119void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) {
Stephen Hines6f757552013-03-04 19:51:03 -0800120}
121
122/// dynamic - the dynamic section of the target machine.
123/// Use co-variant return type to return its own dynamic section.
Stephen Hines37b74a32014-11-26 18:48:20 -0800124HexagonELFDynamic& HexagonLDBackend::dynamic() {
125 assert(m_pDynamic != NULL);
Stephen Hines6f757552013-03-04 19:51:03 -0800126 return *m_pDynamic;
127}
128
129/// dynamic - the dynamic section of the target machine.
130/// Use co-variant return type to return its own dynamic section.
Stephen Hines37b74a32014-11-26 18:48:20 -0800131const HexagonELFDynamic& HexagonLDBackend::dynamic() const {
132 assert(m_pDynamic != NULL);
Stephen Hines6f757552013-03-04 19:51:03 -0800133 return *m_pDynamic;
134}
135
Stephen Hines6f757552013-03-04 19:51:03 -0800136uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
Stephen Hines37b74a32014-11-26 18:48:20 -0800137 MemoryRegion& pRegion) const {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700138 if (!pRegion.size())
139 return 0;
140
141 const ELFFileFormat* FileFormat = getOutputFormat();
142 unsigned int EntrySize = 0;
143 uint64_t RegionSize = 0;
144
145 if ((LinkerConfig::Object != config().codeGenType()) &&
146 (!config().isCodeStatic())) {
Stephen Hines87f34652014-02-14 18:00:16 -0800147 if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) {
Stephen Hines87f34652014-02-14 18:00:16 -0800148 unsigned char* buffer = pRegion.begin();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700149
150 m_pPLT->applyPLT0();
151 m_pPLT->applyPLT1();
152 HexagonPLT::iterator it = m_pPLT->begin();
153 unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
154
155 memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
156 RegionSize += plt0_size;
157 ++it;
158
159 PLTEntryBase* plt1 = 0;
160 HexagonPLT::iterator ie = m_pPLT->end();
161 while (it != ie) {
162 plt1 = &(llvm::cast<PLTEntryBase>(*it));
163 EntrySize = plt1->size();
164 memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
165 RegionSize += EntrySize;
166 ++it;
167 }
168 return RegionSize;
Stephen Hines37b74a32014-11-26 18:48:20 -0800169 } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700170 RegionSize += emitGOTSectionData(pRegion);
171 return RegionSize;
Stephen Hines37b74a32014-11-26 18:48:20 -0800172 } else if (FileFormat->hasGOTPLT() &&
173 (&pSection == &(FileFormat->getGOTPLT()))) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700174 RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
175 return RegionSize;
176 }
177 }
178
179 const SectionData* sect_data = pSection.getSectionData();
180 SectionData::const_iterator frag_iter, frag_end = sect_data->end();
Stephen Hines87f34652014-02-14 18:00:16 -0800181 uint8_t* out_offset = pRegion.begin();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700182 for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
183 size_t size = frag_iter->size();
Stephen Hines37b74a32014-11-26 18:48:20 -0800184 switch (frag_iter->getKind()) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700185 case Fragment::Fillment: {
Stephen Hines37b74a32014-11-26 18:48:20 -0800186 const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter);
187 if (fill_frag.getValueSize() == 0) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700188 // virtual fillment, ignore it.
189 break;
190 }
191 memset(out_offset, fill_frag.getValue(), fill_frag.size());
192 break;
193 }
194 case Fragment::Region: {
195 const RegionFragment& region_frag =
Stephen Hines37b74a32014-11-26 18:48:20 -0800196 llvm::cast<RegionFragment>(*frag_iter);
Stephen Hines87f34652014-02-14 18:00:16 -0800197 const char* start = region_frag.getRegion().begin();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700198 memcpy(out_offset, start, size);
199 break;
200 }
201 case Fragment::Alignment: {
202 const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
203 uint64_t count = size / align_frag.getValueSize();
204 switch (align_frag.getValueSize()) {
205 case 1u:
206 std::memset(out_offset, align_frag.getValue(), count);
207 break;
208 default:
209 llvm::report_fatal_error(
Stephen Hines37b74a32014-11-26 18:48:20 -0800210 "unsupported value size for align fragment emission yet.\n");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700211 break;
Stephen Hines37b74a32014-11-26 18:48:20 -0800212 } // end switch
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700213 break;
214 }
215 case Fragment::Null: {
216 assert(0x0 == size);
217 break;
218 }
219 default:
220 llvm::report_fatal_error("unsupported fragment type.\n");
221 break;
Stephen Hines37b74a32014-11-26 18:48:20 -0800222 } // end switch
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700223 out_offset += size;
Stephen Hines37b74a32014-11-26 18:48:20 -0800224 } // end for
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700225
226 return pRegion.size();
Stephen Hines6f757552013-03-04 19:51:03 -0800227}
228
Stephen Hines37b74a32014-11-26 18:48:20 -0800229HexagonGOT& HexagonLDBackend::getGOT() {
230 assert(m_pGOT != NULL);
Stephen Hines6f757552013-03-04 19:51:03 -0800231 return *m_pGOT;
232}
233
Stephen Hines37b74a32014-11-26 18:48:20 -0800234const HexagonGOT& HexagonLDBackend::getGOT() const {
235 assert(m_pGOT != NULL);
Stephen Hines6f757552013-03-04 19:51:03 -0800236 return *m_pGOT;
237}
238
Stephen Hines37b74a32014-11-26 18:48:20 -0800239HexagonPLT& HexagonLDBackend::getPLT() {
240 assert(m_pPLT != NULL && "PLT section not exist");
Stephen Hines6f757552013-03-04 19:51:03 -0800241 return *m_pPLT;
242}
243
Stephen Hines37b74a32014-11-26 18:48:20 -0800244const HexagonPLT& HexagonLDBackend::getPLT() const {
245 assert(m_pPLT != NULL && "PLT section not exist");
Stephen Hines6f757552013-03-04 19:51:03 -0800246 return *m_pPLT;
247}
248
Stephen Hines37b74a32014-11-26 18:48:20 -0800249OutputRelocSection& HexagonLDBackend::getRelaDyn() {
250 assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700251 return *m_pRelaDyn;
Stephen Hines6f757552013-03-04 19:51:03 -0800252}
253
Stephen Hines37b74a32014-11-26 18:48:20 -0800254const OutputRelocSection& HexagonLDBackend::getRelaDyn() const {
255 assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700256 return *m_pRelaDyn;
Stephen Hines6f757552013-03-04 19:51:03 -0800257}
258
Stephen Hines37b74a32014-11-26 18:48:20 -0800259OutputRelocSection& HexagonLDBackend::getRelaPLT() {
260 assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700261 return *m_pRelaPLT;
Stephen Hines6f757552013-03-04 19:51:03 -0800262}
263
Stephen Hines37b74a32014-11-26 18:48:20 -0800264const OutputRelocSection& HexagonLDBackend::getRelaPLT() const {
265 assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700266 return *m_pRelaPLT;
267}
268
Stephen Hines37b74a32014-11-26 18:48:20 -0800269HexagonGOTPLT& HexagonLDBackend::getGOTPLT() {
270 assert(m_pGOTPLT != NULL);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700271 return *m_pGOTPLT;
272}
273
Stephen Hines37b74a32014-11-26 18:48:20 -0800274const HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const {
275 assert(m_pGOTPLT != NULL);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700276 return *m_pGOTPLT;
277}
278
Stephen Hines37b74a32014-11-26 18:48:20 -0800279void HexagonLDBackend::setRelaDynSize() {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700280 ELFFileFormat* file_format = getOutputFormat();
Stephen Hines37b74a32014-11-26 18:48:20 -0800281 file_format->getRelaDyn().setSize(m_pRelaDyn->numOfRelocs() *
282 getRelaEntrySize());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700283}
284
Stephen Hines37b74a32014-11-26 18:48:20 -0800285void HexagonLDBackend::setRelaPLTSize() {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700286 ELFFileFormat* file_format = getOutputFormat();
Stephen Hines37b74a32014-11-26 18:48:20 -0800287 file_format->getRelaPlt().setSize(m_pRelaPLT->numOfRelocs() *
288 getRelaEntrySize());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700289}
290
Stephen Hines37b74a32014-11-26 18:48:20 -0800291void HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700292 // set .got.plt size
Stephen Hines37b74a32014-11-26 18:48:20 -0800293 if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() ||
294 m_pGOTSymbol != NULL) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700295 m_pGOTPLT->finalizeSectionSize();
296 defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
297 }
298
299 // set .got size
300 if (!m_pGOT->empty())
301 m_pGOT->finalizeSectionSize();
302}
303
Stephen Hines37b74a32014-11-26 18:48:20 -0800304uint64_t HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700305 assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
306
Stephen Hines87f34652014-02-14 18:00:16 -0800307 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700308
309 HexagonGOTEntry* got = 0;
310 unsigned int EntrySize = HexagonGOTEntry::EntrySize;
311 uint64_t RegionSize = 0;
312
Stephen Hines37b74a32014-11-26 18:48:20 -0800313 for (HexagonGOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie;
314 ++it, ++buffer) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700315 got = &(llvm::cast<HexagonGOTEntry>((*it)));
316 *buffer = static_cast<uint32_t>(got->getValue());
317 RegionSize += EntrySize;
318 }
319
320 return RegionSize;
321}
322
Stephen Hines37b74a32014-11-26 18:48:20 -0800323void HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700324 // define symbol _GLOBAL_OFFSET_TABLE_
325 if (m_pGOTSymbol != NULL) {
326 pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
Stephen Hines37b74a32014-11-26 18:48:20 -0800327 "_GLOBAL_OFFSET_TABLE_",
328 ResolveInfo::Object,
329 ResolveInfo::Define,
330 ResolveInfo::Local,
331 0x0, // size
332 0x0, // value
333 FragmentRef::Create(pFrag, 0x0),
334 ResolveInfo::Hidden);
335 } else {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700336 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
Stephen Hines37b74a32014-11-26 18:48:20 -0800337 "_GLOBAL_OFFSET_TABLE_",
338 ResolveInfo::Object,
339 ResolveInfo::Define,
340 ResolveInfo::Local,
341 0x0, // size
342 0x0, // value
343 FragmentRef::Create(pFrag, 0x0),
344 ResolveInfo::Hidden);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700345 }
346}
347
Stephen Hines37b74a32014-11-26 18:48:20 -0800348uint64_t HexagonLDBackend::emitGOTPLTSectionData(
349 MemoryRegion& pRegion,
350 const ELFFileFormat* FileFormat) const {
351 assert(m_pGOTPLT != NULL &&
352 "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700353 m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
354 m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
355
Stephen Hines87f34652014-02-14 18:00:16 -0800356 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700357
358 HexagonGOTEntry* got = 0;
359 unsigned int EntrySize = HexagonGOTEntry::EntrySize;
360 uint64_t RegionSize = 0;
361
Stephen Hines37b74a32014-11-26 18:48:20 -0800362 for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end();
363 it != ie;
364 ++it, ++buffer) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700365 got = &(llvm::cast<HexagonGOTEntry>((*it)));
366 *buffer = static_cast<uint32_t>(got->getValue());
367 RegionSize += EntrySize;
368 }
369
370 return RegionSize;
Stephen Hines6f757552013-03-04 19:51:03 -0800371}
372
Stephen Hines37b74a32014-11-26 18:48:20 -0800373unsigned int HexagonLDBackend::getTargetSectionOrder(
374 const LDSection& pSectHdr) const {
Stephen Hines6f757552013-03-04 19:51:03 -0800375 const ELFFileFormat* file_format = getOutputFormat();
376
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700377 if (LinkerConfig::Object != config().codeGenType()) {
Stephen Hines87f34652014-02-14 18:00:16 -0800378 if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700379 if (config().options().hasNow())
380 return SHO_RELRO;
381 return SHO_RELRO_LAST;
382 }
383
Stephen Hines87f34652014-02-14 18:00:16 -0800384 if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700385 if (config().options().hasNow())
386 return SHO_RELRO;
387 return SHO_NON_RELRO_FIRST;
388 }
389
Stephen Hines87f34652014-02-14 18:00:16 -0800390 if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700391 return SHO_PLT;
Stephen Hines6f757552013-03-04 19:51:03 -0800392 }
393
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700394 if (&pSectHdr == m_pstart)
395 return SHO_INIT;
396
397 if (&pSectHdr == m_psdata)
398 return SHO_SMALL_DATA;
Stephen Hines6f757552013-03-04 19:51:03 -0800399
400 return SHO_UNDEFINED;
401}
402
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700403void HexagonLDBackend::initTargetSections(Module& pModule,
Stephen Hines37b74a32014-11-26 18:48:20 -0800404 ObjectBuilder& pBuilder) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700405 if ((LinkerConfig::Object != config().codeGenType()) &&
406 (!config().isCodeStatic())) {
Stephen Hines6f757552013-03-04 19:51:03 -0800407 ELFFileFormat* file_format = getOutputFormat();
408 // initialize .got
409 LDSection& got = file_format->getGOT();
410 m_pGOT = new HexagonGOT(got);
411
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700412 // initialize .got.plt
413 LDSection& gotplt = file_format->getGOTPLT();
414 m_pGOTPLT = new HexagonGOTPLT(gotplt);
415
Stephen Hines6f757552013-03-04 19:51:03 -0800416 // initialize .plt
417 LDSection& plt = file_format->getPLT();
Stephen Hines37b74a32014-11-26 18:48:20 -0800418 m_pPLT = new HexagonPLT(plt, *m_pGOTPLT, config());
Stephen Hines6f757552013-03-04 19:51:03 -0800419
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700420 // initialize .rela.plt
421 LDSection& relaplt = file_format->getRelaPlt();
422 relaplt.setLink(&plt);
423 m_pRelaPLT = new OutputRelocSection(pModule, relaplt);
Stephen Hines6f757552013-03-04 19:51:03 -0800424
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700425 // initialize .rela.dyn
426 LDSection& reladyn = file_format->getRelaDyn();
427 m_pRelaDyn = new OutputRelocSection(pModule, reladyn);
Stephen Hines6f757552013-03-04 19:51:03 -0800428 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700429 m_psdata = pBuilder.CreateSection(".sdata",
430 LDFileFormat::Target,
431 llvm::ELF::SHT_PROGBITS,
432 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
Stephen Hines37b74a32014-11-26 18:48:20 -0800433 4 * 1024);
434 m_pscommon_1 =
435 pBuilder.CreateSection(".scommon.1",
436 LDFileFormat::Target,
437 llvm::ELF::SHT_PROGBITS,
438 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
439 1);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700440 IRBuilder::CreateSectionData(*m_pscommon_1);
441
Stephen Hines37b74a32014-11-26 18:48:20 -0800442 m_pscommon_2 =
443 pBuilder.CreateSection(".scommon.2",
444 LDFileFormat::Target,
445 llvm::ELF::SHT_PROGBITS,
446 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
447 2);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700448 IRBuilder::CreateSectionData(*m_pscommon_2);
449
Stephen Hines37b74a32014-11-26 18:48:20 -0800450 m_pscommon_4 =
451 pBuilder.CreateSection(".scommon.4",
452 LDFileFormat::Target,
453 llvm::ELF::SHT_PROGBITS,
454 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
455 4);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700456 IRBuilder::CreateSectionData(*m_pscommon_4);
457
Stephen Hines37b74a32014-11-26 18:48:20 -0800458 m_pscommon_8 =
459 pBuilder.CreateSection(".scommon.8",
460 LDFileFormat::Target,
461 llvm::ELF::SHT_PROGBITS,
462 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
463 8);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700464 IRBuilder::CreateSectionData(*m_pscommon_8);
465
466 m_pstart = pBuilder.CreateSection(".start",
467 LDFileFormat::Target,
468 llvm::ELF::SHT_PROGBITS,
469 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
470 8);
471 IRBuilder::CreateSectionData(*m_pstart);
Stephen Hines6f757552013-03-04 19:51:03 -0800472}
473
Stephen Hines37b74a32014-11-26 18:48:20 -0800474void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700475 if (config().codeGenType() == LinkerConfig::Object)
476 return;
477
478 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
479 // same name in input
480 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
Stephen Hines37b74a32014-11-26 18:48:20 -0800481 "_GLOBAL_OFFSET_TABLE_",
482 ResolveInfo::Object,
483 ResolveInfo::Define,
484 ResolveInfo::Local,
485 0x0, // size
486 0x0, // value
487 FragmentRef::Null(),
488 ResolveInfo::Hidden);
489
490 m_psdabase = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
491 "_SDA_BASE_",
492 ResolveInfo::Object,
493 ResolveInfo::Define,
494 ResolveInfo::Absolute,
495 0x0, // size
496 0x0, // value
497 FragmentRef::Null(),
498 ResolveInfo::Hidden);
499
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700500 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
Stephen Hines37b74a32014-11-26 18:48:20 -0800501 "__sbss_start",
502 ResolveInfo::Object,
503 ResolveInfo::Define,
504 ResolveInfo::Absolute,
505 0x0, // size
506 0x0, // value
507 FragmentRef::Null(),
508 ResolveInfo::Hidden);
509
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700510 pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
Stephen Hines37b74a32014-11-26 18:48:20 -0800511 "__sbss_end",
512 ResolveInfo::Object,
513 ResolveInfo::Define,
514 ResolveInfo::Absolute,
515 0x0, // size
516 0x0, // value
517 FragmentRef::Null(),
518 ResolveInfo::Hidden);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700519}
520
Stephen Hines37b74a32014-11-26 18:48:20 -0800521bool HexagonLDBackend::initTargetStubs() {
522 if (getStubFactory() != NULL) {
523 getStubFactory()->addPrototype(
524 new HexagonAbsoluteStub(config().isCodeIndep()));
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700525 return true;
Stephen Hines6f757552013-03-04 19:51:03 -0800526 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700527 return false;
528}
529
Stephen Hines37b74a32014-11-26 18:48:20 -0800530bool HexagonLDBackend::initBRIslandFactory() {
531 if (m_pBRIslandFactory == NULL) {
532 m_pBRIslandFactory =
533 new BranchIslandFactory(maxFwdBranchOffset(), maxBwdBranchOffset(), 0);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700534 }
535 return true;
536}
537
Stephen Hines37b74a32014-11-26 18:48:20 -0800538bool HexagonLDBackend::initStubFactory() {
539 if (m_pStubFactory == NULL) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700540 m_pStubFactory = new StubFactory();
541 }
542 return true;
543}
544
Stephen Hines37b74a32014-11-26 18:48:20 -0800545bool HexagonLDBackend::doRelax(Module& pModule,
546 IRBuilder& pBuilder,
547 bool& pFinished) {
548 assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700549 bool isRelaxed = false;
550 ELFFileFormat* file_format = getOutputFormat();
551 // check branch relocs and create the related stubs if needed
552 Module::obj_iterator input, inEnd = pModule.obj_end();
553 for (input = pModule.obj_begin(); input != inEnd; ++input) {
554 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
555 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
556 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
557 continue;
558 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
559 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
560 switch (reloc->type()) {
561 case llvm::ELF::R_HEX_B22_PCREL:
562 case llvm::ELF::R_HEX_B15_PCREL:
563 case llvm::ELF::R_HEX_B7_PCREL:
564 case llvm::ELF::R_HEX_B13_PCREL:
565 case llvm::ELF::R_HEX_B9_PCREL: {
566 Relocation* relocation = llvm::cast<Relocation>(reloc);
567 uint64_t sym_value = 0x0;
568 LDSymbol* symbol = relocation->symInfo()->outSymbol();
569 if (symbol->hasFragRef()) {
570 uint64_t value = symbol->fragRef()->getOutputOffset();
571 uint64_t addr =
Stephen Hines37b74a32014-11-26 18:48:20 -0800572 symbol->fragRef()->frag()->getParent()->getSection().addr();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700573 sym_value = addr + value;
574 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800575 Stub* stub = getStubFactory()->create(*relocation, // relocation
576 sym_value, // symbol value
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700577 pBuilder,
578 *getBRIslandFactory());
Stephen Hines37b74a32014-11-26 18:48:20 -0800579 if (stub != NULL) {
580 assert(stub->symInfo() != NULL);
Stephen Hinescfcb2242016-03-08 00:18:09 -0800581 // reset the branch target of the reloc to this stub instead
582 relocation->setSymInfo(stub->symInfo());
583
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700584 // increase the size of .symtab and .strtab
585 LDSection& symtab = file_format->getSymTab();
586 LDSection& strtab = file_format->getStrTab();
587 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
588 strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
589 isRelaxed = true;
590 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800591 } break;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700592
593 default:
594 break;
595 }
596 }
597 }
598 }
599
600 // find the first fragment w/ invalid offset due to stub insertion
Stephen Hinescfcb2242016-03-08 00:18:09 -0800601 std::vector<Fragment*> invalid_frags;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700602 pFinished = true;
603 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
Stephen Hines37b74a32014-11-26 18:48:20 -0800604 island_end = getBRIslandFactory()->end();
605 island != island_end;
606 ++island) {
Stephen Hinescfcb2242016-03-08 00:18:09 -0800607 if ((*island).size() > stubGroupSize()) {
608 error(diag::err_no_space_to_place_stubs) << stubGroupSize();
609 return false;
610 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700611
Stephen Hinescfcb2242016-03-08 00:18:09 -0800612 if ((*island).numOfStubs() == 0) {
613 continue;
614 }
615
616 Fragment* exit = &*(*island).end();
617 if (exit == (*island).begin()->getParent()->end()) {
618 continue;
619 }
620
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700621 if (((*island).offset() + (*island).size()) > exit->getOffset()) {
Stephen Hinescfcb2242016-03-08 00:18:09 -0800622 if (invalid_frags.empty() ||
623 (invalid_frags.back()->getParent() != (*island).getParent())) {
624 invalid_frags.push_back(exit);
625 pFinished = false;
626 }
627 continue;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700628 }
629 }
630
631 // reset the offset of invalid fragments
Stephen Hinescfcb2242016-03-08 00:18:09 -0800632 for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie;
633 ++it) {
634 Fragment* invalid = *it;
635 while (invalid != NULL) {
636 invalid->setOffset(invalid->getPrevNode()->getOffset() +
637 invalid->getPrevNode()->size());
638 invalid = invalid->getNextNode();
639 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700640 }
641
Stephen Hinescfcb2242016-03-08 00:18:09 -0800642 // reset the size of section that has stubs inserted.
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700643 if (isRelaxed) {
Stephen Hinescfcb2242016-03-08 00:18:09 -0800644 SectionData* prev = NULL;
645 for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
646 island_end = getBRIslandFactory()->end();
647 island != island_end;
648 ++island) {
649 SectionData* sd = (*island).begin()->getParent();
650 if ((*island).numOfStubs() != 0) {
651 if (sd != prev) {
652 sd->getSection().setSize(sd->back().getOffset() + sd->back().size());
653 }
654 }
655 prev = sd;
656 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700657 }
658 return isRelaxed;
Stephen Hines6f757552013-03-04 19:51:03 -0800659}
660
661/// finalizeSymbol - finalize the symbol value
Stephen Hines37b74a32014-11-26 18:48:20 -0800662bool HexagonLDBackend::finalizeTargetSymbols() {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700663 if (config().codeGenType() == LinkerConfig::Object)
664 return true;
665 if (m_psdabase)
666 m_psdabase->setValue(m_psdata->addr());
667
Stephen Hines37b74a32014-11-26 18:48:20 -0800668 ELFSegmentFactory::const_iterator edata = elfSegmentTable().find(
669 llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
Stephen Hines87f34652014-02-14 18:00:16 -0800670 if (elfSegmentTable().end() != edata) {
Stephen Hines37b74a32014-11-26 18:48:20 -0800671 if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) {
Stephen Hines87f34652014-02-14 18:00:16 -0800672 f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700673 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800674 if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) {
Stephen Hines87f34652014-02-14 18:00:16 -0800675 f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700676 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800677 if (f_pBSSStart != NULL &&
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700678 ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
Stephen Hines87f34652014-02-14 18:00:16 -0800679 f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700680 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800681 if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) {
682 f_pEnd->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700683 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800684 if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) {
685 f_p_End->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700686 }
687 }
688 return true;
689}
690
691/// merge Input Sections
Stephen Hines87f34652014-02-14 18:00:16 -0800692bool HexagonLDBackend::mergeSection(Module& pModule,
693 const Input& pInputFile,
Stephen Hines37b74a32014-11-26 18:48:20 -0800694 LDSection& pInputSection) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700695 if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) ||
696 (pInputSection.kind() == LDFileFormat::LinkOnce) ||
697 (pInputSection.kind() == LDFileFormat::Target)) {
Stephen Hines37b74a32014-11-26 18:48:20 -0800698 SectionData* sd = NULL;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700699 if (!m_psdata->hasSectionData()) {
700 sd = IRBuilder::CreateSectionData(*m_psdata);
701 m_psdata->setSectionData(sd);
702 }
703 sd = m_psdata->getSectionData();
704 MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd);
Stephen Hines37b74a32014-11-26 18:48:20 -0800705 } else {
Stephen Hines533eae22014-05-28 17:43:38 -0700706 ObjectBuilder builder(pModule);
Stephen Hines87f34652014-02-14 18:00:16 -0800707 builder.MergeSection(pInputFile, pInputSection);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700708 }
709 return true;
710}
711
712bool HexagonLDBackend::SetSDataSection() {
Stephen Hines37b74a32014-11-26 18:48:20 -0800713 SectionData* pTo = (m_psdata->getSectionData());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700714
715 if (pTo) {
716 MoveCommonData(*m_pscommon_1->getSectionData(), *pTo);
717 MoveCommonData(*m_pscommon_2->getSectionData(), *pTo);
718 MoveCommonData(*m_pscommon_4->getSectionData(), *pTo);
719 MoveCommonData(*m_pscommon_8->getSectionData(), *pTo);
720
721 SectionData::FragmentListType& to_list = pTo->getFragmentList();
722 SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end();
723 uint32_t offset = 0;
724 for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) {
725 fragTo->setOffset(offset);
726 offset += fragTo->size();
727 }
728
729 // set up pTo's header
730 pTo->getSection().setSize(offset);
731
732 SectionData::FragmentListType& newlist = pTo->getFragmentList();
733
734 for (fragTo = newlist.begin(), fragToEnd = newlist.end();
Stephen Hines37b74a32014-11-26 18:48:20 -0800735 fragTo != fragToEnd;
736 ++fragTo) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700737 fragTo->setParent(pTo);
738 }
739 }
740
741 return true;
742}
743
744/// allocateCommonSymbols - allocate common symbols in the corresponding
745/// sections. This is called at pre-layout stage.
Stephen Hines37b74a32014-11-26 18:48:20 -0800746bool HexagonLDBackend::allocateCommonSymbols(Module& pModule) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700747 SymbolCategory& symbol_list = pModule.getSymbolTable();
748
749 if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) {
750 SetSDataSection();
751 return true;
752 }
753
Stephen Hinescfcb2242016-03-08 00:18:09 -0800754 int8_t maxGPSize = config().targets().getGPSize();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700755
756 SymbolCategory::iterator com_sym, com_end;
757
758 // get corresponding BSS LDSection
759 ELFFileFormat* file_format = getOutputFormat();
760 LDSection& bss_sect = file_format->getBSS();
761 LDSection& tbss_sect = file_format->getTBSS();
762
763 // get or create corresponding BSS SectionData
764 SectionData* bss_sect_data = NULL;
765 if (bss_sect.hasSectionData())
766 bss_sect_data = bss_sect.getSectionData();
767 else
768 bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
769
770 SectionData* tbss_sect_data = NULL;
771 if (tbss_sect.hasSectionData())
772 tbss_sect_data = tbss_sect.getSectionData();
773 else
774 tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
775
776 // remember original BSS size
Stephen Hines37b74a32014-11-26 18:48:20 -0800777 uint64_t bss_offset = bss_sect.size();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700778 uint64_t tbss_offset = tbss_sect.size();
779
780 // allocate all local common symbols
781 com_end = symbol_list.localEnd();
782
783 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
784 if (ResolveInfo::Common == (*com_sym)->desc()) {
785 // We have to reset the description of the symbol here. When doing
786 // incremental linking, the output relocatable object may have common
787 // symbols. Therefore, we can not treat common symbols as normal symbols
788 // when emitting the regular name pools. We must change the symbols'
789 // description here.
790 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
791 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700792
Stephen Hines37b74a32014-11-26 18:48:20 -0800793 switch ((*com_sym)->size()) {
794 case 1:
795 if (maxGPSize <= 0)
796 break;
797 ObjectBuilder::AppendFragment(
798 *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value());
799 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
800 continue;
801 case 2:
802 if (maxGPSize <= 1)
803 break;
804 ObjectBuilder::AppendFragment(
805 *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value());
806 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
807 continue;
808 case 4:
809 if (maxGPSize <= 3)
810 break;
811 ObjectBuilder::AppendFragment(
812 *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value());
813 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
814 continue;
815 case 8:
816 if (maxGPSize <= 7)
817 break;
818 ObjectBuilder::AppendFragment(
819 *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value());
820 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
821 continue;
822 default:
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700823 break;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700824 }
825
826 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
827 // allocate TLS common symbol in tbss section
Stephen Hines37b74a32014-11-26 18:48:20 -0800828 tbss_offset += ObjectBuilder::AppendFragment(
829 *frag, *tbss_sect_data, (*com_sym)->value());
Stephen Hines87f34652014-02-14 18:00:16 -0800830 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
Stephen Hines37b74a32014-11-26 18:48:20 -0800831 } else {
832 // FIXME: how to identify small and large common symbols?
833 bss_offset += ObjectBuilder::AppendFragment(
834 *frag, *bss_sect_data, (*com_sym)->value());
Stephen Hines87f34652014-02-14 18:00:16 -0800835 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700836 }
837 }
838 }
839
840 // allocate all global common symbols
841 com_end = symbol_list.commonEnd();
842 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
843 // We have to reset the description of the symbol here. When doing
844 // incremental linking, the output relocatable object may have common
845 // symbols. Therefore, we can not treat common symbols as normal symbols
846 // when emitting the regular name pools. We must change the symbols'
847 // description here.
848 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
849 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700850
Stephen Hines37b74a32014-11-26 18:48:20 -0800851 switch ((*com_sym)->size()) {
852 case 1:
853 if (maxGPSize <= 0)
854 break;
855 ObjectBuilder::AppendFragment(
856 *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value());
857 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
858 continue;
859 case 2:
860 if (maxGPSize <= 1)
861 break;
862 ObjectBuilder::AppendFragment(
863 *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value());
864 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
865 continue;
866 case 4:
867 if (maxGPSize <= 3)
868 break;
869 ObjectBuilder::AppendFragment(
870 *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value());
871 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
872 continue;
873 case 8:
874 if (maxGPSize <= 7)
875 break;
876 ObjectBuilder::AppendFragment(
877 *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value());
878 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
879 continue;
880 default:
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700881 break;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700882 }
883
884 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
885 // allocate TLS common symbol in tbss section
Stephen Hines37b74a32014-11-26 18:48:20 -0800886 tbss_offset += ObjectBuilder::AppendFragment(
887 *frag, *tbss_sect_data, (*com_sym)->value());
Stephen Hines87f34652014-02-14 18:00:16 -0800888 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
Stephen Hines37b74a32014-11-26 18:48:20 -0800889 } else {
890 // FIXME: how to identify small and large common symbols?
891 bss_offset += ObjectBuilder::AppendFragment(
892 *frag, *bss_sect_data, (*com_sym)->value());
Stephen Hines87f34652014-02-14 18:00:16 -0800893 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700894 }
895 }
896
897 bss_sect.setSize(bss_offset);
898 tbss_sect.setSize(tbss_offset);
899 symbol_list.changeCommonsToGlobal();
900 SetSDataSection();
901 return true;
902}
903
Stephen Hines37b74a32014-11-26 18:48:20 -0800904bool HexagonLDBackend::MoveCommonData(SectionData& pFrom, SectionData& pTo) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700905 SectionData::FragmentListType& to_list = pTo.getFragmentList();
906 SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();
907
908 uint32_t pFromFlag = pFrom.getSection().align();
909 bool found = false;
910
911 SectionData::FragmentListType::iterator fragInsert;
912
913 for (frag = to_list.begin(); frag != fragEnd; ++frag) {
914 if (frag->getKind() == mcld::Fragment::Alignment) {
915 fragInsert = frag;
916 continue;
917 }
918 if ((frag->getKind() != mcld::Fragment::Region) &&
919 (frag->getKind() != mcld::Fragment::Fillment)) {
920 continue;
921 }
922 uint32_t flag = frag->getParent()->getSection().align();
923 if (pFromFlag < flag) {
924 found = true;
925 break;
926 }
927 }
928 AlignFragment* align = NULL;
929 if (pFrom.getSection().align() > 1) {
930 // if the align constraint is larger than 1, append an alignment
Stephen Hines37b74a32014-11-26 18:48:20 -0800931 unsigned int alignment = pFrom.getSection().align();
932 align = new AlignFragment(/*alignment*/alignment,
933 /*the filled value*/0x0,
934 /*the size of filled value*/1u,
935 /*max bytes to emit*/alignment - 1);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700936 pFrom.getFragmentList().push_front(align);
937 }
938 if (found)
939 to_list.splice(fragInsert, pFrom.getFragmentList());
940 else
941 to_list.splice(frag, pFrom.getFragmentList());
942
943 return true;
944}
945
Stephen Hines37b74a32014-11-26 18:48:20 -0800946bool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700947 Fragment* frag = NULL;
948 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
949 uint32_t size = pSD.getSection().size();
950
951 if (pSD.getSection().type() == llvm::ELF::SHT_NOBITS) {
952 frag = new FillFragment(0x0, 1, size);
Stephen Hines37b74a32014-11-26 18:48:20 -0800953 } else {
Stephen Hines87f34652014-02-14 18:00:16 -0800954 llvm::StringRef region = pInput.memArea()->request(offset, size);
955 if (region.size() == 0) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700956 // If the input section's size is zero, we got a NULL region.
957 // use a virtual fill fragment
958 frag = new FillFragment(0x0, 0, 0);
Stephen Hines37b74a32014-11-26 18:48:20 -0800959 } else {
Stephen Hines87f34652014-02-14 18:00:16 -0800960 frag = new RegionFragment(region);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700961 }
962 }
963
964 ObjectBuilder::AppendFragment(*frag, pSD);
965 return true;
966}
967
968/// MoveSectionData - move the fragments of pTO section data to pTo
Stephen Hines37b74a32014-11-26 18:48:20 -0800969bool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom,
970 SectionData& pTo) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700971 assert(&pFrom != &pTo && "Cannot move section data to itself!");
972 SectionData::FragmentListType& to_list = pTo.getFragmentList();
973 SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();
974
975 uint32_t pFromFlag = pFrom.getSection().align();
976 bool found = false;
977
978 SectionData::FragmentListType::iterator fragInsert;
979
980 for (frag = to_list.begin(); frag != fragEnd; ++frag) {
981 if (frag->getKind() == mcld::Fragment::Alignment) {
982 fragInsert = frag;
983 continue;
984 }
985 if ((frag->getKind() != mcld::Fragment::Region) &&
986 (frag->getKind() != mcld::Fragment::Fillment)) {
987 continue;
988 }
989 uint32_t flag = frag->getParent()->getSection().align();
990 if (pFromFlag < flag) {
991 found = true;
992 break;
993 }
994 }
995 AlignFragment* align = NULL;
996 if (pFrom.getSection().align() > 1) {
997 // if the align constraint is larger than 1, append an alignment
Stephen Hines37b74a32014-11-26 18:48:20 -0800998 unsigned int alignment = pFrom.getSection().align();
999 align = new AlignFragment(/*alignment*/alignment,
1000 /*the filled value*/0x0,
1001 /*the size of filled value*/1u,
1002 /*max bytes to emit*/alignment - 1);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -07001003 pFrom.getFragmentList().push_front(align);
1004 }
1005 if (found)
1006 to_list.splice(fragInsert, pFrom.getFragmentList());
1007 else
1008 to_list.splice(frag, pFrom.getFragmentList());
1009
1010 uint32_t offset = 0;
1011 for (frag = to_list.begin(); frag != fragEnd; ++frag) {
1012 frag->setOffset(offset);
1013 offset += frag->size();
1014 }
1015
1016 // set up pTo's header
1017 pTo.getSection().setSize(offset);
1018
1019 if (pFrom.getSection().align() > pTo.getSection().align())
1020 pTo.getSection().setAlign(pFrom.getSection().align());
1021
1022 if (pFrom.getSection().flag() > pTo.getSection().flag())
1023 pTo.getSection().setFlag(pFrom.getSection().flag());
Stephen Hines6f757552013-03-04 19:51:03 -08001024 return true;
1025}
1026
1027/// doCreateProgramHdrs - backend can implement this function to create the
1028/// target-dependent segments
Stephen Hines37b74a32014-11-26 18:48:20 -08001029void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) {
Stephen Hines6f757552013-03-04 19:51:03 -08001030 // TODO
1031}
1032
Stephen Hines6f757552013-03-04 19:51:03 -08001033//===----------------------------------------------------------------------===//
Stephen Hinesf7ac0f12013-05-03 19:09:24 -07001034/// createHexagonLDBackend - the help funtion to create corresponding
Stephen Hines6f757552013-03-04 19:51:03 -08001035/// HexagonLDBackend
Stephen Hines37b74a32014-11-26 18:48:20 -08001036TargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) {
Stephen Hines6f757552013-03-04 19:51:03 -08001037 if (pConfig.targets().triple().isOSDarwin()) {
1038 assert(0 && "MachO linker is not supported yet");
1039 /**
1040 return new HexagonMachOLDBackend(createHexagonMachOArchiveReader,
1041 createHexagonMachOObjectReader,
1042 createHexagonMachOObjectWriter);
1043 **/
1044 }
1045 if (pConfig.targets().triple().isOSWindows()) {
1046 assert(0 && "COFF linker is not supported yet");
1047 /**
1048 return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader,
1049 createHexagonCOFFObjectReader,
1050 createHexagonCOFFObjectWriter);
1051 **/
1052 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -07001053 return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets()));
Stephen Hines6f757552013-03-04 19:51:03 -08001054}
1055
Stephen Hines37b74a32014-11-26 18:48:20 -08001056} // namespace mcld
Stephen Hines6f757552013-03-04 19:51:03 -08001057
1058//===----------------------------------------------------------------------===//
1059// Force static initialization.
1060//===----------------------------------------------------------------------===//
1061extern "C" void MCLDInitializeHexagonLDBackend() {
1062 // Register the linker backend
Stephen Hines37b74a32014-11-26 18:48:20 -08001063 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheHexagonTarget,
1064 mcld::createHexagonLDBackend);
Stephen Hines6f757552013-03-04 19:51:03 -08001065}