• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- 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"
14 #include "HexagonAbsoluteStub.h"
15 
16 #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 
33 #include <llvm/ADT/Triple.h>
34 #include <llvm/Support/Casting.h>
35 
36 #include <cstring>
37 #include <vector>
38 
39 namespace mcld {
40 
41 //===----------------------------------------------------------------------===//
42 // HexagonLDBackend
43 //===----------------------------------------------------------------------===//
HexagonLDBackend(const LinkerConfig & pConfig,HexagonGNUInfo * pInfo)44 HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig,
45                                    HexagonGNUInfo* pInfo)
46     : 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) {
56 }
57 
~HexagonLDBackend()58 HexagonLDBackend::~HexagonLDBackend() {
59   delete m_pRelocator;
60   delete m_pGOT;
61   delete m_pPLT;
62   delete m_pRelaDyn;
63   delete m_pRelaPLT;
64   delete m_pDynamic;
65 }
66 
initRelocator()67 bool HexagonLDBackend::initRelocator() {
68   if (m_pRelocator == NULL) {
69     m_pRelocator = new HexagonRelocator(*this, config());
70   }
71   return true;
72 }
73 
getRelocator() const74 const Relocator* HexagonLDBackend::getRelocator() const {
75   assert(m_pRelocator != NULL);
76   return m_pRelocator;
77 }
78 
getRelocator()79 Relocator* HexagonLDBackend::getRelocator() {
80   assert(m_pRelocator != NULL);
81   return m_pRelocator;
82 }
83 
doPreLayout(IRBuilder & pBuilder)84 void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) {
85   // initialize .dynamic data
86   if (!config().isCodeStatic() && m_pDynamic == NULL)
87     m_pDynamic = new HexagonELFDynamic(*this, config());
88 
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()) {
101       assert(
102           !config().isCodeStatic() &&
103           "static linkage should not result in a dynamic relocation section");
104       setRelaDynSize();
105     }
106     // set .rela.plt size
107     if (!m_pRelaPLT->empty()) {
108       assert(
109           !config().isCodeStatic() &&
110           "static linkage should not result in a dynamic relocation section");
111       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();
117 }
118 
doPostLayout(Module & pModule,IRBuilder & pBuilder)119 void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) {
120 }
121 
122 /// dynamic - the dynamic section of the target machine.
123 /// Use co-variant return type to return its own dynamic section.
dynamic()124 HexagonELFDynamic& HexagonLDBackend::dynamic() {
125   assert(m_pDynamic != NULL);
126   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.
dynamic() const131 const HexagonELFDynamic& HexagonLDBackend::dynamic() const {
132   assert(m_pDynamic != NULL);
133   return *m_pDynamic;
134 }
135 
emitSectionData(const LDSection & pSection,MemoryRegion & pRegion) const136 uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
137                                            MemoryRegion& pRegion) const {
138   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())) {
147     if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) {
148       unsigned char* buffer = pRegion.begin();
149 
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;
169     } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) {
170       RegionSize += emitGOTSectionData(pRegion);
171       return RegionSize;
172     } else if (FileFormat->hasGOTPLT() &&
173                (&pSection == &(FileFormat->getGOTPLT()))) {
174       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();
181   uint8_t* out_offset = pRegion.begin();
182   for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
183     size_t size = frag_iter->size();
184     switch (frag_iter->getKind()) {
185       case Fragment::Fillment: {
186         const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter);
187         if (fill_frag.getValueSize() == 0) {
188           // 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 =
196             llvm::cast<RegionFragment>(*frag_iter);
197         const char* start = region_frag.getRegion().begin();
198         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(
210                 "unsupported value size for align fragment emission yet.\n");
211             break;
212         }  // end switch
213         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;
222     }  // end switch
223     out_offset += size;
224   }  // end for
225 
226   return pRegion.size();
227 }
228 
getGOT()229 HexagonGOT& HexagonLDBackend::getGOT() {
230   assert(m_pGOT != NULL);
231   return *m_pGOT;
232 }
233 
getGOT() const234 const HexagonGOT& HexagonLDBackend::getGOT() const {
235   assert(m_pGOT != NULL);
236   return *m_pGOT;
237 }
238 
getPLT()239 HexagonPLT& HexagonLDBackend::getPLT() {
240   assert(m_pPLT != NULL && "PLT section not exist");
241   return *m_pPLT;
242 }
243 
getPLT() const244 const HexagonPLT& HexagonLDBackend::getPLT() const {
245   assert(m_pPLT != NULL && "PLT section not exist");
246   return *m_pPLT;
247 }
248 
getRelaDyn()249 OutputRelocSection& HexagonLDBackend::getRelaDyn() {
250   assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
251   return *m_pRelaDyn;
252 }
253 
getRelaDyn() const254 const OutputRelocSection& HexagonLDBackend::getRelaDyn() const {
255   assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
256   return *m_pRelaDyn;
257 }
258 
getRelaPLT()259 OutputRelocSection& HexagonLDBackend::getRelaPLT() {
260   assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
261   return *m_pRelaPLT;
262 }
263 
getRelaPLT() const264 const OutputRelocSection& HexagonLDBackend::getRelaPLT() const {
265   assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
266   return *m_pRelaPLT;
267 }
268 
getGOTPLT()269 HexagonGOTPLT& HexagonLDBackend::getGOTPLT() {
270   assert(m_pGOTPLT != NULL);
271   return *m_pGOTPLT;
272 }
273 
getGOTPLT() const274 const HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const {
275   assert(m_pGOTPLT != NULL);
276   return *m_pGOTPLT;
277 }
278 
setRelaDynSize()279 void HexagonLDBackend::setRelaDynSize() {
280   ELFFileFormat* file_format = getOutputFormat();
281   file_format->getRelaDyn().setSize(m_pRelaDyn->numOfRelocs() *
282                                     getRelaEntrySize());
283 }
284 
setRelaPLTSize()285 void HexagonLDBackend::setRelaPLTSize() {
286   ELFFileFormat* file_format = getOutputFormat();
287   file_format->getRelaPlt().setSize(m_pRelaPLT->numOfRelocs() *
288                                     getRelaEntrySize());
289 }
290 
setGOTSectionSize(IRBuilder & pBuilder)291 void HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) {
292   // set .got.plt size
293   if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() ||
294       m_pGOTSymbol != NULL) {
295     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 
emitGOTSectionData(MemoryRegion & pRegion) const304 uint64_t HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const {
305   assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
306 
307   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
308 
309   HexagonGOTEntry* got = 0;
310   unsigned int EntrySize = HexagonGOTEntry::EntrySize;
311   uint64_t RegionSize = 0;
312 
313   for (HexagonGOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie;
314        ++it, ++buffer) {
315     got = &(llvm::cast<HexagonGOTEntry>((*it)));
316     *buffer = static_cast<uint32_t>(got->getValue());
317     RegionSize += EntrySize;
318   }
319 
320   return RegionSize;
321 }
322 
defineGOTSymbol(IRBuilder & pBuilder,Fragment & pFrag)323 void HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) {
324   // define symbol _GLOBAL_OFFSET_TABLE_
325   if (m_pGOTSymbol != NULL) {
326     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
327         "_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 {
336     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
337         "_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);
345   }
346 }
347 
emitGOTPLTSectionData(MemoryRegion & pRegion,const ELFFileFormat * FileFormat) const348 uint64_t HexagonLDBackend::emitGOTPLTSectionData(
349     MemoryRegion& pRegion,
350     const ELFFileFormat* FileFormat) const {
351   assert(m_pGOTPLT != NULL &&
352          "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
353   m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
354   m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
355 
356   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
357 
358   HexagonGOTEntry* got = 0;
359   unsigned int EntrySize = HexagonGOTEntry::EntrySize;
360   uint64_t RegionSize = 0;
361 
362   for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end();
363        it != ie;
364        ++it, ++buffer) {
365     got = &(llvm::cast<HexagonGOTEntry>((*it)));
366     *buffer = static_cast<uint32_t>(got->getValue());
367     RegionSize += EntrySize;
368   }
369 
370   return RegionSize;
371 }
372 
getTargetSectionOrder(const LDSection & pSectHdr) const373 unsigned int HexagonLDBackend::getTargetSectionOrder(
374     const LDSection& pSectHdr) const {
375   const ELFFileFormat* file_format = getOutputFormat();
376 
377   if (LinkerConfig::Object != config().codeGenType()) {
378     if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) {
379       if (config().options().hasNow())
380         return SHO_RELRO;
381       return SHO_RELRO_LAST;
382     }
383 
384     if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) {
385       if (config().options().hasNow())
386         return SHO_RELRO;
387       return SHO_NON_RELRO_FIRST;
388     }
389 
390     if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
391       return SHO_PLT;
392   }
393 
394   if (&pSectHdr == m_pstart)
395     return SHO_INIT;
396 
397   if (&pSectHdr == m_psdata)
398     return SHO_SMALL_DATA;
399 
400   return SHO_UNDEFINED;
401 }
402 
initTargetSections(Module & pModule,ObjectBuilder & pBuilder)403 void HexagonLDBackend::initTargetSections(Module& pModule,
404                                           ObjectBuilder& pBuilder) {
405   if ((LinkerConfig::Object != config().codeGenType()) &&
406       (!config().isCodeStatic())) {
407     ELFFileFormat* file_format = getOutputFormat();
408     // initialize .got
409     LDSection& got = file_format->getGOT();
410     m_pGOT = new HexagonGOT(got);
411 
412     // initialize .got.plt
413     LDSection& gotplt = file_format->getGOTPLT();
414     m_pGOTPLT = new HexagonGOTPLT(gotplt);
415 
416     // initialize .plt
417     LDSection& plt = file_format->getPLT();
418     m_pPLT = new HexagonPLT(plt, *m_pGOTPLT, config());
419 
420     // initialize .rela.plt
421     LDSection& relaplt = file_format->getRelaPlt();
422     relaplt.setLink(&plt);
423     m_pRelaPLT = new OutputRelocSection(pModule, relaplt);
424 
425     // initialize .rela.dyn
426     LDSection& reladyn = file_format->getRelaDyn();
427     m_pRelaDyn = new OutputRelocSection(pModule, reladyn);
428   }
429   m_psdata = pBuilder.CreateSection(".sdata",
430                                     LDFileFormat::Target,
431                                     llvm::ELF::SHT_PROGBITS,
432                                     llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
433                                     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);
440   IRBuilder::CreateSectionData(*m_pscommon_1);
441 
442   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);
448   IRBuilder::CreateSectionData(*m_pscommon_2);
449 
450   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);
456   IRBuilder::CreateSectionData(*m_pscommon_4);
457 
458   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);
464   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);
472 }
473 
initTargetSymbols(IRBuilder & pBuilder,Module & pModule)474 void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {
475   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>(
481       "_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 
500   pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
501       "__sbss_start",
502       ResolveInfo::Object,
503       ResolveInfo::Define,
504       ResolveInfo::Absolute,
505       0x0,  // size
506       0x0,  // value
507       FragmentRef::Null(),
508       ResolveInfo::Hidden);
509 
510   pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
511       "__sbss_end",
512       ResolveInfo::Object,
513       ResolveInfo::Define,
514       ResolveInfo::Absolute,
515       0x0,  // size
516       0x0,  // value
517       FragmentRef::Null(),
518       ResolveInfo::Hidden);
519 }
520 
initTargetStubs()521 bool HexagonLDBackend::initTargetStubs() {
522   if (getStubFactory() != NULL) {
523     getStubFactory()->addPrototype(
524         new HexagonAbsoluteStub(config().isCodeIndep()));
525     return true;
526   }
527   return false;
528 }
529 
initBRIslandFactory()530 bool HexagonLDBackend::initBRIslandFactory() {
531   if (m_pBRIslandFactory == NULL) {
532     m_pBRIslandFactory =
533         new BranchIslandFactory(maxFwdBranchOffset(), maxBwdBranchOffset(), 0);
534   }
535   return true;
536 }
537 
initStubFactory()538 bool HexagonLDBackend::initStubFactory() {
539   if (m_pStubFactory == NULL) {
540     m_pStubFactory = new StubFactory();
541   }
542   return true;
543 }
544 
doRelax(Module & pModule,IRBuilder & pBuilder,bool & pFinished)545 bool HexagonLDBackend::doRelax(Module& pModule,
546                                IRBuilder& pBuilder,
547                                bool& pFinished) {
548   assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
549   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 =
572                   symbol->fragRef()->frag()->getParent()->getSection().addr();
573               sym_value = addr + value;
574             }
575             Stub* stub = getStubFactory()->create(*relocation,  // relocation
576                                                   sym_value,  // symbol value
577                                                   pBuilder,
578                                                   *getBRIslandFactory());
579             if (stub != NULL) {
580               assert(stub->symInfo() != NULL);
581               // reset the branch target of the reloc to this stub instead
582               relocation->setSymInfo(stub->symInfo());
583 
584               // 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             }
591           } break;
592 
593           default:
594             break;
595         }
596       }
597     }
598   }
599 
600   // find the first fragment w/ invalid offset due to stub insertion
601   std::vector<Fragment*> invalid_frags;
602   pFinished = true;
603   for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
604                                      island_end = getBRIslandFactory()->end();
605        island != island_end;
606        ++island) {
607     if ((*island).size() > stubGroupSize()) {
608       error(diag::err_no_space_to_place_stubs) << stubGroupSize();
609       return false;
610     }
611 
612     if ((*island).numOfStubs() == 0) {
613       continue;
614     }
615 
616     Fragment* exit = &*(*island).end();
617     if (exit == (*island).begin()->getParent()->end()) {
618       continue;
619     }
620 
621     if (((*island).offset() + (*island).size()) > exit->getOffset()) {
622       if (invalid_frags.empty() ||
623           (invalid_frags.back()->getParent() != (*island).getParent())) {
624         invalid_frags.push_back(exit);
625         pFinished = false;
626       }
627       continue;
628     }
629   }
630 
631   // reset the offset of invalid fragments
632   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     }
640   }
641 
642   // reset the size of section that has stubs inserted.
643   if (isRelaxed) {
644     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     }
657   }
658   return isRelaxed;
659 }
660 
661 /// finalizeSymbol - finalize the symbol value
finalizeTargetSymbols()662 bool HexagonLDBackend::finalizeTargetSymbols() {
663   if (config().codeGenType() == LinkerConfig::Object)
664     return true;
665   if (m_psdabase)
666     m_psdabase->setValue(m_psdata->addr());
667 
668   ELFSegmentFactory::const_iterator edata = elfSegmentTable().find(
669       llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
670   if (elfSegmentTable().end() != edata) {
671     if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) {
672       f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz());
673     }
674     if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) {
675       f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz());
676     }
677     if (f_pBSSStart != NULL &&
678         ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
679       f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz());
680     }
681     if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) {
682       f_pEnd->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
683     }
684     if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) {
685       f_p_End->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
686     }
687   }
688   return true;
689 }
690 
691 /// merge Input Sections
mergeSection(Module & pModule,const Input & pInputFile,LDSection & pInputSection)692 bool HexagonLDBackend::mergeSection(Module& pModule,
693                                     const Input& pInputFile,
694                                     LDSection& pInputSection) {
695   if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) ||
696       (pInputSection.kind() == LDFileFormat::LinkOnce) ||
697       (pInputSection.kind() == LDFileFormat::Target)) {
698     SectionData* sd = NULL;
699     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);
705   } else {
706     ObjectBuilder builder(pModule);
707     builder.MergeSection(pInputFile, pInputSection);
708   }
709   return true;
710 }
711 
SetSDataSection()712 bool HexagonLDBackend::SetSDataSection() {
713   SectionData* pTo = (m_psdata->getSectionData());
714 
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();
735          fragTo != fragToEnd;
736          ++fragTo) {
737       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.
allocateCommonSymbols(Module & pModule)746 bool HexagonLDBackend::allocateCommonSymbols(Module& pModule) {
747   SymbolCategory& symbol_list = pModule.getSymbolTable();
748 
749   if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) {
750     SetSDataSection();
751     return true;
752   }
753 
754   int8_t maxGPSize = config().targets().getGPSize();
755 
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
777   uint64_t bss_offset = bss_sect.size();
778   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());
792 
793       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:
823           break;
824       }
825 
826       if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
827         // allocate TLS common symbol in tbss section
828         tbss_offset += ObjectBuilder::AppendFragment(
829             *frag, *tbss_sect_data, (*com_sym)->value());
830         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
831       } else {
832         // FIXME: how to identify small and large common symbols?
833         bss_offset += ObjectBuilder::AppendFragment(
834             *frag, *bss_sect_data, (*com_sym)->value());
835         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
836       }
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());
850 
851     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:
881         break;
882     }
883 
884     if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
885       // allocate TLS common symbol in tbss section
886       tbss_offset += ObjectBuilder::AppendFragment(
887           *frag, *tbss_sect_data, (*com_sym)->value());
888       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
889     } else {
890       // FIXME: how to identify small and large common symbols?
891       bss_offset += ObjectBuilder::AppendFragment(
892           *frag, *bss_sect_data, (*com_sym)->value());
893       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
894     }
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 
MoveCommonData(SectionData & pFrom,SectionData & pTo)904 bool HexagonLDBackend::MoveCommonData(SectionData& pFrom, SectionData& pTo) {
905   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
931     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);
936     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 
readSection(Input & pInput,SectionData & pSD)946 bool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) {
947   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);
953   } else {
954     llvm::StringRef region = pInput.memArea()->request(offset, size);
955     if (region.size() == 0) {
956       // 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);
959     } else {
960       frag = new RegionFragment(region);
961     }
962   }
963 
964   ObjectBuilder::AppendFragment(*frag, pSD);
965   return true;
966 }
967 
968 /// MoveSectionData - move the fragments of pTO section data to pTo
MoveSectionDataAndSort(SectionData & pFrom,SectionData & pTo)969 bool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom,
970                                               SectionData& pTo) {
971   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
998     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);
1003     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());
1024   return true;
1025 }
1026 
1027 /// doCreateProgramHdrs - backend can implement this function to create the
1028 /// target-dependent segments
doCreateProgramHdrs(Module & pModule)1029 void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) {
1030   // TODO
1031 }
1032 
1033 //===----------------------------------------------------------------------===//
1034 /// createHexagonLDBackend - the help funtion to create corresponding
1035 /// HexagonLDBackend
createHexagonLDBackend(const LinkerConfig & pConfig)1036 TargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) {
1037   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   }
1053   return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets()));
1054 }
1055 
1056 }  // namespace mcld
1057 
1058 //===----------------------------------------------------------------------===//
1059 // Force static initialization.
1060 //===----------------------------------------------------------------------===//
MCLDInitializeHexagonLDBackend()1061 extern "C" void MCLDInitializeHexagonLDBackend() {
1062   // Register the linker backend
1063   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheHexagonTarget,
1064                                                 mcld::createHexagonLDBackend);
1065 }
1066