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