Home | History | Annotate | Download | only in ARM
      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 
     52 namespace mcld {
     53 
     54 /// Fragment data for EXIDX_CANTUNWIND.
     55 static 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.
     63 static mcld::ResolveInfo*
     64 CreateLocalSymbolToFragmentEnd(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.
     95 class 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 //===----------------------------------------------------------------------===//
    122 ARMGNULDBackend::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 
    139 ARMGNULDBackend::~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 
    149 void 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 
    197 void 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 
    266 bool ARMGNULDBackend::initRelocator() {
    267   if (m_pRelocator == NULL) {
    268     m_pRelocator = new ARMRelocator(*this, config());
    269   }
    270   return true;
    271 }
    272 
    273 const Relocator* ARMGNULDBackend::getRelocator() const {
    274   assert(m_pRelocator != NULL);
    275   return m_pRelocator;
    276 }
    277 
    278 Relocator* ARMGNULDBackend::getRelocator() {
    279   assert(m_pRelocator != NULL);
    280   return m_pRelocator;
    281 }
    282 
    283 void 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 
    325 void 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.
    352 ARMELFDynamic& 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.
    359 const ARMELFDynamic& ARMGNULDBackend::dynamic() const {
    360   assert(m_pDynamic != NULL);
    361   return *m_pDynamic;
    362 }
    363 
    364 void 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 
    389 uint64_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
    462 bool ARMGNULDBackend::finalizeTargetSymbols() {
    463   return true;
    464 }
    465 
    466 
    467 /// preMergeSections - hooks to be executed before merging sections
    468 void 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
    476 void 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 
    484 bool 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 
    555 void 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 
    619 bool 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 
    637 ARMGOT& ARMGNULDBackend::getGOT() {
    638   assert(m_pGOT != NULL && "GOT section not exist");
    639   return *m_pGOT;
    640 }
    641 
    642 const ARMGOT& ARMGNULDBackend::getGOT() const {
    643   assert(m_pGOT != NULL && "GOT section not exist");
    644   return *m_pGOT;
    645 }
    646 
    647 ARMPLT& ARMGNULDBackend::getPLT() {
    648   assert(m_pPLT != NULL && "PLT section not exist");
    649   return *m_pPLT;
    650 }
    651 
    652 const ARMPLT& ARMGNULDBackend::getPLT() const {
    653   assert(m_pPLT != NULL && "PLT section not exist");
    654   return *m_pPLT;
    655 }
    656 
    657 OutputRelocSection& ARMGNULDBackend::getRelDyn() {
    658   assert(m_pRelDyn != NULL && ".rel.dyn section not exist");
    659   return *m_pRelDyn;
    660 }
    661 
    662 const OutputRelocSection& ARMGNULDBackend::getRelDyn() const {
    663   assert(m_pRelDyn != NULL && ".rel.dyn section not exist");
    664   return *m_pRelDyn;
    665 }
    666 
    667 OutputRelocSection& ARMGNULDBackend::getRelPLT() {
    668   assert(m_pRelPLT != NULL && ".rel.plt section not exist");
    669   return *m_pRelPLT;
    670 }
    671 
    672 const OutputRelocSection& ARMGNULDBackend::getRelPLT() const {
    673   assert(m_pRelPLT != NULL && ".rel.plt section not exist");
    674   return *m_pRelPLT;
    675 }
    676 
    677 ARMELFAttributeData& ARMGNULDBackend::getAttributeData() {
    678   assert(m_pAttrData != NULL && ".ARM.attributes section not exist");
    679   return *m_pAttrData;
    680 }
    681 
    682 const ARMELFAttributeData& ARMGNULDBackend::getAttributeData() const {
    683   assert(m_pAttrData != NULL && ".ARM.attributes section not exist");
    684   return *m_pAttrData;
    685 }
    686 
    687 unsigned 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 
    708 void 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
    807 bool 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
    816 bool 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
    961 bool 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
    975 int64_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
    984 int64_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
    994 void 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
   1005 bool 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 ///
   1015 TargetLDBackend* 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 //===----------------------------------------------------------------------===//
   1041 extern "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