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