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 "ARMELFDynamic.h"
     12 #include "ARMLDBackend.h"
     13 #include "ARMRelocator.h"
     14 #include "ARMToARMStub.h"
     15 #include "ARMToTHMStub.h"
     16 #include "THMToTHMStub.h"
     17 #include "THMToARMStub.h"
     18 
     19 #include <cstring>
     20 
     21 #include <llvm/ADT/Triple.h>
     22 #include <llvm/ADT/Twine.h>
     23 #include <llvm/Support/ELF.h>
     24 #include <llvm/Support/Casting.h>
     25 
     26 #include <mcld/IRBuilder.h>
     27 #include <mcld/LinkerConfig.h>
     28 #include <mcld/Fragment/FillFragment.h>
     29 #include <mcld/Fragment/AlignFragment.h>
     30 #include <mcld/Fragment/RegionFragment.h>
     31 #include <mcld/Support/MemoryRegion.h>
     32 #include <mcld/Support/MemoryArea.h>
     33 #include <mcld/Support/MsgHandling.h>
     34 #include <mcld/Support/TargetRegistry.h>
     35 #include <mcld/Fragment/Stub.h>
     36 #include <mcld/LD/BranchIslandFactory.h>
     37 #include <mcld/LD/StubFactory.h>
     38 #include <mcld/Object/ObjectBuilder.h>
     39 #include <mcld/Fragment/NullFragment.h>
     40 #include <mcld/LD/LDContext.h>
     41 #include <mcld/Target/GNUInfo.h>
     42 
     43 using namespace mcld;
     44 
     45 //===----------------------------------------------------------------------===//
     46 // ARMGNULDBackend
     47 //===----------------------------------------------------------------------===//
     48 ARMGNULDBackend::ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo)
     49   : GNULDBackend(pConfig, pInfo),
     50     m_pRelocator(NULL),
     51     m_pGOT(NULL),
     52     m_pPLT(NULL),
     53     m_pRelDyn(NULL),
     54     m_pRelPLT(NULL),
     55     m_pDynamic(NULL),
     56     m_pGOTSymbol(NULL),
     57     m_pEXIDXStart(NULL),
     58     m_pEXIDXEnd(NULL),
     59     m_pEXIDX(NULL),
     60     m_pEXTAB(NULL),
     61     m_pAttributes(NULL) {
     62 }
     63 
     64 ARMGNULDBackend::~ARMGNULDBackend()
     65 {
     66   delete m_pRelocator;
     67   delete m_pGOT;
     68   delete m_pPLT;
     69   delete m_pRelDyn;
     70   delete m_pRelPLT;
     71   delete m_pDynamic;
     72 }
     73 
     74 void ARMGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
     75 {
     76  // FIXME: Currently we set exidx and extab to "Exception" and directly emit
     77  // them from input
     78   m_pEXIDX        = pBuilder.CreateSection(".ARM.exidx",
     79                                            LDFileFormat::Target,
     80                                            llvm::ELF::SHT_ARM_EXIDX,
     81                                            llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER,
     82                                            config().targets().bitclass() / 8);
     83   m_pEXTAB        = pBuilder.CreateSection(".ARM.extab",
     84                                            LDFileFormat::Target,
     85                                            llvm::ELF::SHT_PROGBITS,
     86                                            llvm::ELF::SHF_ALLOC,
     87                                            0x1);
     88   m_pAttributes   = pBuilder.CreateSection(".ARM.attributes",
     89                                            LDFileFormat::Target,
     90                                            llvm::ELF::SHT_ARM_ATTRIBUTES,
     91                                            0x0,
     92                                            0x1);
     93 
     94   if (LinkerConfig::Object != config().codeGenType()) {
     95     ELFFileFormat* file_format = getOutputFormat();
     96 
     97     // initialize .got
     98     LDSection& got = file_format->getGOT();
     99     m_pGOT = new ARMGOT(got);
    100 
    101     // initialize .plt
    102     LDSection& plt = file_format->getPLT();
    103     m_pPLT = new ARMPLT(plt, *m_pGOT);
    104 
    105     // initialize .rel.plt
    106     LDSection& relplt = file_format->getRelPlt();
    107     relplt.setLink(&plt);
    108     // create SectionData and ARMRelDynSection
    109     m_pRelPLT = new OutputRelocSection(pModule, relplt);
    110 
    111     // initialize .rel.dyn
    112     LDSection& reldyn = file_format->getRelDyn();
    113     m_pRelDyn = new OutputRelocSection(pModule, reldyn);
    114   }
    115 }
    116 
    117 void ARMGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
    118 {
    119   // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
    120   // same name in input
    121   m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    122                                                   "_GLOBAL_OFFSET_TABLE_",
    123                                                   ResolveInfo::Object,
    124                                                   ResolveInfo::Define,
    125                                                   ResolveInfo::Local,
    126                                                   0x0,  // size
    127                                                   0x0,  // value
    128                                                   FragmentRef::Null(),
    129                                                   ResolveInfo::Hidden);
    130   if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) {
    131     FragmentRef* exidx_start =
    132       FragmentRef::Create(m_pEXIDX->getSectionData()->front(), 0x0);
    133     FragmentRef* exidx_end =
    134       FragmentRef::Create(m_pEXIDX->getSectionData()->front(),
    135                           m_pEXIDX->size());
    136     m_pEXIDXStart =
    137       pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    138                                                     "__exidx_start",
    139                                                     ResolveInfo::Object,
    140                                                     ResolveInfo::Define,
    141                                                     ResolveInfo::Local,
    142                                                     0x0, // size
    143                                                     0x0, // value
    144                                                     exidx_start, // FragRef
    145                                                     ResolveInfo::Default);
    146 
    147     m_pEXIDXEnd =
    148       pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    149                                                     "__exidx_end",
    150                                                     ResolveInfo::Object,
    151                                                     ResolveInfo::Define,
    152                                                     ResolveInfo::Local,
    153                                                     0x0, // size
    154                                                     0x0, // value
    155                                                     exidx_end, // FragRef
    156                                                     ResolveInfo::Default);
    157     // change __exidx_start/_end to local dynamic category
    158     if (NULL != m_pEXIDXStart)
    159       pModule.getSymbolTable().changeLocalToDynamic(*m_pEXIDXStart);
    160     if (NULL != m_pEXIDXEnd)
    161       pModule.getSymbolTable().changeLocalToDynamic(*m_pEXIDXEnd);
    162   } else {
    163     m_pEXIDXStart =
    164       pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    165                                                     "__exidx_start",
    166                                                     ResolveInfo::NoType,
    167                                                     ResolveInfo::Define,
    168                                                     ResolveInfo::Absolute,
    169                                                     0x0, // size
    170                                                     0x0, // value
    171                                                     FragmentRef::Null(),
    172                                                     ResolveInfo::Default);
    173 
    174     m_pEXIDXEnd =
    175       pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    176                                                     "__exidx_end",
    177                                                     ResolveInfo::NoType,
    178                                                     ResolveInfo::Define,
    179                                                     ResolveInfo::Absolute,
    180                                                     0x0, // size
    181                                                     0x0, // value
    182                                                     FragmentRef::Null(),
    183                                                     ResolveInfo::Default);
    184   }
    185 }
    186 
    187 bool ARMGNULDBackend::initRelocator()
    188 {
    189   if (NULL == m_pRelocator) {
    190     m_pRelocator = new ARMRelocator(*this);
    191   }
    192   return true;
    193 }
    194 
    195 Relocator* ARMGNULDBackend::getRelocator()
    196 {
    197   assert(NULL != m_pRelocator);
    198   return m_pRelocator;
    199 }
    200 
    201 void ARMGNULDBackend::doPreLayout(IRBuilder& pBuilder)
    202 {
    203   // initialize .dynamic data
    204   if (!config().isCodeStatic() && NULL == m_pDynamic)
    205     m_pDynamic = new ARMELFDynamic(*this, config());
    206 
    207   // set .got size
    208   // when building shared object, the .got section is must
    209   if (LinkerConfig::Object != config().codeGenType()) {
    210     if (LinkerConfig::DynObj == config().codeGenType() ||
    211         m_pGOT->hasGOT1() ||
    212         NULL != m_pGOTSymbol) {
    213       m_pGOT->finalizeSectionSize();
    214       defineGOTSymbol(pBuilder);
    215     }
    216 
    217     // set .plt size
    218     if (m_pPLT->hasPLT1())
    219       m_pPLT->finalizeSectionSize();
    220 
    221     ELFFileFormat* file_format = getOutputFormat();
    222     // set .rel.dyn size
    223     if (!m_pRelDyn->empty()) {
    224       assert(!config().isCodeStatic() &&
    225             "static linkage should not result in a dynamic relocation section");
    226       file_format->getRelDyn().setSize(
    227                                   m_pRelDyn->numOfRelocs() * getRelEntrySize());
    228     }
    229 
    230     // set .rel.plt size
    231     if (!m_pRelPLT->empty()) {
    232       assert(!config().isCodeStatic() &&
    233             "static linkage should not result in a dynamic relocation section");
    234       file_format->getRelPlt().setSize(
    235                                   m_pRelPLT->numOfRelocs() * getRelEntrySize());
    236     }
    237   }
    238 }
    239 
    240 void ARMGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
    241 {
    242   const ELFFileFormat *file_format = getOutputFormat();
    243 
    244   // apply PLT
    245   if (file_format->hasPLT()) {
    246     // Since we already have the size of LDSection PLT, m_pPLT should not be
    247     // NULL.
    248     assert(NULL != m_pPLT);
    249     m_pPLT->applyPLT0();
    250     m_pPLT->applyPLT1();
    251   }
    252 
    253   // apply GOT
    254   if (file_format->hasGOT()) {
    255     // Since we already have the size of GOT, m_pGOT should not be NULL.
    256     assert(NULL != m_pGOT);
    257     if (LinkerConfig::DynObj == config().codeGenType())
    258       m_pGOT->applyGOT0(file_format->getDynamic().addr());
    259     else {
    260       // executable file and object file? should fill with zero.
    261       m_pGOT->applyGOT0(0);
    262     }
    263   }
    264 }
    265 
    266 /// dynamic - the dynamic section of the target machine.
    267 /// Use co-variant return type to return its own dynamic section.
    268 ARMELFDynamic& ARMGNULDBackend::dynamic()
    269 {
    270   assert(NULL != m_pDynamic);
    271   return *m_pDynamic;
    272 }
    273 
    274 /// dynamic - the dynamic section of the target machine.
    275 /// Use co-variant return type to return its own dynamic section.
    276 const ARMELFDynamic& ARMGNULDBackend::dynamic() const
    277 {
    278   assert(NULL != m_pDynamic);
    279   return *m_pDynamic;
    280 }
    281 
    282 void ARMGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder)
    283 {
    284   // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
    285   if (m_pGOTSymbol != NULL) {
    286     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
    287                      "_GLOBAL_OFFSET_TABLE_",
    288                      ResolveInfo::Object,
    289                      ResolveInfo::Define,
    290                      ResolveInfo::Local,
    291                      0x0, // size
    292                      0x0, // value
    293                      FragmentRef::Create(*(m_pGOT->begin()), 0x0),
    294                      ResolveInfo::Hidden);
    295   }
    296   else {
    297     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    298                      "_GLOBAL_OFFSET_TABLE_",
    299                      ResolveInfo::Object,
    300                      ResolveInfo::Define,
    301                      ResolveInfo::Local,
    302                      0x0, // size
    303                      0x0, // value
    304                      FragmentRef::Create(*(m_pGOT->begin()), 0x0),
    305                      ResolveInfo::Hidden);
    306   }
    307 
    308 }
    309 
    310 void ARMGNULDBackend::addCopyReloc(ResolveInfo& pSym)
    311 {
    312   Relocation& rel_entry = *m_pRelDyn->consumeEntry();
    313   rel_entry.setType(llvm::ELF::R_ARM_COPY);
    314   assert(pSym.outSymbol()->hasFragRef());
    315   rel_entry.targetRef().assign(*pSym.outSymbol()->fragRef());
    316   rel_entry.setSymInfo(&pSym);
    317 }
    318 
    319 /// defineSymbolForCopyReloc
    320 /// For a symbol needing copy relocation, define a copy symbol in the BSS
    321 /// section and all other reference to this symbol should refer to this
    322 /// copy.
    323 /// This is executed at scan relocation stage.
    324 LDSymbol&
    325 ARMGNULDBackend::defineSymbolforCopyReloc(IRBuilder& pBuilder,
    326                                           const ResolveInfo& pSym)
    327 {
    328   // get or create corresponding BSS LDSection
    329   LDSection* bss_sect_hdr = NULL;
    330   ELFFileFormat* file_format = getOutputFormat();
    331   if (ResolveInfo::ThreadLocal == pSym.type())
    332     bss_sect_hdr = &file_format->getTBSS();
    333   else
    334     bss_sect_hdr = &file_format->getBSS();
    335 
    336   // get or create corresponding BSS SectionData
    337   SectionData* bss_data = NULL;
    338   if (bss_sect_hdr->hasSectionData())
    339     bss_data = bss_sect_hdr->getSectionData();
    340   else
    341     bss_data = IRBuilder::CreateSectionData(*bss_sect_hdr);
    342 
    343   // Determine the alignment by the symbol value
    344   // FIXME: here we use the largest alignment
    345   uint32_t addralign = config().targets().bitclass() / 8;
    346 
    347   // allocate space in BSS for the copy symbol
    348   Fragment* frag = new FillFragment(0x0, 1, pSym.size());
    349   uint64_t size = ObjectBuilder::AppendFragment(*frag,
    350                                                 *bss_data,
    351                                                 addralign);
    352   bss_sect_hdr->setSize(bss_sect_hdr->size() + size);
    353 
    354   // change symbol binding to Global if it's a weak symbol
    355   ResolveInfo::Binding binding = (ResolveInfo::Binding)pSym.binding();
    356   if (binding == ResolveInfo::Weak)
    357     binding = ResolveInfo::Global;
    358 
    359   // Define the copy symbol in the bss section and resolve it
    360   LDSymbol* cpy_sym = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    361                       pSym.name(),
    362                       (ResolveInfo::Type)pSym.type(),
    363                       ResolveInfo::Define,
    364                       binding,
    365                       pSym.size(),  // size
    366                       0x0,          // value
    367                       FragmentRef::Create(*frag, 0x0),
    368                       (ResolveInfo::Visibility)pSym.other());
    369 
    370   return *cpy_sym;
    371 }
    372 
    373 /// checkValidReloc - When we attempt to generate a dynamic relocation for
    374 /// ouput file, check if the relocation is supported by dynamic linker.
    375 void ARMGNULDBackend::checkValidReloc(Relocation& pReloc) const
    376 {
    377   // If not PIC object, no relocation type is invalid
    378   if (!config().isCodeIndep())
    379     return;
    380 
    381   switch(pReloc.type()) {
    382     case llvm::ELF::R_ARM_RELATIVE:
    383     case llvm::ELF::R_ARM_COPY:
    384     case llvm::ELF::R_ARM_GLOB_DAT:
    385     case llvm::ELF::R_ARM_JUMP_SLOT:
    386     case llvm::ELF::R_ARM_ABS32:
    387     case llvm::ELF::R_ARM_ABS32_NOI:
    388     case llvm::ELF::R_ARM_PC24:
    389     case llvm::ELF::R_ARM_TLS_DTPMOD32:
    390     case llvm::ELF::R_ARM_TLS_DTPOFF32:
    391     case llvm::ELF::R_ARM_TLS_TPOFF32:
    392       break;
    393 
    394     default:
    395       error(diag::non_pic_relocation) << (int)pReloc.type()
    396                                       << pReloc.symInfo()->name();
    397       break;
    398   }
    399 }
    400 
    401 void
    402 ARMGNULDBackend::scanLocalReloc(Relocation& pReloc, const LDSection& pSection)
    403 {
    404   // rsym - The relocation target symbol
    405   ResolveInfo* rsym = pReloc.symInfo();
    406 
    407   switch(pReloc.type()){
    408 
    409     // Set R_ARM_TARGET1 to R_ARM_ABS32
    410     // Ref: GNU gold 1.11 arm.cc, line 9892
    411     // FIXME: R_ARM_TARGET1 should be set by option --target1-rel
    412     // or --target1-rel
    413     case llvm::ELF::R_ARM_TARGET1:
    414        pReloc.setType(llvm::ELF::R_ARM_ABS32);
    415     case llvm::ELF::R_ARM_ABS32:
    416     case llvm::ELF::R_ARM_ABS32_NOI: {
    417       // If buiding PIC object (shared library or PIC executable),
    418       // a dynamic relocations with RELATIVE type to this location is needed.
    419       // Reserve an entry in .rel.dyn
    420       if (config().isCodeIndep()) {
    421         m_pRelDyn->reserveEntry();
    422         // set Rel bit
    423         rsym->setReserved(rsym->reserved() | ReserveRel);
    424         checkAndSetHasTextRel(*pSection.getLink());
    425       }
    426       return;
    427     }
    428 
    429     case llvm::ELF::R_ARM_ABS16:
    430     case llvm::ELF::R_ARM_ABS12:
    431     case llvm::ELF::R_ARM_THM_ABS5:
    432     case llvm::ELF::R_ARM_ABS8:
    433     case llvm::ELF::R_ARM_BASE_ABS:
    434     case llvm::ELF::R_ARM_MOVW_ABS_NC:
    435     case llvm::ELF::R_ARM_MOVT_ABS:
    436     case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
    437     case llvm::ELF::R_ARM_THM_MOVT_ABS: {
    438       // PIC code should not contain these kinds of relocation
    439       if (config().isCodeIndep()) {
    440         error(diag::non_pic_relocation) << (int)pReloc.type()
    441                                         << pReloc.symInfo()->name();
    442       }
    443       return;
    444     }
    445     case llvm::ELF::R_ARM_GOTOFF32:
    446     case llvm::ELF::R_ARM_GOTOFF12: {
    447       // FIXME: A GOT section is needed
    448       return;
    449     }
    450 
    451     // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
    452     // Ref: GNU gold 1.11 arm.cc, line 9892
    453     // FIXME: R_ARM_TARGET2 should be set by option --target2
    454     case llvm::ELF::R_ARM_TARGET2:
    455       pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
    456     case llvm::ELF::R_ARM_GOT_BREL:
    457     case llvm::ELF::R_ARM_GOT_PREL: {
    458       // A GOT entry is needed for these relocation type.
    459       // return if we already create GOT for this symbol
    460       if (rsym->reserved() & (ReserveGOT | GOTRel))
    461         return;
    462       m_pGOT->reserveGOT();
    463       // If building PIC object, a dynamic relocation with
    464       // type RELATIVE is needed to relocate this GOT entry.
    465       // Reserve an entry in .rel.dyn
    466       if (config().isCodeIndep()) {
    467         // create .rel.dyn section if not exist
    468         m_pRelDyn->reserveEntry();
    469         // set GOTRel bit
    470         rsym->setReserved(rsym->reserved() | 0x4u);
    471         return;
    472       }
    473       // set GOT bit
    474       rsym->setReserved(rsym->reserved() | 0x2u);
    475       return;
    476     }
    477 
    478     case llvm::ELF::R_ARM_BASE_PREL: {
    479       // FIXME: Currently we only support R_ARM_BASE_PREL against
    480       // symbol _GLOBAL_OFFSET_TABLE_
    481       if (rsym != m_pGOTSymbol->resolveInfo())
    482         fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name()
    483                                      << "mclinker (at) googlegroups.com";
    484       return;
    485     }
    486     case llvm::ELF::R_ARM_COPY:
    487     case llvm::ELF::R_ARM_GLOB_DAT:
    488     case llvm::ELF::R_ARM_JUMP_SLOT:
    489     case llvm::ELF::R_ARM_RELATIVE: {
    490       // These are relocation type for dynamic linker, shold not
    491       // appear in object file.
    492       fatal(diag::dynamic_relocation) << (int)pReloc.type();
    493       break;
    494     }
    495     default: {
    496       break;
    497     }
    498   } // end switch
    499 }
    500 
    501 void ARMGNULDBackend::scanGlobalReloc(Relocation& pReloc,
    502                                       IRBuilder& pBuilder,
    503                                       const LDSection& pSection)
    504 {
    505   // rsym - The relocation target symbol
    506   ResolveInfo* rsym = pReloc.symInfo();
    507 
    508   switch(pReloc.type()) {
    509 
    510     // Set R_ARM_TARGET1 to R_ARM_ABS32
    511     // Ref: GNU gold 1.11 arm.cc, line 9892
    512     // FIXME: R_ARM_TARGET1 should be set by option --target1-rel
    513     // or --target1-rel
    514     case llvm::ELF::R_ARM_TARGET1:
    515       pReloc.setType(llvm::ELF::R_ARM_ABS32);
    516     case llvm::ELF::R_ARM_ABS32:
    517     case llvm::ELF::R_ARM_ABS16:
    518     case llvm::ELF::R_ARM_ABS12:
    519     case llvm::ELF::R_ARM_THM_ABS5:
    520     case llvm::ELF::R_ARM_ABS8:
    521     case llvm::ELF::R_ARM_BASE_ABS:
    522     case llvm::ELF::R_ARM_MOVW_ABS_NC:
    523     case llvm::ELF::R_ARM_MOVT_ABS:
    524     case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
    525     case llvm::ELF::R_ARM_THM_MOVT_ABS:
    526     case llvm::ELF::R_ARM_ABS32_NOI: {
    527       // Absolute relocation type, symbol may needs PLT entry or
    528       // dynamic relocation entry
    529       if (symbolNeedsPLT(*rsym)) {
    530         // create plt for this symbol if it does not have one
    531         if (!(rsym->reserved() & ReservePLT)){
    532           // Symbol needs PLT entry, we need to reserve a PLT entry
    533           // and the corresponding GOT and dynamic relocation entry
    534           // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    535           // when calling ARMPLT->reserveEntry())
    536           m_pPLT->reserveEntry();
    537           m_pRelPLT->reserveEntry();
    538           // set PLT bit
    539           rsym->setReserved(rsym->reserved() | ReservePLT);
    540         }
    541       }
    542 
    543       if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), true)) {
    544         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
    545         m_pRelDyn->reserveEntry();
    546         if (symbolNeedsCopyReloc(pReloc, *rsym)) {
    547           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
    548           addCopyReloc(*cpy_sym.resolveInfo());
    549         }
    550         else {
    551           checkValidReloc(pReloc);
    552           // set Rel bit
    553           rsym->setReserved(rsym->reserved() | ReserveRel);
    554           checkAndSetHasTextRel(*pSection.getLink());
    555         }
    556       }
    557       return;
    558     }
    559 
    560     case llvm::ELF::R_ARM_GOTOFF32:
    561     case llvm::ELF::R_ARM_GOTOFF12: {
    562       // FIXME: A GOT section is needed
    563       return;
    564     }
    565 
    566     case llvm::ELF::R_ARM_BASE_PREL:
    567     case llvm::ELF::R_ARM_THM_MOVW_BREL_NC:
    568     case llvm::ELF::R_ARM_THM_MOVW_BREL:
    569     case llvm::ELF::R_ARM_THM_MOVT_BREL:
    570       // FIXME: Currently we only support these relocations against
    571       // symbol _GLOBAL_OFFSET_TABLE_
    572       if (rsym != m_pGOTSymbol->resolveInfo()) {
    573         fatal(diag::base_relocation) << (int)pReloc.type() << rsym->name()
    574                                      << "mclinker (at) googlegroups.com";
    575       }
    576     case llvm::ELF::R_ARM_REL32:
    577     case llvm::ELF::R_ARM_LDR_PC_G0:
    578     case llvm::ELF::R_ARM_SBREL32:
    579     case llvm::ELF::R_ARM_THM_PC8:
    580     case llvm::ELF::R_ARM_MOVW_PREL_NC:
    581     case llvm::ELF::R_ARM_MOVT_PREL:
    582     case llvm::ELF::R_ARM_THM_MOVW_PREL_NC:
    583     case llvm::ELF::R_ARM_THM_MOVT_PREL:
    584     case llvm::ELF::R_ARM_THM_ALU_PREL_11_0:
    585     case llvm::ELF::R_ARM_THM_PC12:
    586     case llvm::ELF::R_ARM_REL32_NOI:
    587     case llvm::ELF::R_ARM_ALU_PC_G0_NC:
    588     case llvm::ELF::R_ARM_ALU_PC_G0:
    589     case llvm::ELF::R_ARM_ALU_PC_G1_NC:
    590     case llvm::ELF::R_ARM_ALU_PC_G1:
    591     case llvm::ELF::R_ARM_ALU_PC_G2:
    592     case llvm::ELF::R_ARM_LDR_PC_G1:
    593     case llvm::ELF::R_ARM_LDR_PC_G2:
    594     case llvm::ELF::R_ARM_LDRS_PC_G0:
    595     case llvm::ELF::R_ARM_LDRS_PC_G1:
    596     case llvm::ELF::R_ARM_LDRS_PC_G2:
    597     case llvm::ELF::R_ARM_LDC_PC_G0:
    598     case llvm::ELF::R_ARM_LDC_PC_G1:
    599     case llvm::ELF::R_ARM_LDC_PC_G2:
    600     case llvm::ELF::R_ARM_ALU_SB_G0_NC:
    601     case llvm::ELF::R_ARM_ALU_SB_G0:
    602     case llvm::ELF::R_ARM_ALU_SB_G1_NC:
    603     case llvm::ELF::R_ARM_ALU_SB_G1:
    604     case llvm::ELF::R_ARM_ALU_SB_G2:
    605     case llvm::ELF::R_ARM_LDR_SB_G0:
    606     case llvm::ELF::R_ARM_LDR_SB_G1:
    607     case llvm::ELF::R_ARM_LDR_SB_G2:
    608     case llvm::ELF::R_ARM_LDRS_SB_G0:
    609     case llvm::ELF::R_ARM_LDRS_SB_G1:
    610     case llvm::ELF::R_ARM_LDRS_SB_G2:
    611     case llvm::ELF::R_ARM_LDC_SB_G0:
    612     case llvm::ELF::R_ARM_LDC_SB_G1:
    613     case llvm::ELF::R_ARM_LDC_SB_G2:
    614     case llvm::ELF::R_ARM_MOVW_BREL_NC:
    615     case llvm::ELF::R_ARM_MOVT_BREL:
    616     case llvm::ELF::R_ARM_MOVW_BREL: {
    617       // Relative addressing relocation, may needs dynamic relocation
    618       if (symbolNeedsDynRel(*rsym, (rsym->reserved() & ReservePLT), false)) {
    619         // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
    620         m_pRelDyn->reserveEntry();
    621         if (symbolNeedsCopyReloc(pReloc, *rsym)) {
    622           LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym);
    623           addCopyReloc(*cpy_sym.resolveInfo());
    624         }
    625         else {
    626           checkValidReloc(pReloc);
    627           // set Rel bit
    628           rsym->setReserved(rsym->reserved() | ReserveRel);
    629           checkAndSetHasTextRel(*pSection.getLink());
    630         }
    631       }
    632       return;
    633     }
    634 
    635     case llvm::ELF::R_ARM_THM_CALL:
    636     case llvm::ELF::R_ARM_PLT32:
    637     case llvm::ELF::R_ARM_CALL:
    638     case llvm::ELF::R_ARM_JUMP24:
    639     case llvm::ELF::R_ARM_THM_JUMP24:
    640     case llvm::ELF::R_ARM_SBREL31:
    641     case llvm::ELF::R_ARM_PREL31:
    642     case llvm::ELF::R_ARM_THM_JUMP19:
    643     case llvm::ELF::R_ARM_THM_JUMP6:
    644     case llvm::ELF::R_ARM_THM_JUMP11:
    645     case llvm::ELF::R_ARM_THM_JUMP8: {
    646       // These are branch relocation (except PREL31)
    647       // A PLT entry is needed when building shared library
    648 
    649       // return if we already create plt for this symbol
    650       if (rsym->reserved() & ReservePLT)
    651         return;
    652 
    653       // if the symbol's value can be decided at link time, then no need plt
    654       if (symbolFinalValueIsKnown(*rsym))
    655         return;
    656 
    657       // if symbol is defined in the ouput file and it's not
    658       // preemptible, no need plt
    659       if (rsym->isDefine() && !rsym->isDyn() &&
    660           !isSymbolPreemptible(*rsym)) {
    661         return;
    662       }
    663 
    664       // Symbol needs PLT entry, we need to reserve a PLT entry
    665       // and the corresponding GOT and dynamic relocation entry
    666       // in .got and .rel.plt. (GOT entry will be reserved simultaneously
    667       // when calling ARMPLT->reserveEntry())
    668       m_pPLT->reserveEntry();
    669       m_pRelPLT->reserveEntry();
    670       // set PLT bit
    671       rsym->setReserved(rsym->reserved() | ReservePLT);
    672       return;
    673     }
    674 
    675     // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
    676     // Ref: GNU gold 1.11 arm.cc, line 9892
    677     // FIXME: R_ARM_TARGET2 should be set by option --target2
    678     case llvm::ELF::R_ARM_TARGET2:
    679       pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
    680     case llvm::ELF::R_ARM_GOT_BREL:
    681     case llvm::ELF::R_ARM_GOT_ABS:
    682     case llvm::ELF::R_ARM_GOT_PREL: {
    683       // Symbol needs GOT entry, reserve entry in .got
    684       // return if we already create GOT for this symbol
    685       if (rsym->reserved() & (ReserveGOT | GOTRel))
    686         return;
    687       m_pGOT->reserveGOT();
    688       // if the symbol cannot be fully resolved at link time, then we need a
    689       // dynamic relocation
    690       if (!symbolFinalValueIsKnown(*rsym)) {
    691         m_pRelDyn->reserveEntry();
    692         // set GOTRel bit
    693         rsym->setReserved(rsym->reserved() | GOTRel);
    694         return;
    695       }
    696       // set GOT bit
    697       rsym->setReserved(rsym->reserved() | ReserveGOT);
    698       return;
    699     }
    700 
    701     case llvm::ELF::R_ARM_COPY:
    702     case llvm::ELF::R_ARM_GLOB_DAT:
    703     case llvm::ELF::R_ARM_JUMP_SLOT:
    704     case llvm::ELF::R_ARM_RELATIVE: {
    705       // These are relocation type for dynamic linker, shold not
    706       // appear in object file.
    707       fatal(diag::dynamic_relocation) << (int)pReloc.type();
    708       break;
    709     }
    710     default: {
    711       break;
    712     }
    713   } // end switch
    714 }
    715 
    716 void ARMGNULDBackend::scanRelocation(Relocation& pReloc,
    717                                      IRBuilder& pBuilder,
    718                                      Module& pModule,
    719                                      LDSection& pSection)
    720 {
    721   // rsym - The relocation target symbol
    722   ResolveInfo* rsym = pReloc.symInfo();
    723   assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
    724 
    725   pReloc.updateAddend();
    726   assert(NULL != pSection.getLink());
    727   if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
    728     return;
    729 
    730   // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
    731   // entries should be created.
    732   // FIXME: Below judgements concern nothing about TLS related relocation
    733 
    734   // rsym is local
    735   if (rsym->isLocal())
    736     scanLocalReloc(pReloc, pSection);
    737 
    738   // rsym is external
    739   else
    740     scanGlobalReloc(pReloc, pBuilder, pSection);
    741 
    742   // check if we shoule issue undefined reference for the relocation target
    743   // symbol
    744   if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
    745     fatal(diag::undefined_reference) << rsym->name();
    746 }
    747 
    748 uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection,
    749                                           MemoryRegion& pRegion) const
    750 {
    751   assert(pRegion.size() && "Size of MemoryRegion is zero!");
    752 
    753   const ELFFileFormat* file_format = getOutputFormat();
    754 
    755   if (&pSection == m_pAttributes ||
    756       &pSection == m_pEXIDX ||
    757       &pSection == m_pEXTAB) {
    758     // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab
    759     // directly from the input file.
    760     const SectionData* sect_data = pSection.getSectionData();
    761     SectionData::const_iterator frag_iter, frag_end = sect_data->end();
    762     uint8_t* out_offset = pRegion.start();
    763     for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
    764       size_t size = frag_iter->size();
    765       switch(frag_iter->getKind()) {
    766         case Fragment::Fillment: {
    767           const FillFragment& fill_frag =
    768             llvm::cast<FillFragment>(*frag_iter);
    769           if (0 == fill_frag.getValueSize()) {
    770             // virtual fillment, ignore it.
    771             break;
    772           }
    773 
    774           memset(out_offset, fill_frag.getValue(), fill_frag.size());
    775           break;
    776         }
    777         case Fragment::Region: {
    778           const RegionFragment& region_frag =
    779             llvm::cast<RegionFragment>(*frag_iter);
    780           const uint8_t* start = region_frag.getRegion().start();
    781           memcpy(out_offset, start, size);
    782           break;
    783         }
    784         case Fragment::Alignment: {
    785           const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
    786           uint64_t count = size / align_frag.getValueSize();
    787           switch (align_frag.getValueSize()) {
    788             case 1u:
    789               std::memset(out_offset, align_frag.getValue(), count);
    790               break;
    791             default:
    792               llvm::report_fatal_error(
    793                 "unsupported value size for align fragment emission yet.\n");
    794               break;
    795           } // end switch
    796           break;
    797         }
    798         case Fragment::Null: {
    799           assert(0x0 == size);
    800           break;
    801         }
    802         default:
    803           llvm::report_fatal_error("unsupported fragment type.\n");
    804           break;
    805       } // end switch
    806       out_offset += size;
    807     } // end for
    808     return pRegion.size();
    809   } // end if
    810 
    811   if (&pSection == &(file_format->getPLT())) {
    812     assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
    813     uint64_t result = m_pPLT->emit(pRegion);
    814     return result;
    815   }
    816 
    817   if (&pSection == &(file_format->getGOT())) {
    818     assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
    819     uint64_t result = m_pGOT->emit(pRegion);
    820     return result;
    821   }
    822   fatal(diag::unrecognized_output_sectoin)
    823           << pSection.name()
    824           << "mclinker (at) googlegroups.com";
    825   return 0x0;
    826 }
    827 
    828 /// finalizeSymbol - finalize the symbol value
    829 bool ARMGNULDBackend::finalizeTargetSymbols()
    830 {
    831   return true;
    832 }
    833 
    834 bool ARMGNULDBackend::mergeSection(Module& pModule, LDSection& pSection)
    835 {
    836   switch (pSection.type()) {
    837     case llvm::ELF::SHT_ARM_ATTRIBUTES: {
    838       // FIXME: (Luba)
    839       // Handle ARM attributes in the right way.
    840       // In current milestone, we goes through the shortcut.
    841       // It reads input's ARM attributes and copies the first ARM attributes
    842       // into the output file. The correct way is merge these sections, not
    843       // just copy.
    844       if (0 != m_pAttributes->size())
    845         return true;
    846 
    847       // First time we meet a ARM attributes section.
    848       SectionData* sd = IRBuilder::CreateSectionData(*m_pAttributes);
    849       ObjectBuilder::MoveSectionData(*pSection.getSectionData(), *sd);
    850       return true;
    851     }
    852     default: {
    853       ObjectBuilder builder(config(), pModule);
    854       return builder.MergeSection(pSection);
    855     }
    856   } // end of switch
    857   return true;
    858 }
    859 
    860 bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD)
    861 {
    862   Fragment* frag = NULL;
    863   uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
    864   uint32_t size = pSD.getSection().size();
    865 
    866   MemoryRegion* region = pInput.memArea()->request(offset, size);
    867   if (NULL == region) {
    868     // If the input section's size is zero, we got a NULL region.
    869     // use a virtual fill fragment
    870     frag = new FillFragment(0x0, 0, 0);
    871   }
    872   else {
    873     frag = new RegionFragment(*region);
    874   }
    875 
    876   ObjectBuilder::AppendFragment(*frag, pSD);
    877   return true;
    878 }
    879 
    880 ARMGOT& ARMGNULDBackend::getGOT()
    881 {
    882   assert(NULL != m_pGOT && "GOT section not exist");
    883   return *m_pGOT;
    884 }
    885 
    886 const ARMGOT& ARMGNULDBackend::getGOT() const
    887 {
    888   assert(NULL != m_pGOT && "GOT section not exist");
    889   return *m_pGOT;
    890 }
    891 
    892 ARMPLT& ARMGNULDBackend::getPLT()
    893 {
    894   assert(NULL != m_pPLT && "PLT section not exist");
    895   return *m_pPLT;
    896 }
    897 
    898 const ARMPLT& ARMGNULDBackend::getPLT() const
    899 {
    900   assert(NULL != m_pPLT && "PLT section not exist");
    901   return *m_pPLT;
    902 }
    903 
    904 OutputRelocSection& ARMGNULDBackend::getRelDyn()
    905 {
    906   assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
    907   return *m_pRelDyn;
    908 }
    909 
    910 const OutputRelocSection& ARMGNULDBackend::getRelDyn() const
    911 {
    912   assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
    913   return *m_pRelDyn;
    914 }
    915 
    916 OutputRelocSection& ARMGNULDBackend::getRelPLT()
    917 {
    918   assert(NULL != m_pRelPLT && ".rel.plt section not exist");
    919   return *m_pRelPLT;
    920 }
    921 
    922 const OutputRelocSection& ARMGNULDBackend::getRelPLT() const
    923 {
    924   assert(NULL != m_pRelPLT && ".rel.plt section not exist");
    925   return *m_pRelPLT;
    926 }
    927 
    928 unsigned int
    929 ARMGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
    930 {
    931   const ELFFileFormat* file_format = getOutputFormat();
    932 
    933   if (&pSectHdr == &file_format->getGOT()) {
    934     if (config().options().hasNow())
    935       return SHO_RELRO_LAST;
    936     return SHO_DATA;
    937   }
    938 
    939   if (&pSectHdr == &file_format->getPLT())
    940     return SHO_PLT;
    941 
    942   if (&pSectHdr == m_pEXIDX || &pSectHdr == m_pEXTAB) {
    943     // put ARM.exidx and ARM.extab in the same order of .eh_frame
    944     return SHO_EXCEPTION;
    945   }
    946 
    947   return SHO_UNDEFINED;
    948 }
    949 
    950 /// doRelax
    951 bool
    952 ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
    953 {
    954   assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
    955 
    956   bool isRelaxed = false;
    957   ELFFileFormat* file_format = getOutputFormat();
    958   // check branch relocs and create the related stubs if needed
    959   Module::obj_iterator input, inEnd = pModule.obj_end();
    960   for (input = pModule.obj_begin(); input != inEnd; ++input) {
    961     LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    962     for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
    963       if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
    964         continue;
    965       RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
    966       for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
    967         Relocation* relocation = llvm::cast<Relocation>(reloc);
    968 
    969         switch (relocation->type()) {
    970           case llvm::ELF::R_ARM_CALL:
    971           case llvm::ELF::R_ARM_JUMP24:
    972           case llvm::ELF::R_ARM_PLT32:
    973           case llvm::ELF::R_ARM_THM_CALL:
    974           case llvm::ELF::R_ARM_THM_XPC22:
    975           case llvm::ELF::R_ARM_THM_JUMP24:
    976           case llvm::ELF::R_ARM_THM_JUMP19:
    977           case llvm::ELF::R_ARM_V4BX: {
    978             // calculate the possible symbol value
    979             uint64_t sym_value = 0x0;
    980             LDSymbol* symbol = relocation->symInfo()->outSymbol();
    981             if (symbol->hasFragRef()) {
    982               uint64_t value = symbol->fragRef()->getOutputOffset();
    983               uint64_t addr =
    984                 symbol->fragRef()->frag()->getParent()->getSection().addr();
    985               sym_value = addr + value;
    986             }
    987             if (relocation->symInfo()->isGlobal() &&
    988                 (relocation->symInfo()->reserved() & ReservePLT) != 0x0) {
    989               // FIXME: we need to find out the address of the specific plt entry
    990               assert(file_format->hasPLT());
    991               sym_value = file_format->getPLT().addr();
    992             }
    993 
    994             Stub* stub = getStubFactory()->create(*relocation, // relocation
    995                                                   sym_value, // symbol value
    996                                                   pBuilder,
    997                                                   *getBRIslandFactory());
    998             if (NULL != stub) {
    999               // a stub symbol should be local
   1000               assert(NULL != stub->symInfo() && stub->symInfo()->isLocal());
   1001               LDSection& symtab = file_format->getSymTab();
   1002               LDSection& strtab = file_format->getStrTab();
   1003 
   1004               // increase the size of .symtab and .strtab if needed
   1005               if (config().targets().is32Bits())
   1006                 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
   1007               else
   1008                 symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym));
   1009               symtab.setInfo(symtab.getInfo() + 1);
   1010               strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
   1011 
   1012               isRelaxed = true;
   1013             }
   1014             break;
   1015           }
   1016           default:
   1017             break;
   1018         } // end of switch
   1019 
   1020       } // for all relocations
   1021     } // for all relocation section
   1022   } // for all inputs
   1023 
   1024   // find the first fragment w/ invalid offset due to stub insertion
   1025   Fragment* invalid = NULL;
   1026   pFinished = true;
   1027   for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
   1028        island_end = getBRIslandFactory()->end(); island != island_end; ++island) {
   1029     if ((*island).end() == file_format->getText().getSectionData()->end())
   1030       break;
   1031 
   1032     Fragment* exit = (*island).end();
   1033     if (((*island).offset() + (*island).size()) > exit->getOffset()) {
   1034       invalid = exit;
   1035       pFinished = false;
   1036       break;
   1037     }
   1038   }
   1039 
   1040   // reset the offset of invalid fragments
   1041   while (NULL != invalid) {
   1042     invalid->setOffset(invalid->getPrevNode()->getOffset() +
   1043                        invalid->getPrevNode()->size());
   1044     invalid = invalid->getNextNode();
   1045   }
   1046 
   1047   // reset the size of .text
   1048   if (isRelaxed) {
   1049     file_format->getText().setSize(
   1050       file_format->getText().getSectionData()->back().getOffset() +
   1051       file_format->getText().getSectionData()->back().size());
   1052   }
   1053   return isRelaxed;
   1054 }
   1055 
   1056 /// initTargetStubs
   1057 bool ARMGNULDBackend::initTargetStubs()
   1058 {
   1059   if (NULL != getStubFactory()) {
   1060     getStubFactory()->addPrototype(new ARMToARMStub(config().isCodeIndep()));
   1061     getStubFactory()->addPrototype(new ARMToTHMStub(config().isCodeIndep()));
   1062     getStubFactory()->addPrototype(new THMToTHMStub(config().isCodeIndep()));
   1063     getStubFactory()->addPrototype(new THMToARMStub(config().isCodeIndep()));
   1064     return true;
   1065   }
   1066   return false;
   1067 }
   1068 
   1069 /// doCreateProgramHdrs - backend can implement this function to create the
   1070 /// target-dependent segments
   1071 void ARMGNULDBackend::doCreateProgramHdrs(Module& pModule)
   1072 {
   1073    if (NULL != m_pEXIDX && 0x0 != m_pEXIDX->size()) {
   1074      // make PT_ARM_EXIDX
   1075      ELFSegment* exidx_seg = elfSegmentTable().produce(llvm::ELF::PT_ARM_EXIDX,
   1076                                                        llvm::ELF::PF_R);
   1077      exidx_seg->addSection(m_pEXIDX);
   1078    }
   1079 }
   1080 
   1081 namespace mcld {
   1082 
   1083 //===----------------------------------------------------------------------===//
   1084 /// createARMLDBackend - the help funtion to create corresponding ARMLDBackend
   1085 ///
   1086 TargetLDBackend* createARMLDBackend(const llvm::Target& pTarget,
   1087                                     const LinkerConfig& pConfig)
   1088 {
   1089   if (pConfig.targets().triple().isOSDarwin()) {
   1090     assert(0 && "MachO linker is not supported yet");
   1091     /**
   1092     return new ARMMachOLDBackend(createARMMachOArchiveReader,
   1093                                createARMMachOObjectReader,
   1094                                createARMMachOObjectWriter);
   1095     **/
   1096   }
   1097   if (pConfig.targets().triple().isOSWindows()) {
   1098     assert(0 && "COFF linker is not supported yet");
   1099     /**
   1100     return new ARMCOFFLDBackend(createARMCOFFArchiveReader,
   1101                                createARMCOFFObjectReader,
   1102                                createARMCOFFObjectWriter);
   1103     **/
   1104   }
   1105   return new ARMGNULDBackend(pConfig, new ARMGNUInfo(pConfig.targets().triple()));
   1106 }
   1107 
   1108 } // namespace of mcld
   1109 
   1110 //===----------------------------------------------------------------------===//
   1111 // Force static initialization.
   1112 //===----------------------------------------------------------------------===//
   1113 extern "C" void MCLDInitializeARMLDBackend() {
   1114   // Register the linker backend
   1115   mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend);
   1116   mcld::TargetRegistry::RegisterTargetLDBackend(TheThumbTarget, createARMLDBackend);
   1117 }
   1118 
   1119