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