[go: nahoru, domu]

1//===- ARMLDBackend.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 "ARM.h"
10#include "ARMGNUInfo.h"
11#include "ARMELFAttributeData.h"
12#include "ARMELFDynamic.h"
13#include "ARMException.h"
14#include "ARMLDBackend.h"
15#include "ARMRelocator.h"
16#include "ARMToARMStub.h"
17#include "ARMToTHMStub.h"
18#include "THMToTHMStub.h"
19#include "THMToARMStub.h"
20
21#include "mcld/IRBuilder.h"
22#include "mcld/LinkerConfig.h"
23#include "mcld/ADT/ilist_sort.h"
24#include "mcld/Fragment/AlignFragment.h"
25#include "mcld/Fragment/FillFragment.h"
26#include "mcld/Fragment/NullFragment.h"
27#include "mcld/Fragment/RegionFragment.h"
28#include "mcld/Fragment/Stub.h"
29#include "mcld/LD/BranchIslandFactory.h"
30#include "mcld/LD/ELFFileFormat.h"
31#include "mcld/LD/ELFSegment.h"
32#include "mcld/LD/ELFSegmentFactory.h"
33#include "mcld/LD/LDContext.h"
34#include "mcld/LD/StubFactory.h"
35#include "mcld/Object/ObjectBuilder.h"
36#include "mcld/Support/MemoryArea.h"
37#include "mcld/Support/MemoryRegion.h"
38#include "mcld/Support/MsgHandling.h"
39#include "mcld/Support/TargetRegistry.h"
40#include "mcld/Target/ELFAttribute.h"
41#include "mcld/Target/GNUInfo.h"
42
43#include <llvm/ADT/StringRef.h>
44#include <llvm/ADT/Triple.h>
45#include <llvm/ADT/Twine.h>
46#include <llvm/Support/Casting.h>
47#include <llvm/Support/ELF.h>
48
49#include <cstring>
50#include <vector>
51
52namespace mcld {
53
54/// Fragment data for EXIDX_CANTUNWIND.
55static const char g_CantUnwindEntry[8] = {
56  // Relocation to text section.
57  0, 0, 0, 0,
58  // EXIDX_CANTUNWIND (little endian.)
59  1, 0, 0, 0,
60};
61
62/// Helper function to create a local symbol at the end of the fragment.
63static mcld::ResolveInfo*
64CreateLocalSymbolToFragmentEnd(mcld::Module& pModule, mcld::Fragment& pFrag) {
65  // Create and add symbol to the name pool.
66  mcld::ResolveInfo* resolveInfo =
67      pModule.getNamePool().createSymbol(/* pName */"",
68                                         /* pIsDyn */false,
69                                         mcld::ResolveInfo::Section,
70                                         mcld::ResolveInfo::Define,
71                                         mcld::ResolveInfo::Local,
72                                         /* pSize */0,
73                                         mcld::ResolveInfo::Hidden);
74  if (resolveInfo == nullptr) {
75    return nullptr;
76  }
77
78  // Create input symbol.
79  mcld::LDSymbol* inputSym = mcld::LDSymbol::Create(*resolveInfo);
80  if (inputSym == nullptr) {
81    return nullptr;
82  }
83
84  inputSym->setFragmentRef(mcld::FragmentRef::Create(pFrag, pFrag.size()));
85  inputSym->setValue(/* pValue */0);
86
87  // The output symbol is simply an alias to the input symbol.
88  resolveInfo->setSymPtr(inputSym);
89
90  return resolveInfo;
91}
92
93/// Comparator to sort .ARM.exidx fragments according to the address of the
94/// corresponding .text fragment.
95class ExIdxFragmentComparator {
96 private:
97  const ARMExData& m_pExData;
98
99 public:
100  explicit ExIdxFragmentComparator(const ARMExData& pExData)
101      : m_pExData(pExData) {
102  }
103
104  bool operator()(const Fragment& a, const Fragment& b) {
105    ARMExSectionTuple* tupleA = m_pExData.getTupleByExIdx(&a);
106    ARMExSectionTuple* tupleB = m_pExData.getTupleByExIdx(&b);
107
108    Fragment* textFragA = tupleA->getTextFragment();
109    Fragment* textFragB = tupleB->getTextFragment();
110
111    uint64_t addrA = textFragA->getParent()->getSection().addr() +
112                     textFragA->getOffset();
113    uint64_t addrB = textFragB->getParent()->getSection().addr() +
114                     textFragB->getOffset();
115    return (addrA < addrB);
116  }
117};
118
119//===----------------------------------------------------------------------===//
120// ARMGNULDBackend
121//===----------------------------------------------------------------------===//
122ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
123    : GNULDBackend(pConfig, pInfo),
124      m_pRelocator(NULL),
125      m_pGOT(NULL),
126      m_pPLT(NULL),
127      m_pRelDyn(NULL),
128      m_pRelPLT(NULL),
129      m_pAttrData(NULL),
130      m_pDynamic(NULL),
131      m_pGOTSymbol(NULL),
132      m_pEXIDXStart(NULL),
133      m_pEXIDXEnd(NULL),
134      m_pEXIDX(NULL),
135      m_pEXTAB(NULL),
136      m_pAttributes(NULL) {
137}
138
139ARMGNULDBackend::~ARMGNULDBackend() {
140  delete m_pRelocator;
141  delete m_pGOT;
142  delete m_pPLT;
143  delete m_pRelDyn;
144  delete m_pRelPLT;
145  delete m_pDynamic;
146  delete m_pAttrData;
147}
148
149void ARMGNULDBackend::initTargetSections(Module& pModule,
150                                         ObjectBuilder& pBuilder) {
151  // FIXME: Currently we set exidx and extab to "Exception" and directly emit
152  // them from input
153  m_pEXIDX =
154      pBuilder.CreateSection(".ARM.exidx",
155                             LDFileFormat::Target,
156                             llvm::ELF::SHT_ARM_EXIDX,
157                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER,
158                             config().targets().bitclass() / 8);
159  m_pEXTAB = pBuilder.CreateSection(".ARM.extab",
160                                    LDFileFormat::Target,
161                                    llvm::ELF::SHT_PROGBITS,
162                                    llvm::ELF::SHF_ALLOC,
163                                    0x1);
164  m_pAttributes = pBuilder.CreateSection(".ARM.attributes",
165                                         LDFileFormat::Target,
166                                         llvm::ELF::SHT_ARM_ATTRIBUTES,
167                                         0x0,
168                                         0x1);
169
170  // initialize "aeabi" attributes subsection
171  m_pAttrData = new ARMELFAttributeData();
172  attribute().registerAttributeData(*m_pAttrData);
173
174  if (LinkerConfig::Object != config().codeGenType()) {
175    ELFFileFormat* file_format = getOutputFormat();
176
177    // initialize .got
178    LDSection& got = file_format->getGOT();
179    m_pGOT = new ARMGOT(got);
180
181    // initialize .plt
182    LDSection& plt = file_format->getPLT();
183    m_pPLT = new ARMPLT(plt, *m_pGOT);
184
185    // initialize .rel.plt
186    LDSection& relplt = file_format->getRelPlt();
187    relplt.setLink(&plt);
188    // create SectionData and ARMRelDynSection
189    m_pRelPLT = new OutputRelocSection(pModule, relplt);
190
191    // initialize .rel.dyn
192    LDSection& reldyn = file_format->getRelDyn();
193    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
194  }
195}
196
197void ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {
198  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
199  // same name in input
200  if (LinkerConfig::Object != config().codeGenType()) {
201    m_pGOTSymbol =
202        pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
203            "_GLOBAL_OFFSET_TABLE_",
204            ResolveInfo::Object,
205            ResolveInfo::Define,
206            ResolveInfo::Local,
207            0x0,  // size
208            0x0,  // value
209            FragmentRef::Null(),
210            ResolveInfo::Hidden);
211  }
212  if (m_pEXIDX != NULL && m_pEXIDX->size() != 0x0) {
213    FragmentRef* exidx_start =
214        FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0);
215    FragmentRef* exidx_end = FragmentRef::Create(
216        m_pEXIDX->getSectionData()->front(), m_pEXIDX->size());
217    m_pEXIDXStart =
218        pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
219            "__exidx_start",
220            ResolveInfo::Object,
221            ResolveInfo::Define,
222            ResolveInfo::Local,
223            0x0,          // size
224            0x0,          // value
225            exidx_start,  // FragRef
226            ResolveInfo::Default);
227
228    m_pEXIDXEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
229        "__exidx_end",
230        ResolveInfo::Object,
231        ResolveInfo::Define,
232        ResolveInfo::Local,
233        0x0,        // size
234        0x0,        // value
235        exidx_end,  // FragRef
236        ResolveInfo::Default);
237    // change __exidx_start/_end to local dynamic category
238    if (m_pEXIDXStart != NULL)
239      pModule.getSymbolTable().changeToDynamic(*m_pEXIDXStart);
240    if (m_pEXIDXEnd != NULL)
241      pModule.getSymbolTable().changeToDynamic(*m_pEXIDXEnd);
242  } else {
243    m_pEXIDXStart =
244        pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
245            "__exidx_start",
246            ResolveInfo::NoType,
247            ResolveInfo::Define,
248            ResolveInfo::Absolute,
249            0x0,  // size
250            0x0,  // value
251            FragmentRef::Null(),
252            ResolveInfo::Default);
253
254    m_pEXIDXEnd = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
255        "__exidx_end",
256        ResolveInfo::NoType,
257        ResolveInfo::Define,
258        ResolveInfo::Absolute,
259        0x0,  // size
260        0x0,  // value
261        FragmentRef::Null(),
262        ResolveInfo::Default);
263  }
264}
265
266bool ARMGNULDBackend::initRelocator() {
267  if (m_pRelocator == NULL) {
268    m_pRelocator = new ARMRelocator(*this, config());
269  }
270  return true;
271}
272
273const Relocator* ARMGNULDBackend::getRelocator() const {
274  assert(m_pRelocator != NULL);
275  return m_pRelocator;
276}
277
278Relocator* ARMGNULDBackend::getRelocator() {
279  assert(m_pRelocator != NULL);
280  return m_pRelocator;
281}
282
283void ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder) {
284  // initialize .dynamic data
285  if (!config().isCodeStatic() && m_pDynamic == NULL)
286    m_pDynamic = new ARMELFDynamic(*this, config());
287
288  // set attribute section size
289  m_pAttributes->setSize(attribute().sizeOutput());
290
291  // set .got size
292  // when building shared object, the .got section is must
293  if (LinkerConfig::Object != config().codeGenType()) {
294    if (LinkerConfig::DynObj == config().codeGenType() || m_pGOT->hasGOT1() ||
295        m_pGOTSymbol != NULL) {
296      m_pGOT->finalizeSectionSize();
297      defineGOTSymbol(pBuilder);
298    }
299
300    // set .plt size
301    if (m_pPLT->hasPLT1())
302      m_pPLT->finalizeSectionSize();
303
304    ELFFileFormat* file_format = getOutputFormat();
305    // set .rel.dyn size
306    if (!m_pRelDyn->empty()) {
307      assert(
308          !config().isCodeStatic() &&
309          "static linkage should not result in a dynamic relocation section");
310      file_format->getRelDyn().setSize(m_pRelDyn->numOfRelocs() *
311                                       getRelEntrySize());
312    }
313
314    // set .rel.plt size
315    if (!m_pRelPLT->empty()) {
316      assert(
317          !config().isCodeStatic() &&
318          "static linkage should not result in a dynamic relocation section");
319      file_format->getRelPlt().setSize(m_pRelPLT->numOfRelocs() *
320                                       getRelEntrySize());
321    }
322  }
323}
324
325void ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) {
326  const ELFFileFormat* file_format = getOutputFormat();
327
328  // apply PLT
329  if (file_format->hasPLT()) {
330    // Since we already have the size of LDSection PLT, m_pPLT should not be
331    // NULL.
332    assert(m_pPLT != NULL);
333    m_pPLT->applyPLT0();
334    m_pPLT->applyPLT1();
335  }
336
337  // apply GOT
338  if (file_format->hasGOT()) {
339    // Since we already have the size of GOT, m_pGOT should not be NULL.
340    assert(m_pGOT != NULL);
341    if (LinkerConfig::DynObj == config().codeGenType())
342      m_pGOT->applyGOT0(file_format->getDynamic().addr());
343    else {
344      // executable file and object file? should fill with zero.
345      m_pGOT->applyGOT0(0);
346    }
347  }
348}
349
350/// dynamic - the dynamic section of the target machine.
351/// Use co-variant return type to return its own dynamic section.
352ARMELFDynamic& ARMGNULDBackend::dynamic() {
353  assert(m_pDynamic != NULL);
354  return *m_pDynamic;
355}
356
357/// dynamic - the dynamic section of the target machine.
358/// Use co-variant return type to return its own dynamic section.
359const ARMELFDynamic& ARMGNULDBackend::dynamic() const {
360  assert(m_pDynamic != NULL);
361  return *m_pDynamic;
362}
363
364void ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) {
365  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
366  if (m_pGOTSymbol != NULL) {
367    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
368        "_GLOBAL_OFFSET_TABLE_",
369        ResolveInfo::Object,
370        ResolveInfo::Define,
371        ResolveInfo::Local,
372        0x0,  // size
373        0x0,  // value
374        FragmentRef::Create(*(m_pGOT->begin()), 0x0),
375        ResolveInfo::Hidden);
376  } else {
377    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
378        "_GLOBAL_OFFSET_TABLE_",
379        ResolveInfo::Object,
380        ResolveInfo::Define,
381        ResolveInfo::Local,
382        0x0,  // size
383        0x0,  // value
384        FragmentRef::Create(*(m_pGOT->begin()), 0x0),
385        ResolveInfo::Hidden);
386  }
387}
388
389uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection,
390                                          MemoryRegion& pRegion) const {
391  assert(pRegion.size() && "Size of MemoryRegion is zero!");
392
393  const ELFFileFormat* file_format = getOutputFormat();
394
395  if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) {
396    uint64_t result = m_pPLT->emit(pRegion);
397    return result;
398  }
399
400  if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) {
401    uint64_t result = m_pGOT->emit(pRegion);
402    return result;
403  }
404
405  if (&pSection == m_pAttributes) {
406    return attribute().emit(pRegion);
407  }
408
409  // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab
410  // directly from the input file.
411  const SectionData* sect_data = pSection.getSectionData();
412  SectionData::const_iterator frag_iter, frag_end = sect_data->end();
413  uint8_t* out_offset = pRegion.begin();
414  for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
415    size_t size = frag_iter->size();
416    switch (frag_iter->getKind()) {
417      case Fragment::Fillment: {
418        const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter);
419        if (fill_frag.getValueSize() == 0) {
420          // virtual fillment, ignore it.
421          break;
422        }
423
424        memset(out_offset, fill_frag.getValue(), fill_frag.size());
425        break;
426      }
427      case Fragment::Region: {
428        const RegionFragment& region_frag =
429            llvm::cast<RegionFragment>(*frag_iter);
430        const char* start = region_frag.getRegion().begin();
431        memcpy(out_offset, start, size);
432        break;
433      }
434      case Fragment::Alignment: {
435        const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
436        uint64_t count = size / align_frag.getValueSize();
437        switch (align_frag.getValueSize()) {
438          case 1u:
439            std::memset(out_offset, align_frag.getValue(), count);
440            break;
441          default:
442            llvm::report_fatal_error(
443                "unsupported value size for align fragment emission yet.\n");
444            break;
445        }  // end switch
446        break;
447      }
448      case Fragment::Null: {
449        assert(0x0 == size);
450        break;
451      }
452      default:
453        llvm::report_fatal_error("unsupported fragment type.\n");
454        break;
455    }  // end switch
456    out_offset += size;
457  }  // end for
458  return pRegion.size();
459}
460
461/// finalizeSymbol - finalize the symbol value
462bool ARMGNULDBackend::finalizeTargetSymbols() {
463  return true;
464}
465
466
467/// preMergeSections - hooks to be executed before merging sections
468void ARMGNULDBackend::preMergeSections(Module& pModule) {
469  // Since the link relationship between .text and .ARM.exidx will be discarded
470  // after merging sections, we have to build the exception handling section
471  // mapping before section merge.
472  m_pExData = ARMExData::create(pModule);
473}
474
475/// postMergeSections - hooks to be executed after merging sections
476void ARMGNULDBackend::postMergeSections(Module& pModule) {
477  if (m_pEXIDX->hasSectionData()) {
478    // Append the NullFragment so that __exidx_end can be correctly inserted.
479    NullFragment* null = new NullFragment(m_pEXIDX->getSectionData());
480    null->setOffset(m_pEXIDX->size());
481  }
482}
483
484bool ARMGNULDBackend::mergeSection(Module& pModule,
485                                   const Input& pInput,
486                                   LDSection& pSection) {
487  switch (pSection.type()) {
488    case llvm::ELF::SHT_ARM_ATTRIBUTES: {
489      return attribute().merge(pInput, pSection);
490    }
491
492    case llvm::ELF::SHT_ARM_EXIDX: {
493      assert(pSection.getLink() != NULL);
494      if ((pSection.getLink()->kind() == LDFileFormat::Ignore) ||
495          (pSection.getLink()->kind() == LDFileFormat::Folded)) {
496        // if the target section of the .ARM.exidx is Ignore, then it should be
497        // ignored as well
498        pSection.setKind(LDFileFormat::Ignore);
499        return true;
500      }
501
502      if (!m_pEXIDX->hasSectionData()) {
503        // Create SectionData for m_pEXIDX.
504        SectionData* sectData = IRBuilder::CreateSectionData(*m_pEXIDX);
505
506        // Initialize the alignment of m_pEXIDX.
507        const size_t alignExIdx = 4;
508        m_pEXIDX->setAlign(alignExIdx);
509
510        // Insert an AlignFragment to the beginning of m_pEXIDX.
511        AlignFragment* frag =
512            new AlignFragment(/*alignment*/alignExIdx,
513                              /*the filled value*/0x0,
514                              /*the size of filled value*/1u,
515                              /*max bytes to emit*/alignExIdx - 1);
516        frag->setOffset(0);
517        frag->setParent(sectData);
518        sectData->getFragmentList().push_back(frag);
519        m_pEXIDX->setSize(frag->size());
520      }
521
522      // Move RegionFragment from pSection to m_pEXIDX.
523      uint64_t offset = m_pEXIDX->size();
524      SectionData::FragmentListType& src =
525          pSection.getSectionData()->getFragmentList();
526      SectionData::FragmentListType& dst =
527          m_pEXIDX->getSectionData()->getFragmentList();
528      SectionData::FragmentListType::iterator frag = src.begin();
529      SectionData::FragmentListType::iterator fragEnd = src.end();
530      while (frag != fragEnd) {
531        if (frag->getKind() != Fragment::Region) {
532          ++frag;
533        } else {
534          frag->setParent(m_pEXIDX->getSectionData());
535          frag->setOffset(offset);
536          offset += frag->size();
537          dst.splice(dst.end(), src, frag++);
538        }
539      }
540
541      // Update the size of m_pEXIDX.
542      m_pEXIDX->setSize(offset);
543      return true;
544    }
545
546    default: {
547      ObjectBuilder builder(pModule);
548      builder.MergeSection(pInput, pSection);
549      return true;
550    }
551  }  // end of switch
552  return true;
553}
554
555void ARMGNULDBackend::setUpReachedSectionsForGC(
556    const Module& pModule,
557    GarbageCollection::SectionReachedListMap& pSectReachedListMap) const {
558  // traverse all the input relocations to find the relocation sections applying
559  // .ARM.exidx sections
560  Module::const_obj_iterator input, inEnd = pModule.obj_end();
561  for (input = pModule.obj_begin(); input != inEnd; ++input) {
562    LDContext::const_sect_iterator rs,
563        rsEnd = (*input)->context()->relocSectEnd();
564    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
565      // bypass the discarded relocation section
566      // 1. its section kind is changed to Ignore. (The target section is a
567      // discarded group section.)
568      // 2. it has no reloc data. (All symbols in the input relocs are in the
569      // discarded group sections)
570      LDSection* reloc_sect = *rs;
571      LDSection* apply_sect = reloc_sect->getLink();
572      if ((LDFileFormat::Ignore == reloc_sect->kind()) ||
573          (!reloc_sect->hasRelocData()))
574        continue;
575
576      if (llvm::ELF::SHT_ARM_EXIDX == apply_sect->type()) {
577        // 1. set up the reference according to relocations
578        bool add_first = false;
579        GarbageCollection::SectionListTy* reached_sects = NULL;
580        RelocData::iterator reloc_it, rEnd = reloc_sect->getRelocData()->end();
581        for (reloc_it = reloc_sect->getRelocData()->begin(); reloc_it != rEnd;
582             ++reloc_it) {
583          Relocation* reloc = llvm::cast<Relocation>(reloc_it);
584          ResolveInfo* sym = reloc->symInfo();
585          // only the target symbols defined in the input fragments can make the
586          // reference
587          if (sym == NULL)
588            continue;
589          if (!sym->isDefine() || !sym->outSymbol()->hasFragRef())
590            continue;
591
592          // only the target symbols defined in the concerned sections can make
593          // the reference
594          const LDSection* target_sect =
595              &sym->outSymbol()->fragRef()->frag()->getParent()->getSection();
596          if (target_sect->kind() != LDFileFormat::TEXT &&
597              target_sect->kind() != LDFileFormat::DATA &&
598              target_sect->kind() != LDFileFormat::BSS)
599            continue;
600
601          // setup the reached list, if we first add the element to reached list
602          // of this section, create an entry in ReachedSections map
603          if (!add_first) {
604            reached_sects = &pSectReachedListMap.getReachedList(*apply_sect);
605            add_first = true;
606          }
607          reached_sects->insert(target_sect);
608        }
609        reached_sects = NULL;
610        add_first = false;
611        // 2. set up the reference from XXX to .ARM.exidx.XXX
612        assert(apply_sect->getLink() != NULL);
613        pSectReachedListMap.addReference(*apply_sect->getLink(), *apply_sect);
614      }
615    }
616  }
617}
618
619bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD) {
620  Fragment* frag = NULL;
621  uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
622  uint32_t size = pSD.getSection().size();
623
624  llvm::StringRef region = pInput.memArea()->request(offset, size);
625  if (region.size() == 0) {
626    // If the input section's size is zero, we got a NULL region.
627    // use a virtual fill fragment
628    frag = new FillFragment(0x0, 0, 0);
629  } else {
630    frag = new RegionFragment(region);
631  }
632
633  ObjectBuilder::AppendFragment(*frag, pSD);
634  return true;
635}
636
637ARMGOT& ARMGNULDBackend::getGOT() {
638  assert(m_pGOT != NULL && "GOT section not exist");
639  return *m_pGOT;
640}
641
642const ARMGOT& ARMGNULDBackend::getGOT() const {
643  assert(m_pGOT != NULL && "GOT section not exist");
644  return *m_pGOT;
645}
646
647ARMPLT& ARMGNULDBackend::getPLT() {
648  assert(m_pPLT != NULL && "PLT section not exist");
649  return *m_pPLT;
650}
651
652const ARMPLT& ARMGNULDBackend::getPLT() const {
653  assert(m_pPLT != NULL && "PLT section not exist");
654  return *m_pPLT;
655}
656
657OutputRelocSection& ARMGNULDBackend::getRelDyn() {
658  assert(m_pRelDyn != NULL && ".rel.dyn section not exist");
659  return *m_pRelDyn;
660}
661
662const OutputRelocSection& ARMGNULDBackend::getRelDyn() const {
663  assert(m_pRelDyn != NULL && ".rel.dyn section not exist");
664  return *m_pRelDyn;
665}
666
667OutputRelocSection& ARMGNULDBackend::getRelPLT() {
668  assert(m_pRelPLT != NULL && ".rel.plt section not exist");
669  return *m_pRelPLT;
670}
671
672const OutputRelocSection& ARMGNULDBackend::getRelPLT() const {
673  assert(m_pRelPLT != NULL && ".rel.plt section not exist");
674  return *m_pRelPLT;
675}
676
677ARMELFAttributeData& ARMGNULDBackend::getAttributeData() {
678  assert(m_pAttrData != NULL && ".ARM.attributes section not exist");
679  return *m_pAttrData;
680}
681
682const ARMELFAttributeData& ARMGNULDBackend::getAttributeData() const {
683  assert(m_pAttrData != NULL && ".ARM.attributes section not exist");
684  return *m_pAttrData;
685}
686
687unsigned int ARMGNULDBackend::getTargetSectionOrder(
688    const LDSection& pSectHdr) const {
689  const ELFFileFormat* file_format = getOutputFormat();
690
691  if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) {
692    if (config().options().hasNow())
693      return SHO_RELRO_LAST;
694    return SHO_DATA;
695  }
696
697  if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
698    return SHO_PLT;
699
700  if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) {
701    // put ARM.exidx and ARM.extab in the same order of .eh_frame
702    return SHO_EXCEPTION;
703  }
704
705  return SHO_UNDEFINED;
706}
707
708void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) {
709  if (!m_pEXIDX->hasSectionData()) {
710    // Return if this is empty section.
711    return;
712  }
713
714  SectionData* sectData = m_pEXIDX->getSectionData();
715  SectionData::FragmentListType& list = sectData->getFragmentList();
716
717  // Move the first fragment (align fragment) and last fragment (null fragment)
718  // to temporary list because we would only like to sort the region fragment.
719  SectionData::FragmentListType tmp;
720  {
721    SectionData::iterator first = sectData->begin();
722    SectionData::iterator last = sectData->end();
723    --last;
724
725    assert(first->getKind() == Fragment::Alignment);
726    assert(last->getKind() == Fragment::Null);
727
728    tmp.splice(tmp.end(), list, first);
729    tmp.splice(tmp.end(), list, last);
730  }
731
732  // Sort the region fragments in the .ARM.exidx output section.
733  sort(list, ExIdxFragmentComparator(*m_pExData));
734
735  // Fix the coverage of the .ARM.exidx table.
736  llvm::StringRef cantUnwindRegion(g_CantUnwindEntry,
737                                   sizeof(g_CantUnwindEntry));
738
739  SectionData::FragmentListType::iterator it = list.begin();
740  if (it != list.end()) {
741    Fragment* prevTextFrag = m_pExData->getTupleByExIdx(&*it)->getTextFragment();
742    uint64_t prevTextEnd = prevTextFrag->getParent()->getSection().addr() +
743                           prevTextFrag->getOffset() +
744                           prevTextFrag->size();
745    ++it;
746    while (it != list.end()) {
747      Fragment* currTextFrag =
748          m_pExData->getTupleByExIdx(&*it)->getTextFragment();
749      uint64_t currTextBegin = currTextFrag->getParent()->getSection().addr() +
750                               currTextFrag->getOffset();
751
752      if (currTextBegin > prevTextEnd) {
753        // Found a gap. Insert a can't unwind entry.
754        RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr);
755        frag->setParent(sectData);
756        list.insert(it, frag);
757
758        // Add PREL31 reference to the beginning of the uncovered region.
759        Relocation* reloc =
760            Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31),
761                               *FragmentRef::Create(*frag, /* pOffset */0),
762                               /* pAddend */0);
763        reloc->setSymInfo(
764            CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag));
765        addExtraRelocation(reloc);
766      }
767
768      prevTextEnd = currTextBegin + currTextFrag->size();
769      prevTextFrag = currTextFrag;
770      ++it;
771    }
772
773    // Add a can't unwind entry to terminate .ARM.exidx section.
774    RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr);
775    frag->setParent(sectData);
776    list.push_back(frag);
777
778    // Add PREL31 reference to the end of the .text section.
779    Relocation* reloc =
780        Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31),
781                           *FragmentRef::Create(*frag, /* pOffset */0),
782                           /* pAddend */0);
783    reloc->setSymInfo(CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag));
784    addExtraRelocation(reloc);
785  }
786
787  // Add the first and the last fragment back.
788  list.splice(list.begin(), tmp, tmp.begin());
789  list.splice(list.end(), tmp, tmp.begin());
790
791  // Update the fragment offsets.
792  uint64_t offset = 0;
793  for (SectionData::iterator it = sectData->begin(), end = sectData->end();
794       it != end; ++it) {
795    it->setOffset(offset);
796    offset += it->size();
797  }
798
799  // Update the section size.
800  m_pEXIDX->setSize(offset);
801
802  // Rebuild the section header.
803  setOutputSectionAddress(pModule);
804}
805
806/// relax - the relaxation pass
807bool ARMGNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) {
808  if (!GNULDBackend::relax(pModule, pBuilder)) {
809    return false;
810  }
811  rewriteARMExIdxSection(pModule);
812  return true;
813}
814
815/// doRelax
816bool ARMGNULDBackend::doRelax(Module& pModule,
817                              IRBuilder& pBuilder,
818                              bool& pFinished) {
819  assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
820
821  bool isRelaxed = false;
822  ELFFileFormat* file_format = getOutputFormat();
823  // check branch relocs and create the related stubs if needed
824  Module::obj_iterator input, inEnd = pModule.obj_end();
825  for (input = pModule.obj_begin(); input != inEnd; ++input) {
826    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
827    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
828      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
829        continue;
830      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
831      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
832        Relocation* relocation = llvm::cast<Relocation>(reloc);
833
834        switch (relocation->type()) {
835          case llvm::ELF::R_ARM_PC24:
836          case llvm::ELF::R_ARM_CALL:
837          case llvm::ELF::R_ARM_JUMP24:
838          case llvm::ELF::R_ARM_PLT32:
839          case llvm::ELF::R_ARM_THM_CALL:
840          case llvm::ELF::R_ARM_THM_XPC22:
841          case llvm::ELF::R_ARM_THM_JUMP24:
842          case llvm::ELF::R_ARM_THM_JUMP19: {
843            // calculate the possible symbol value
844            uint64_t sym_value = 0x0;
845            LDSymbol* symbol = relocation->symInfo()->outSymbol();
846            if (symbol->hasFragRef()) {
847              uint64_t value = symbol->fragRef()->getOutputOffset();
848              uint64_t addr =
849                  symbol->fragRef()->frag()->getParent()->getSection().addr();
850              sym_value = addr + value;
851            }
852            if ((relocation->symInfo()->reserved() &
853                 ARMRelocator::ReservePLT) != 0x0) {
854              // FIXME: we need to find out the address of the specific plt
855              // entry
856              assert(file_format->hasPLT());
857              sym_value = file_format->getPLT().addr();
858            }
859            Stub* stub = getStubFactory()->create(*relocation,  // relocation
860                                                  sym_value,    // symbol value
861                                                  pBuilder,
862                                                  *getBRIslandFactory());
863            if (stub != NULL) {
864              assert(stub->symInfo() != NULL);
865              // reset the branch target of the reloc to this stub instead
866              relocation->setSymInfo(stub->symInfo());
867
868              switch (config().options().getStripSymbolMode()) {
869                case GeneralOptions::StripSymbolMode::StripAllSymbols:
870                case GeneralOptions::StripSymbolMode::StripLocals:
871                  break;
872                default: {
873                  // a stub symbol should be local
874                  assert(stub->symInfo() != NULL && stub->symInfo()->isLocal());
875                  LDSection& symtab = file_format->getSymTab();
876                  LDSection& strtab = file_format->getStrTab();
877
878                  // increase the size of .symtab and .strtab if needed
879                  symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
880                  symtab.setInfo(symtab.getInfo() + 1);
881                  strtab.setSize(strtab.size() + stub->symInfo()->nameSize() +
882                                 1);
883                }
884              }  // end of switch
885              isRelaxed = true;
886            }
887            break;
888          }
889          case llvm::ELF::R_ARM_V4BX:
890            /* FIXME: bypass R_ARM_V4BX relocation now */
891            break;
892          default:
893            break;
894        }  // end of switch
895      }  // for all relocations
896    }  // for all relocation section
897  }  // for all inputs
898
899  // find the first fragment w/ invalid offset due to stub insertion
900  std::vector<Fragment*> invalid_frags;
901  pFinished = true;
902  for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
903                                     island_end = getBRIslandFactory()->end();
904       island != island_end;
905       ++island) {
906    if ((*island).size() > stubGroupSize()) {
907      error(diag::err_no_space_to_place_stubs) << stubGroupSize();
908      return false;
909    }
910
911    if ((*island).numOfStubs() == 0) {
912      continue;
913    }
914
915    Fragment* exit = &*(*island).end();
916    if (exit == (*island).begin()->getParent()->end()) {
917      continue;
918    }
919
920    if (((*island).offset() + (*island).size()) > exit->getOffset()) {
921      if (invalid_frags.empty() ||
922          (invalid_frags.back()->getParent() != (*island).getParent())) {
923        invalid_frags.push_back(exit);
924        pFinished = false;
925      }
926      continue;
927    }
928  }
929
930  // reset the offset of invalid fragments
931  for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie;
932       ++it) {
933    Fragment* invalid = *it;
934    while (invalid != NULL) {
935      invalid->setOffset(invalid->getPrevNode()->getOffset() +
936                         invalid->getPrevNode()->size());
937      invalid = invalid->getNextNode();
938    }
939  }
940
941  // reset the size of section that has stubs inserted.
942  if (isRelaxed) {
943    SectionData* prev = NULL;
944    for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
945                                       island_end = getBRIslandFactory()->end();
946         island != island_end;
947         ++island) {
948      SectionData* sd = (*island).begin()->getParent();
949      if ((*island).numOfStubs() != 0) {
950        if (sd != prev) {
951          sd->getSection().setSize(sd->back().getOffset() + sd->back().size());
952        }
953      }
954      prev = sd;
955    }
956  }
957  return isRelaxed;
958}
959
960/// initTargetStubs
961bool ARMGNULDBackend::initTargetStubs() {
962  if (getStubFactory() != NULL) {
963    getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep()));
964    getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep()));
965    getStubFactory()->addPrototype(
966        new THMToTHMStub(config().isCodeIndep(), m_pAttrData->usingThumb2()));
967    getStubFactory()->addPrototype(
968        new THMToARMStub(config().isCodeIndep(), m_pAttrData->usingThumb2()));
969    return true;
970  }
971  return false;
972}
973
974/// maxFwdBranchOffset
975int64_t ARMGNULDBackend::maxFwdBranchOffset() const {
976  if (m_pAttrData->usingThumb2()) {
977    return THM2_MAX_FWD_BRANCH_OFFSET;
978  } else {
979    return THM_MAX_FWD_BRANCH_OFFSET;
980  }
981}
982
983/// maxBwdBranchOffset
984int64_t ARMGNULDBackend::maxBwdBranchOffset() const {
985  if (m_pAttrData->usingThumb2()) {
986    return THM2_MAX_BWD_BRANCH_OFFSET;
987  } else {
988    return THM_MAX_BWD_BRANCH_OFFSET;
989  }
990}
991
992/// doCreateProgramHdrs - backend can implement this function to create the
993/// target-dependent segments
994void ARMGNULDBackend::doCreateProgramHdrs(Module& pModule) {
995  if (m_pEXIDX != NULL && m_pEXIDX->size() != 0x0) {
996    // make PT_ARM_EXIDX
997    ELFSegment* exidx_seg =
998        elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX, llvm::ELF::PF_R);
999    exidx_seg->append(m_pEXIDX);
1000  }
1001}
1002
1003/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
1004/// function pointer access
1005bool ARMGNULDBackend::mayHaveUnsafeFunctionPointerAccess(
1006    const LDSection& pSection) const {
1007  llvm::StringRef name(pSection.name());
1008  return !name.startswith(".ARM.exidx") && !name.startswith(".ARM.extab") &&
1009         GNULDBackend::mayHaveUnsafeFunctionPointerAccess(pSection);
1010}
1011
1012//===----------------------------------------------------------------------===//
1013/// createARMLDBackend - the help funtion to create corresponding ARMLDBackend
1014///
1015TargetLDBackend* createARMLDBackend(const LinkerConfig& pConfig) {
1016  if (pConfig.targets().triple().isOSDarwin()) {
1017    assert(0 && "MachO linker is not supported yet");
1018    /**
1019    return new ARMMachOLDBackend(createARMMachOArchiveReader,
1020                               createARMMachOObjectReader,
1021                               createARMMachOObjectWriter);
1022    **/
1023  }
1024  if (pConfig.targets().triple().isOSWindows()) {
1025    assert(0 && "COFF linker is not supported yet");
1026    /**
1027    return new ARMCOFFLDBackend(createARMCOFFArchiveReader,
1028                               createARMCOFFObjectReader,
1029                               createARMCOFFObjectWriter);
1030    **/
1031  }
1032  return new ARMGNULDBackend(pConfig,
1033                             new ARMGNUInfo(pConfig.targets().triple()));
1034}
1035
1036}  // namespace mcld
1037
1038//===----------------------------------------------------------------------===//
1039// Force static initialization.
1040//===----------------------------------------------------------------------===//
1041extern "C" void MCLDInitializeARMLDBackend() {
1042  // Register the linker backend
1043  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheARMTarget,
1044                                                mcld::createARMLDBackend);
1045  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheThumbTarget,
1046                                                mcld::createARMLDBackend);
1047}
1048