HexagonLDBackend.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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
38namespace mcld {
39
40//===----------------------------------------------------------------------===//
41// HexagonLDBackend
42//===----------------------------------------------------------------------===//
43HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig,
44                                   HexagonGNUInfo* pInfo)
45    : GNULDBackend(pConfig, pInfo),
46      m_pRelocator(NULL),
47      m_pGOT(NULL),
48      m_pGOTPLT(NULL),
49      m_pPLT(NULL),
50      m_pRelaDyn(NULL),
51      m_pRelaPLT(NULL),
52      m_pDynamic(NULL),
53      m_pGOTSymbol(NULL),
54      m_CopyRel(llvm::ELF::R_HEX_COPY) {
55}
56
57HexagonLDBackend::~HexagonLDBackend() {
58  delete m_pRelocator;
59  delete m_pGOT;
60  delete m_pPLT;
61  delete m_pRelaDyn;
62  delete m_pRelaPLT;
63  delete m_pDynamic;
64}
65
66bool HexagonLDBackend::initRelocator() {
67  if (m_pRelocator == NULL) {
68    m_pRelocator = new HexagonRelocator(*this, config());
69  }
70  return true;
71}
72
73const Relocator* HexagonLDBackend::getRelocator() const {
74  assert(m_pRelocator != NULL);
75  return m_pRelocator;
76}
77
78Relocator* HexagonLDBackend::getRelocator() {
79  assert(m_pRelocator != NULL);
80  return m_pRelocator;
81}
82
83void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) {
84  // initialize .dynamic data
85  if (!config().isCodeStatic() && m_pDynamic == NULL)
86    m_pDynamic = new HexagonELFDynamic(*this, config());
87
88  // set .got.plt and .got sizes
89  // when building shared object, the .got section is must
90  if ((LinkerConfig::Object != config().codeGenType()) &&
91      (!config().isCodeStatic())) {
92    setGOTSectionSize(pBuilder);
93
94    // set .plt size
95    if (m_pPLT->hasPLT1())
96      m_pPLT->finalizeSectionSize();
97
98    // set .rela.dyn size
99    if (!m_pRelaDyn->empty()) {
100      assert(
101          !config().isCodeStatic() &&
102          "static linkage should not result in a dynamic relocation section");
103      setRelaDynSize();
104    }
105    // set .rela.plt size
106    if (!m_pRelaPLT->empty()) {
107      assert(
108          !config().isCodeStatic() &&
109          "static linkage should not result in a dynamic relocation section");
110      setRelaPLTSize();
111    }
112  }
113  // Shared libraries are compiled with -G0 so there is no need to set SData.
114  if (LinkerConfig::Object == config().codeGenType())
115    SetSDataSection();
116}
117
118void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) {
119}
120
121/// dynamic - the dynamic section of the target machine.
122/// Use co-variant return type to return its own dynamic section.
123HexagonELFDynamic& HexagonLDBackend::dynamic() {
124  assert(m_pDynamic != NULL);
125  return *m_pDynamic;
126}
127
128/// dynamic - the dynamic section of the target machine.
129/// Use co-variant return type to return its own dynamic section.
130const HexagonELFDynamic& HexagonLDBackend::dynamic() const {
131  assert(m_pDynamic != NULL);
132  return *m_pDynamic;
133}
134
135uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
136                                           MemoryRegion& pRegion) const {
137  if (!pRegion.size())
138    return 0;
139
140  const ELFFileFormat* FileFormat = getOutputFormat();
141  unsigned int EntrySize = 0;
142  uint64_t RegionSize = 0;
143
144  if ((LinkerConfig::Object != config().codeGenType()) &&
145      (!config().isCodeStatic())) {
146    if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) {
147      unsigned char* buffer = pRegion.begin();
148
149      m_pPLT->applyPLT0();
150      m_pPLT->applyPLT1();
151      HexagonPLT::iterator it = m_pPLT->begin();
152      unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
153
154      memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
155      RegionSize += plt0_size;
156      ++it;
157
158      PLTEntryBase* plt1 = 0;
159      HexagonPLT::iterator ie = m_pPLT->end();
160      while (it != ie) {
161        plt1 = &(llvm::cast<PLTEntryBase>(*it));
162        EntrySize = plt1->size();
163        memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
164        RegionSize += EntrySize;
165        ++it;
166      }
167      return RegionSize;
168    } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) {
169      RegionSize += emitGOTSectionData(pRegion);
170      return RegionSize;
171    } else if (FileFormat->hasGOTPLT() &&
172               (&pSection == &(FileFormat->getGOTPLT()))) {
173      RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
174      return RegionSize;
175    }
176  }
177
178  const SectionData* sect_data = pSection.getSectionData();
179  SectionData::const_iterator frag_iter, frag_end = sect_data->end();
180  uint8_t* out_offset = pRegion.begin();
181  for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
182    size_t size = frag_iter->size();
183    switch (frag_iter->getKind()) {
184      case Fragment::Fillment: {
185        const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter);
186        if (fill_frag.getValueSize() == 0) {
187          // virtual fillment, ignore it.
188          break;
189        }
190        memset(out_offset, fill_frag.getValue(), fill_frag.size());
191        break;
192      }
193      case Fragment::Region: {
194        const RegionFragment& region_frag =
195            llvm::cast<RegionFragment>(*frag_iter);
196        const char* start = region_frag.getRegion().begin();
197        memcpy(out_offset, start, size);
198        break;
199      }
200      case Fragment::Alignment: {
201        const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
202        uint64_t count = size / align_frag.getValueSize();
203        switch (align_frag.getValueSize()) {
204          case 1u:
205            std::memset(out_offset, align_frag.getValue(), count);
206            break;
207          default:
208            llvm::report_fatal_error(
209                "unsupported value size for align fragment emission yet.\n");
210            break;
211        }  // end switch
212        break;
213      }
214      case Fragment::Null: {
215        assert(0x0 == size);
216        break;
217      }
218      default:
219        llvm::report_fatal_error("unsupported fragment type.\n");
220        break;
221    }  // end switch
222    out_offset += size;
223  }  // end for
224
225  return pRegion.size();
226}
227
228HexagonGOT& HexagonLDBackend::getGOT() {
229  assert(m_pGOT != NULL);
230  return *m_pGOT;
231}
232
233const HexagonGOT& HexagonLDBackend::getGOT() const {
234  assert(m_pGOT != NULL);
235  return *m_pGOT;
236}
237
238HexagonPLT& HexagonLDBackend::getPLT() {
239  assert(m_pPLT != NULL && "PLT section not exist");
240  return *m_pPLT;
241}
242
243const HexagonPLT& HexagonLDBackend::getPLT() const {
244  assert(m_pPLT != NULL && "PLT section not exist");
245  return *m_pPLT;
246}
247
248OutputRelocSection& HexagonLDBackend::getRelaDyn() {
249  assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
250  return *m_pRelaDyn;
251}
252
253const OutputRelocSection& HexagonLDBackend::getRelaDyn() const {
254  assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
255  return *m_pRelaDyn;
256}
257
258OutputRelocSection& HexagonLDBackend::getRelaPLT() {
259  assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
260  return *m_pRelaPLT;
261}
262
263const OutputRelocSection& HexagonLDBackend::getRelaPLT() const {
264  assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
265  return *m_pRelaPLT;
266}
267
268HexagonGOTPLT& HexagonLDBackend::getGOTPLT() {
269  assert(m_pGOTPLT != NULL);
270  return *m_pGOTPLT;
271}
272
273const HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const {
274  assert(m_pGOTPLT != NULL);
275  return *m_pGOTPLT;
276}
277
278void HexagonLDBackend::setRelaDynSize() {
279  ELFFileFormat* file_format = getOutputFormat();
280  file_format->getRelaDyn().setSize(m_pRelaDyn->numOfRelocs() *
281                                    getRelaEntrySize());
282}
283
284void HexagonLDBackend::setRelaPLTSize() {
285  ELFFileFormat* file_format = getOutputFormat();
286  file_format->getRelaPlt().setSize(m_pRelaPLT->numOfRelocs() *
287                                    getRelaEntrySize());
288}
289
290void HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) {
291  // set .got.plt size
292  if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() ||
293      m_pGOTSymbol != NULL) {
294    m_pGOTPLT->finalizeSectionSize();
295    defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
296  }
297
298  // set .got size
299  if (!m_pGOT->empty())
300    m_pGOT->finalizeSectionSize();
301}
302
303uint64_t HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const {
304  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
305
306  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
307
308  HexagonGOTEntry* got = 0;
309  unsigned int EntrySize = HexagonGOTEntry::EntrySize;
310  uint64_t RegionSize = 0;
311
312  for (HexagonGOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie;
313       ++it, ++buffer) {
314    got = &(llvm::cast<HexagonGOTEntry>((*it)));
315    *buffer = static_cast<uint32_t>(got->getValue());
316    RegionSize += EntrySize;
317  }
318
319  return RegionSize;
320}
321
322void HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) {
323  // define symbol _GLOBAL_OFFSET_TABLE_
324  if (m_pGOTSymbol != NULL) {
325    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
326        "_GLOBAL_OFFSET_TABLE_",
327        ResolveInfo::Object,
328        ResolveInfo::Define,
329        ResolveInfo::Local,
330        0x0,  // size
331        0x0,  // value
332        FragmentRef::Create(pFrag, 0x0),
333        ResolveInfo::Hidden);
334  } else {
335    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
336        "_GLOBAL_OFFSET_TABLE_",
337        ResolveInfo::Object,
338        ResolveInfo::Define,
339        ResolveInfo::Local,
340        0x0,  // size
341        0x0,  // value
342        FragmentRef::Create(pFrag, 0x0),
343        ResolveInfo::Hidden);
344  }
345}
346
347uint64_t HexagonLDBackend::emitGOTPLTSectionData(
348    MemoryRegion& pRegion,
349    const ELFFileFormat* FileFormat) const {
350  assert(m_pGOTPLT != NULL &&
351         "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
352  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
353  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
354
355  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
356
357  HexagonGOTEntry* got = 0;
358  unsigned int EntrySize = HexagonGOTEntry::EntrySize;
359  uint64_t RegionSize = 0;
360
361  for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end();
362       it != ie;
363       ++it, ++buffer) {
364    got = &(llvm::cast<HexagonGOTEntry>((*it)));
365    *buffer = static_cast<uint32_t>(got->getValue());
366    RegionSize += EntrySize;
367  }
368
369  return RegionSize;
370}
371
372unsigned int HexagonLDBackend::getTargetSectionOrder(
373    const LDSection& pSectHdr) const {
374  const ELFFileFormat* file_format = getOutputFormat();
375
376  if (LinkerConfig::Object != config().codeGenType()) {
377    if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) {
378      if (config().options().hasNow())
379        return SHO_RELRO;
380      return SHO_RELRO_LAST;
381    }
382
383    if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) {
384      if (config().options().hasNow())
385        return SHO_RELRO;
386      return SHO_NON_RELRO_FIRST;
387    }
388
389    if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
390      return SHO_PLT;
391  }
392
393  if (&pSectHdr == m_pstart)
394    return SHO_INIT;
395
396  if (&pSectHdr == m_psdata)
397    return SHO_SMALL_DATA;
398
399  return SHO_UNDEFINED;
400}
401
402void HexagonLDBackend::initTargetSections(Module& pModule,
403                                          ObjectBuilder& pBuilder) {
404  if ((LinkerConfig::Object != config().codeGenType()) &&
405      (!config().isCodeStatic())) {
406    ELFFileFormat* file_format = getOutputFormat();
407    // initialize .got
408    LDSection& got = file_format->getGOT();
409    m_pGOT = new HexagonGOT(got);
410
411    // initialize .got.plt
412    LDSection& gotplt = file_format->getGOTPLT();
413    m_pGOTPLT = new HexagonGOTPLT(gotplt);
414
415    // initialize .plt
416    LDSection& plt = file_format->getPLT();
417    m_pPLT = new HexagonPLT(plt, *m_pGOTPLT, config());
418
419    // initialize .rela.plt
420    LDSection& relaplt = file_format->getRelaPlt();
421    relaplt.setLink(&plt);
422    m_pRelaPLT = new OutputRelocSection(pModule, relaplt);
423
424    // initialize .rela.dyn
425    LDSection& reladyn = file_format->getRelaDyn();
426    m_pRelaDyn = new OutputRelocSection(pModule, reladyn);
427  }
428  m_psdata = pBuilder.CreateSection(".sdata",
429                                    LDFileFormat::Target,
430                                    llvm::ELF::SHT_PROGBITS,
431                                    llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
432                                    4 * 1024);
433  m_pscommon_1 =
434      pBuilder.CreateSection(".scommon.1",
435                             LDFileFormat::Target,
436                             llvm::ELF::SHT_PROGBITS,
437                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
438                             1);
439  IRBuilder::CreateSectionData(*m_pscommon_1);
440
441  m_pscommon_2 =
442      pBuilder.CreateSection(".scommon.2",
443                             LDFileFormat::Target,
444                             llvm::ELF::SHT_PROGBITS,
445                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
446                             2);
447  IRBuilder::CreateSectionData(*m_pscommon_2);
448
449  m_pscommon_4 =
450      pBuilder.CreateSection(".scommon.4",
451                             LDFileFormat::Target,
452                             llvm::ELF::SHT_PROGBITS,
453                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
454                             4);
455  IRBuilder::CreateSectionData(*m_pscommon_4);
456
457  m_pscommon_8 =
458      pBuilder.CreateSection(".scommon.8",
459                             LDFileFormat::Target,
460                             llvm::ELF::SHT_PROGBITS,
461                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
462                             8);
463  IRBuilder::CreateSectionData(*m_pscommon_8);
464
465  m_pstart = pBuilder.CreateSection(".start",
466                                    LDFileFormat::Target,
467                                    llvm::ELF::SHT_PROGBITS,
468                                    llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
469                                    8);
470  IRBuilder::CreateSectionData(*m_pstart);
471}
472
473void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {
474  if (config().codeGenType() == LinkerConfig::Object)
475    return;
476
477  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
478  // same name in input
479  m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
480      "_GLOBAL_OFFSET_TABLE_",
481      ResolveInfo::Object,
482      ResolveInfo::Define,
483      ResolveInfo::Local,
484      0x0,  // size
485      0x0,  // value
486      FragmentRef::Null(),
487      ResolveInfo::Hidden);
488
489  m_psdabase = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
490      "_SDA_BASE_",
491      ResolveInfo::Object,
492      ResolveInfo::Define,
493      ResolveInfo::Absolute,
494      0x0,  // size
495      0x0,  // value
496      FragmentRef::Null(),
497      ResolveInfo::Hidden);
498
499  pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
500      "__sbss_start",
501      ResolveInfo::Object,
502      ResolveInfo::Define,
503      ResolveInfo::Absolute,
504      0x0,  // size
505      0x0,  // value
506      FragmentRef::Null(),
507      ResolveInfo::Hidden);
508
509  pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
510      "__sbss_end",
511      ResolveInfo::Object,
512      ResolveInfo::Define,
513      ResolveInfo::Absolute,
514      0x0,  // size
515      0x0,  // value
516      FragmentRef::Null(),
517      ResolveInfo::Hidden);
518}
519
520bool HexagonLDBackend::initTargetStubs() {
521  if (getStubFactory() != NULL) {
522    getStubFactory()->addPrototype(
523        new HexagonAbsoluteStub(config().isCodeIndep()));
524    return true;
525  }
526  return false;
527}
528
529bool HexagonLDBackend::initBRIslandFactory() {
530  if (m_pBRIslandFactory == NULL) {
531    m_pBRIslandFactory =
532        new BranchIslandFactory(maxFwdBranchOffset(), maxBwdBranchOffset(), 0);
533  }
534  return true;
535}
536
537bool HexagonLDBackend::initStubFactory() {
538  if (m_pStubFactory == NULL) {
539    m_pStubFactory = new StubFactory();
540  }
541  return true;
542}
543
544bool HexagonLDBackend::doRelax(Module& pModule,
545                               IRBuilder& pBuilder,
546                               bool& pFinished) {
547  assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
548  bool isRelaxed = false;
549  ELFFileFormat* file_format = getOutputFormat();
550  // check branch relocs and create the related stubs if needed
551  Module::obj_iterator input, inEnd = pModule.obj_end();
552  for (input = pModule.obj_begin(); input != inEnd; ++input) {
553    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
554    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
555      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
556        continue;
557      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
558      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
559        switch (reloc->type()) {
560          case llvm::ELF::R_HEX_B22_PCREL:
561          case llvm::ELF::R_HEX_B15_PCREL:
562          case llvm::ELF::R_HEX_B7_PCREL:
563          case llvm::ELF::R_HEX_B13_PCREL:
564          case llvm::ELF::R_HEX_B9_PCREL: {
565            Relocation* relocation = llvm::cast<Relocation>(reloc);
566            uint64_t sym_value = 0x0;
567            LDSymbol* symbol = relocation->symInfo()->outSymbol();
568            if (symbol->hasFragRef()) {
569              uint64_t value = symbol->fragRef()->getOutputOffset();
570              uint64_t addr =
571                  symbol->fragRef()->frag()->getParent()->getSection().addr();
572              sym_value = addr + value;
573            }
574            Stub* stub = getStubFactory()->create(*relocation,  // relocation
575                                                  sym_value,  // symbol value
576                                                  pBuilder,
577                                                  *getBRIslandFactory());
578            if (stub != NULL) {
579              assert(stub->symInfo() != NULL);
580              // increase the size of .symtab and .strtab
581              LDSection& symtab = file_format->getSymTab();
582              LDSection& strtab = file_format->getStrTab();
583              symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
584              strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
585              isRelaxed = true;
586            }
587          } break;
588
589          default:
590            break;
591        }
592      }
593    }
594  }
595
596  // find the first fragment w/ invalid offset due to stub insertion
597  Fragment* invalid = NULL;
598  pFinished = true;
599  for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
600                                     island_end = getBRIslandFactory()->end();
601       island != island_end;
602       ++island) {
603    if ((*island).end() == file_format->getText().getSectionData()->end())
604      break;
605
606    Fragment* exit = (*island).end();
607    if (((*island).offset() + (*island).size()) > exit->getOffset()) {
608      invalid = exit;
609      pFinished = false;
610      break;
611    }
612  }
613
614  // reset the offset of invalid fragments
615  while (invalid != NULL) {
616    invalid->setOffset(invalid->getPrevNode()->getOffset() +
617                       invalid->getPrevNode()->size());
618    invalid = invalid->getNextNode();
619  }
620
621  // reset the size of .text
622  if (isRelaxed) {
623    file_format->getText().setSize(
624        file_format->getText().getSectionData()->back().getOffset() +
625        file_format->getText().getSectionData()->back().size());
626  }
627  return isRelaxed;
628}
629
630/// finalizeSymbol - finalize the symbol value
631bool HexagonLDBackend::finalizeTargetSymbols() {
632  if (config().codeGenType() == LinkerConfig::Object)
633    return true;
634  if (m_psdabase)
635    m_psdabase->setValue(m_psdata->addr());
636
637  ELFSegmentFactory::const_iterator edata = elfSegmentTable().find(
638      llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
639  if (elfSegmentTable().end() != edata) {
640    if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) {
641      f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz());
642    }
643    if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) {
644      f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz());
645    }
646    if (f_pBSSStart != NULL &&
647        ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
648      f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz());
649    }
650    if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) {
651      f_pEnd->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
652    }
653    if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) {
654      f_p_End->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
655    }
656  }
657  return true;
658}
659
660/// merge Input Sections
661bool HexagonLDBackend::mergeSection(Module& pModule,
662                                    const Input& pInputFile,
663                                    LDSection& pInputSection) {
664  if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) ||
665      (pInputSection.kind() == LDFileFormat::LinkOnce) ||
666      (pInputSection.kind() == LDFileFormat::Target)) {
667    SectionData* sd = NULL;
668    if (!m_psdata->hasSectionData()) {
669      sd = IRBuilder::CreateSectionData(*m_psdata);
670      m_psdata->setSectionData(sd);
671    }
672    sd = m_psdata->getSectionData();
673    MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd);
674  } else {
675    ObjectBuilder builder(pModule);
676    builder.MergeSection(pInputFile, pInputSection);
677  }
678  return true;
679}
680
681bool HexagonLDBackend::SetSDataSection() {
682  SectionData* pTo = (m_psdata->getSectionData());
683
684  if (pTo) {
685    MoveCommonData(*m_pscommon_1->getSectionData(), *pTo);
686    MoveCommonData(*m_pscommon_2->getSectionData(), *pTo);
687    MoveCommonData(*m_pscommon_4->getSectionData(), *pTo);
688    MoveCommonData(*m_pscommon_8->getSectionData(), *pTo);
689
690    SectionData::FragmentListType& to_list = pTo->getFragmentList();
691    SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end();
692    uint32_t offset = 0;
693    for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) {
694      fragTo->setOffset(offset);
695      offset += fragTo->size();
696    }
697
698    // set up pTo's header
699    pTo->getSection().setSize(offset);
700
701    SectionData::FragmentListType& newlist = pTo->getFragmentList();
702
703    for (fragTo = newlist.begin(), fragToEnd = newlist.end();
704         fragTo != fragToEnd;
705         ++fragTo) {
706      fragTo->setParent(pTo);
707    }
708  }
709
710  return true;
711}
712
713/// allocateCommonSymbols - allocate common symbols in the corresponding
714/// sections. This is called at pre-layout stage.
715bool HexagonLDBackend::allocateCommonSymbols(Module& pModule) {
716  SymbolCategory& symbol_list = pModule.getSymbolTable();
717
718  if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) {
719    SetSDataSection();
720    return true;
721  }
722
723  int8_t maxGPSize = config().options().getGPSize();
724
725  SymbolCategory::iterator com_sym, com_end;
726
727  // get corresponding BSS LDSection
728  ELFFileFormat* file_format = getOutputFormat();
729  LDSection& bss_sect = file_format->getBSS();
730  LDSection& tbss_sect = file_format->getTBSS();
731
732  // get or create corresponding BSS SectionData
733  SectionData* bss_sect_data = NULL;
734  if (bss_sect.hasSectionData())
735    bss_sect_data = bss_sect.getSectionData();
736  else
737    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
738
739  SectionData* tbss_sect_data = NULL;
740  if (tbss_sect.hasSectionData())
741    tbss_sect_data = tbss_sect.getSectionData();
742  else
743    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
744
745  // remember original BSS size
746  uint64_t bss_offset = bss_sect.size();
747  uint64_t tbss_offset = tbss_sect.size();
748
749  // allocate all local common symbols
750  com_end = symbol_list.localEnd();
751
752  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
753    if (ResolveInfo::Common == (*com_sym)->desc()) {
754      // We have to reset the description of the symbol here. When doing
755      // incremental linking, the output relocatable object may have common
756      // symbols. Therefore, we can not treat common symbols as normal symbols
757      // when emitting the regular name pools. We must change the symbols'
758      // description here.
759      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
760      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
761
762      switch ((*com_sym)->size()) {
763        case 1:
764          if (maxGPSize <= 0)
765            break;
766          ObjectBuilder::AppendFragment(
767              *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value());
768          (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
769          continue;
770        case 2:
771          if (maxGPSize <= 1)
772            break;
773          ObjectBuilder::AppendFragment(
774              *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value());
775          (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
776          continue;
777        case 4:
778          if (maxGPSize <= 3)
779            break;
780          ObjectBuilder::AppendFragment(
781              *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value());
782          (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
783          continue;
784        case 8:
785          if (maxGPSize <= 7)
786            break;
787          ObjectBuilder::AppendFragment(
788              *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value());
789          (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
790          continue;
791        default:
792          break;
793      }
794
795      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
796        // allocate TLS common symbol in tbss section
797        tbss_offset += ObjectBuilder::AppendFragment(
798            *frag, *tbss_sect_data, (*com_sym)->value());
799        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
800      } else {
801        // FIXME: how to identify small and large common symbols?
802        bss_offset += ObjectBuilder::AppendFragment(
803            *frag, *bss_sect_data, (*com_sym)->value());
804        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
805      }
806    }
807  }
808
809  // allocate all global common symbols
810  com_end = symbol_list.commonEnd();
811  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
812    // We have to reset the description of the symbol here. When doing
813    // incremental linking, the output relocatable object may have common
814    // symbols. Therefore, we can not treat common symbols as normal symbols
815    // when emitting the regular name pools. We must change the symbols'
816    // description here.
817    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
818    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
819
820    switch ((*com_sym)->size()) {
821      case 1:
822        if (maxGPSize <= 0)
823          break;
824        ObjectBuilder::AppendFragment(
825            *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value());
826        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
827        continue;
828      case 2:
829        if (maxGPSize <= 1)
830          break;
831        ObjectBuilder::AppendFragment(
832            *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value());
833        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
834        continue;
835      case 4:
836        if (maxGPSize <= 3)
837          break;
838        ObjectBuilder::AppendFragment(
839            *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value());
840        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
841        continue;
842      case 8:
843        if (maxGPSize <= 7)
844          break;
845        ObjectBuilder::AppendFragment(
846            *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value());
847        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
848        continue;
849      default:
850        break;
851    }
852
853    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
854      // allocate TLS common symbol in tbss section
855      tbss_offset += ObjectBuilder::AppendFragment(
856          *frag, *tbss_sect_data, (*com_sym)->value());
857      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
858    } else {
859      // FIXME: how to identify small and large common symbols?
860      bss_offset += ObjectBuilder::AppendFragment(
861          *frag, *bss_sect_data, (*com_sym)->value());
862      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
863    }
864  }
865
866  bss_sect.setSize(bss_offset);
867  tbss_sect.setSize(tbss_offset);
868  symbol_list.changeCommonsToGlobal();
869  SetSDataSection();
870  return true;
871}
872
873bool HexagonLDBackend::MoveCommonData(SectionData& pFrom, SectionData& pTo) {
874  SectionData::FragmentListType& to_list = pTo.getFragmentList();
875  SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();
876
877  uint32_t pFromFlag = pFrom.getSection().align();
878  bool found = false;
879
880  SectionData::FragmentListType::iterator fragInsert;
881
882  for (frag = to_list.begin(); frag != fragEnd; ++frag) {
883    if (frag->getKind() == mcld::Fragment::Alignment) {
884      fragInsert = frag;
885      continue;
886    }
887    if ((frag->getKind() != mcld::Fragment::Region) &&
888        (frag->getKind() != mcld::Fragment::Fillment)) {
889      continue;
890    }
891    uint32_t flag = frag->getParent()->getSection().align();
892    if (pFromFlag < flag) {
893      found = true;
894      break;
895    }
896  }
897  AlignFragment* align = NULL;
898  if (pFrom.getSection().align() > 1) {
899    // if the align constraint is larger than 1, append an alignment
900    unsigned int alignment = pFrom.getSection().align();
901    align = new AlignFragment(/*alignment*/alignment,
902                              /*the filled value*/0x0,
903                              /*the size of filled value*/1u,
904                              /*max bytes to emit*/alignment - 1);
905    pFrom.getFragmentList().push_front(align);
906  }
907  if (found)
908    to_list.splice(fragInsert, pFrom.getFragmentList());
909  else
910    to_list.splice(frag, pFrom.getFragmentList());
911
912  return true;
913}
914
915bool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) {
916  Fragment* frag = NULL;
917  uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
918  uint32_t size = pSD.getSection().size();
919
920  if (pSD.getSection().type() == llvm::ELF::SHT_NOBITS) {
921    frag = new FillFragment(0x0, 1, size);
922  } else {
923    llvm::StringRef region = pInput.memArea()->request(offset, size);
924    if (region.size() == 0) {
925      // If the input section's size is zero, we got a NULL region.
926      // use a virtual fill fragment
927      frag = new FillFragment(0x0, 0, 0);
928    } else {
929      frag = new RegionFragment(region);
930    }
931  }
932
933  ObjectBuilder::AppendFragment(*frag, pSD);
934  return true;
935}
936
937/// MoveSectionData - move the fragments of pTO section data to pTo
938bool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom,
939                                              SectionData& pTo) {
940  assert(&pFrom != &pTo && "Cannot move section data to itself!");
941  SectionData::FragmentListType& to_list = pTo.getFragmentList();
942  SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();
943
944  uint32_t pFromFlag = pFrom.getSection().align();
945  bool found = false;
946
947  SectionData::FragmentListType::iterator fragInsert;
948
949  for (frag = to_list.begin(); frag != fragEnd; ++frag) {
950    if (frag->getKind() == mcld::Fragment::Alignment) {
951      fragInsert = frag;
952      continue;
953    }
954    if ((frag->getKind() != mcld::Fragment::Region) &&
955        (frag->getKind() != mcld::Fragment::Fillment)) {
956      continue;
957    }
958    uint32_t flag = frag->getParent()->getSection().align();
959    if (pFromFlag < flag) {
960      found = true;
961      break;
962    }
963  }
964  AlignFragment* align = NULL;
965  if (pFrom.getSection().align() > 1) {
966    // if the align constraint is larger than 1, append an alignment
967    unsigned int alignment = pFrom.getSection().align();
968    align = new AlignFragment(/*alignment*/alignment,
969                              /*the filled value*/0x0,
970                              /*the size of filled value*/1u,
971                              /*max bytes to emit*/alignment - 1);
972    pFrom.getFragmentList().push_front(align);
973  }
974  if (found)
975    to_list.splice(fragInsert, pFrom.getFragmentList());
976  else
977    to_list.splice(frag, pFrom.getFragmentList());
978
979  uint32_t offset = 0;
980  for (frag = to_list.begin(); frag != fragEnd; ++frag) {
981    frag->setOffset(offset);
982    offset += frag->size();
983  }
984
985  // set up pTo's header
986  pTo.getSection().setSize(offset);
987
988  if (pFrom.getSection().align() > pTo.getSection().align())
989    pTo.getSection().setAlign(pFrom.getSection().align());
990
991  if (pFrom.getSection().flag() > pTo.getSection().flag())
992    pTo.getSection().setFlag(pFrom.getSection().flag());
993  return true;
994}
995
996/// doCreateProgramHdrs - backend can implement this function to create the
997/// target-dependent segments
998void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) {
999  // TODO
1000}
1001
1002//===----------------------------------------------------------------------===//
1003/// createHexagonLDBackend - the help funtion to create corresponding
1004/// HexagonLDBackend
1005TargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) {
1006  if (pConfig.targets().triple().isOSDarwin()) {
1007    assert(0 && "MachO linker is not supported yet");
1008    /**
1009    return new HexagonMachOLDBackend(createHexagonMachOArchiveReader,
1010                               createHexagonMachOObjectReader,
1011                               createHexagonMachOObjectWriter);
1012    **/
1013  }
1014  if (pConfig.targets().triple().isOSWindows()) {
1015    assert(0 && "COFF linker is not supported yet");
1016    /**
1017    return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader,
1018                               createHexagonCOFFObjectReader,
1019                               createHexagonCOFFObjectWriter);
1020    **/
1021  }
1022  return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets()));
1023}
1024
1025}  // namespace mcld
1026
1027//===----------------------------------------------------------------------===//
1028// Force static initialization.
1029//===----------------------------------------------------------------------===//
1030extern "C" void MCLDInitializeHexagonLDBackend() {
1031  // Register the linker backend
1032  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheHexagonTarget,
1033                                                mcld::createHexagonLDBackend);
1034}
1035