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