MipsLDBackend.cpp revision a790f0a8f3175183bea088389b3e4ae41813e192
1//===- MipsLDBackend.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 "Mips.h"
10#include "MipsGNUInfo.h"
11#include "MipsELFDynamic.h"
12#include "MipsLA25Stub.h"
13#include "MipsLDBackend.h"
14#include "MipsRelocator.h"
15
16#include <llvm/ADT/Triple.h>
17#include <llvm/Support/Casting.h>
18#include <llvm/Support/ELF.h>
19#include <llvm/Support/Host.h>
20
21#include <mcld/Module.h>
22#include <mcld/LinkerConfig.h>
23#include <mcld/IRBuilder.h>
24#include <mcld/LD/BranchIslandFactory.h>
25#include <mcld/LD/LDContext.h>
26#include <mcld/LD/StubFactory.h>
27#include <mcld/LD/ELFFileFormat.h>
28#include <mcld/MC/Attribute.h>
29#include <mcld/Fragment/FillFragment.h>
30#include <mcld/Support/MemoryRegion.h>
31#include <mcld/Support/MemoryArea.h>
32#include <mcld/Support/MsgHandling.h>
33#include <mcld/Support/TargetRegistry.h>
34#include <mcld/Target/OutputRelocSection.h>
35#include <mcld/Object/ObjectBuilder.h>
36
37using namespace mcld;
38
39//===----------------------------------------------------------------------===//
40// MipsGNULDBackend
41//===----------------------------------------------------------------------===//
42MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig,
43                                   MipsGNUInfo* pInfo)
44  : GNULDBackend(pConfig, pInfo),
45    m_pRelocator(NULL),
46    m_pGOT(NULL),
47    m_pPLT(NULL),
48    m_pGOTPLT(NULL),
49    m_pInfo(*pInfo),
50    m_pRelPlt(NULL),
51    m_pRelDyn(NULL),
52    m_pDynamic(NULL),
53    m_pGOTSymbol(NULL),
54    m_pPLTSymbol(NULL),
55    m_pGpDispSymbol(NULL)
56{
57}
58
59MipsGNULDBackend::~MipsGNULDBackend()
60{
61  delete m_pRelocator;
62  delete m_pPLT;
63  delete m_pRelPlt;
64  delete m_pRelDyn;
65  delete m_pDynamic;
66}
67
68bool MipsGNULDBackend::needsLA25Stub(Relocation::Type pType,
69                                     const mcld::ResolveInfo* pSym)
70{
71  if (config().isCodeIndep())
72    return false;
73
74  if (llvm::ELF::R_MIPS_26 != pType)
75    return false;
76
77  if (pSym->isLocal())
78    return false;
79
80  return true;
81}
82
83void MipsGNULDBackend::addNonPICBranchSym(ResolveInfo* rsym)
84{
85  m_HasNonPICBranchSyms.insert(rsym);
86}
87
88bool MipsGNULDBackend::hasNonPICBranch(const ResolveInfo* rsym) const
89{
90  return m_HasNonPICBranchSyms.count(rsym);
91}
92
93void MipsGNULDBackend::initTargetSections(Module& pModule,
94                                            ObjectBuilder& pBuilder)
95{
96  if (LinkerConfig::Object == config().codeGenType())
97    return;
98
99  ELFFileFormat* file_format = getOutputFormat();
100
101  // initialize .rel.plt
102  LDSection& relplt = file_format->getRelPlt();
103  m_pRelPlt = new OutputRelocSection(pModule, relplt);
104
105  // initialize .rel.dyn
106  LDSection& reldyn = file_format->getRelDyn();
107  m_pRelDyn = new OutputRelocSection(pModule, reldyn);
108}
109
110void MipsGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
111{
112  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
113  // same name in input
114  m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
115                   "_GLOBAL_OFFSET_TABLE_",
116                   ResolveInfo::Object,
117                   ResolveInfo::Define,
118                   ResolveInfo::Local,
119                   0x0,  // size
120                   0x0,  // value
121                   FragmentRef::Null(), // FragRef
122                   ResolveInfo::Hidden);
123
124  // Define the symbol _PROCEDURE_LINKAGE_TABLE_ if there is a symbol with the
125  // same name in input
126  m_pPLTSymbol =
127    pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
128                   "_PROCEDURE_LINKAGE_TABLE_",
129                   ResolveInfo::Object,
130                   ResolveInfo::Define,
131                   ResolveInfo::Local,
132                   0x0,  // size
133                   0x0,  // value
134                   FragmentRef::Null(), // FragRef
135                   ResolveInfo::Hidden);
136
137  m_pGpDispSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
138                   "_gp_disp",
139                   ResolveInfo::Section,
140                   ResolveInfo::Define,
141                   ResolveInfo::Absolute,
142                   0x0,  // size
143                   0x0,  // value
144                   FragmentRef::Null(), // FragRef
145                   ResolveInfo::Default);
146  pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
147                   "_gp",
148                   ResolveInfo::NoType,
149                   ResolveInfo::Define,
150                   ResolveInfo::Absolute,
151                   0x0,  // size
152                   0x0,  // value
153                   FragmentRef::Null(), // FragRef
154                   ResolveInfo::Default);
155}
156
157const Relocator* MipsGNULDBackend::getRelocator() const
158{
159  assert(NULL != m_pRelocator);
160  return m_pRelocator;
161}
162
163Relocator* MipsGNULDBackend::getRelocator()
164{
165  assert(NULL != m_pRelocator);
166  return m_pRelocator;
167}
168
169void MipsGNULDBackend::doPreLayout(IRBuilder& pBuilder)
170{
171  // initialize .dynamic data
172  if (!config().isCodeStatic() && NULL == m_pDynamic)
173    m_pDynamic = new MipsELFDynamic(*this, config());
174
175  // set .got size
176  // when building shared object, the .got section is must.
177  if (LinkerConfig::Object != config().codeGenType()) {
178    if (LinkerConfig::DynObj == config().codeGenType() ||
179        m_pGOT->hasGOT1() ||
180        NULL != m_pGOTSymbol) {
181      m_pGOT->finalizeScanning(*m_pRelDyn);
182      m_pGOT->finalizeSectionSize();
183
184      defineGOTSymbol(pBuilder);
185    }
186
187    if (m_pGOTPLT->hasGOT1()) {
188      m_pGOTPLT->finalizeSectionSize();
189
190      defineGOTPLTSymbol(pBuilder);
191    }
192
193    if (m_pPLT->hasPLT1())
194      m_pPLT->finalizeSectionSize();
195
196    ELFFileFormat* file_format = getOutputFormat();
197
198    // set .rel.plt size
199    if (!m_pRelPlt->empty()) {
200      assert(!config().isCodeStatic() &&
201            "static linkage should not result in a dynamic relocation section");
202      file_format->getRelPlt().setSize(
203                                  m_pRelPlt->numOfRelocs() * getRelEntrySize());
204    }
205
206    // set .rel.dyn size
207    if (!m_pRelDyn->empty()) {
208      assert(!config().isCodeStatic() &&
209            "static linkage should not result in a dynamic relocation section");
210      file_format->getRelDyn().setSize(
211                                  m_pRelDyn->numOfRelocs() * getRelEntrySize());
212    }
213  }
214}
215
216void MipsGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
217{
218  const ELFFileFormat *format = getOutputFormat();
219
220  if (format->hasGOTPLT()) {
221    assert(m_pGOTPLT && "doPostLayout failed, m_pGOTPLT is NULL!");
222    m_pGOTPLT->applyAllGOTPLT(m_pPLT->addr());
223  }
224
225  if (format->hasPLT()) {
226    assert(m_pPLT && "doPostLayout failed, m_pPLT is NULL!");
227    m_pPLT->applyAllPLT(*m_pGOTPLT);
228  }
229
230  m_pInfo.setABIVersion(m_pPLT && m_pPLT->hasPLT1() ? 1 : 0);
231
232  // FIXME: (simon) We need to iterate all input sections
233  // check that flags are consistent and merge them properly.
234  uint64_t picFlags = llvm::ELF::EF_MIPS_CPIC;
235  if (config().targets().triple().isArch64Bit()) {
236    picFlags |= llvm::ELF::EF_MIPS_PIC;
237  }
238  else {
239    if (LinkerConfig::DynObj == config().codeGenType())
240      picFlags |= llvm::ELF::EF_MIPS_PIC;
241  }
242
243  m_pInfo.setPICFlags(picFlags);
244}
245
246/// dynamic - the dynamic section of the target machine.
247/// Use co-variant return type to return its own dynamic section.
248MipsELFDynamic& MipsGNULDBackend::dynamic()
249{
250  assert(NULL != m_pDynamic);
251  return *m_pDynamic;
252}
253
254/// dynamic - the dynamic section of the target machine.
255/// Use co-variant return type to return its own dynamic section.
256const MipsELFDynamic& MipsGNULDBackend::dynamic() const
257{
258  assert(NULL != m_pDynamic);
259  return *m_pDynamic;
260}
261
262uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
263                                           MemoryRegion& pRegion) const
264{
265  assert(pRegion.size() && "Size of MemoryRegion is zero!");
266
267  const ELFFileFormat* file_format = getOutputFormat();
268
269  if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) {
270    return m_pGOT->emit(pRegion);
271  }
272
273  if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) {
274    return m_pPLT->emit(pRegion);
275  }
276
277  if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) {
278    return m_pGOTPLT->emit(pRegion);
279  }
280
281  fatal(diag::unrecognized_output_sectoin)
282          << pSection.name()
283          << "mclinker@googlegroups.com";
284  return 0;
285}
286
287bool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const
288{
289  return ResolveInfo::Section != pSym.type() ||
290         m_pGpDispSymbol == &pSym;
291}
292
293namespace {
294  struct DynsymGOTCompare
295  {
296    const MipsGOT& m_pGOT;
297
298    DynsymGOTCompare(const MipsGOT& pGOT)
299      : m_pGOT(pGOT)
300    {
301    }
302
303    bool operator()(const LDSymbol* X, const LDSymbol* Y) const
304    {
305      return m_pGOT.dynSymOrderCompare(X, Y);
306    }
307  };
308}
309
310void MipsGNULDBackend::orderSymbolTable(Module& pModule)
311{
312  if (GeneralOptions::GNU  == config().options().getHashStyle() ||
313      GeneralOptions::Both == config().options().getHashStyle()) {
314    // The MIPS ABI and .gnu.hash require .dynsym to be sorted
315    // in different ways. The MIPS ABI requires a mapping between
316    // the GOT and the symbol table. At the same time .gnu.hash
317    // needs symbols to be grouped by hash code.
318    llvm::errs() << ".gnu.hash is incompatible with the MIPS ABI\n";
319  }
320
321  Module::SymbolTable& symbols = pModule.getSymbolTable();
322
323  std::stable_sort(symbols.dynamicBegin(), symbols.dynamicEnd(),
324                   DynsymGOTCompare(*m_pGOT));
325}
326
327namespace llvm {
328namespace ELF {
329// SHT_MIPS_OPTIONS section's block descriptor.
330struct Elf_Options {
331  unsigned char kind;     // Determines interpretation of variable
332                          // part of descriptor. See ODK_xxx enumeration.
333  unsigned char size;     // Byte size of descriptor, including this header.
334  Elf64_Half    section;  // Section header index of section affected,
335                          // or 0 for global options.
336  Elf64_Word    info;     // Kind-specific information.
337};
338
339// Type of SHT_MIPS_OPTIONS section's block.
340enum {
341  ODK_NULL       = 0, // Undefined.
342  ODK_REGINFO    = 1, // Register usage and GP value.
343  ODK_EXCEPTIONS = 2, // Exception processing information.
344  ODK_PAD        = 3, // Section padding information.
345  ODK_HWPATCH    = 4, // Hardware workarounds performed.
346  ODK_FILL       = 5, // Fill value used by the linker.
347  ODK_TAGS       = 6, // Reserved space for desktop tools.
348  ODK_HWAND      = 7, // Hardware workarounds, AND bits when merging.
349  ODK_HWOR       = 8, // Hardware workarounds, OR bits when merging.
350  ODK_GP_GROUP   = 9, // GP group to use for text/data sections.
351  ODK_IDENT      = 10 // ID information.
352};
353
354// Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 32 bit ABI.
355struct Elf32_RegInfo {
356  Elf32_Word ri_gprmask;    // Mask of general purpose registers used.
357  Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used.
358  Elf32_Addr ri_gp_value;   // GP register value for this object file.
359};
360
361// Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 64 bit ABI.
362struct Elf64_RegInfo {
363  Elf32_Word ri_gprmask;    // Mask of general purpose registers used.
364  Elf32_Word ri_pad;        // Padding.
365  Elf32_Word ri_cprmask[4]; // Mask of co-processor registers used.
366  Elf64_Addr ri_gp_value;   // GP register value for this object file.
367};
368
369}
370}
371
372bool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD)
373{
374  llvm::StringRef name(pSD.getSection().name());
375
376  if (name.startswith(".sdata")) {
377    uint64_t offset = pInput.fileOffset() + pSD.getSection().offset();
378    uint64_t size = pSD.getSection().size();
379
380    Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size);
381    ObjectBuilder::AppendFragment(*frag, pSD);
382    return true;
383  }
384
385  if (pSD.getSection().type() == llvm::ELF::SHT_MIPS_OPTIONS) {
386    uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
387    uint32_t size = pSD.getSection().size();
388
389    llvm::StringRef region = pInput.memArea()->request(offset, size);
390    if (region.size() > 0) {
391      const llvm::ELF::Elf_Options* optb =
392        reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin());
393      const llvm::ELF::Elf_Options* opte =
394        reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin() + size);
395
396      for (const llvm::ELF::Elf_Options* opt = optb; opt < opte; opt += opt->size) {
397        switch (opt->kind) {
398          default:
399            // Nothing to do.
400            break;
401          case llvm::ELF::ODK_REGINFO:
402            if (config().targets().triple().isArch32Bit()) {
403              const llvm::ELF::Elf32_RegInfo* reg =
404                reinterpret_cast<const llvm::ELF::Elf32_RegInfo*>(opt + 1);
405              m_GP0Map[&pInput] = reg->ri_gp_value;
406            }
407            else {
408              const llvm::ELF::Elf64_RegInfo* reg =
409                reinterpret_cast<const llvm::ELF::Elf64_RegInfo*>(opt + 1);
410              m_GP0Map[&pInput] = reg->ri_gp_value;
411            }
412            break;
413        }
414      }
415    }
416
417    return true;
418  }
419
420  return GNULDBackend::readSection(pInput, pSD);
421}
422
423MipsGOT& MipsGNULDBackend::getGOT()
424{
425  assert(NULL != m_pGOT);
426  return *m_pGOT;
427}
428
429const MipsGOT& MipsGNULDBackend::getGOT() const
430{
431  assert(NULL != m_pGOT);
432  return *m_pGOT;
433}
434
435MipsPLT& MipsGNULDBackend::getPLT()
436{
437  assert(NULL != m_pPLT);
438  return *m_pPLT;
439}
440
441const MipsPLT& MipsGNULDBackend::getPLT() const
442{
443  assert(NULL != m_pPLT);
444  return *m_pPLT;
445}
446
447MipsGOTPLT& MipsGNULDBackend::getGOTPLT()
448{
449  assert(NULL != m_pGOTPLT);
450  return *m_pGOTPLT;
451}
452
453const MipsGOTPLT& MipsGNULDBackend::getGOTPLT() const
454{
455  assert(NULL != m_pGOTPLT);
456  return *m_pGOTPLT;
457}
458
459OutputRelocSection& MipsGNULDBackend::getRelPLT()
460{
461  assert(NULL != m_pRelPlt);
462  return *m_pRelPlt;
463}
464
465const OutputRelocSection& MipsGNULDBackend::getRelPLT() const
466{
467  assert(NULL != m_pRelPlt);
468  return *m_pRelPlt;
469}
470
471OutputRelocSection& MipsGNULDBackend::getRelDyn()
472{
473  assert(NULL != m_pRelDyn);
474  return *m_pRelDyn;
475}
476
477const OutputRelocSection& MipsGNULDBackend::getRelDyn() const
478{
479  assert(NULL != m_pRelDyn);
480  return *m_pRelDyn;
481}
482
483unsigned int
484MipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
485{
486  const ELFFileFormat* file_format = getOutputFormat();
487
488  if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT()))
489    return SHO_DATA;
490
491  if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT()))
492    return SHO_DATA;
493
494  if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
495    return SHO_PLT;
496
497  return SHO_UNDEFINED;
498}
499
500/// finalizeSymbol - finalize the symbol value
501bool MipsGNULDBackend::finalizeTargetSymbols()
502{
503  if (NULL != m_pGpDispSymbol)
504    m_pGpDispSymbol->setValue(m_pGOT->getGPDispAddress());
505
506  return true;
507}
508
509/// allocateCommonSymbols - allocate common symbols in the corresponding
510/// sections. This is called at pre-layout stage.
511/// @refer Google gold linker: common.cc: 214
512/// FIXME: Mips needs to allocate small common symbol
513bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule)
514{
515  SymbolCategory& symbol_list = pModule.getSymbolTable();
516
517  if (symbol_list.emptyCommons() && symbol_list.emptyFiles() &&
518      symbol_list.emptyLocals() && symbol_list.emptyLocalDyns())
519    return true;
520
521  SymbolCategory::iterator com_sym, com_end;
522
523  // FIXME: If the order of common symbols is defined, then sort common symbols
524  // std::sort(com_sym, com_end, some kind of order);
525
526  // get corresponding BSS LDSection
527  ELFFileFormat* file_format = getOutputFormat();
528  LDSection& bss_sect = file_format->getBSS();
529  LDSection& tbss_sect = file_format->getTBSS();
530
531  // get or create corresponding BSS SectionData
532  SectionData* bss_sect_data = NULL;
533  if (bss_sect.hasSectionData())
534    bss_sect_data = bss_sect.getSectionData();
535  else
536    bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
537
538  SectionData* tbss_sect_data = NULL;
539  if (tbss_sect.hasSectionData())
540    tbss_sect_data = tbss_sect.getSectionData();
541  else
542    tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
543
544  // remember original BSS size
545  uint64_t bss_offset  = bss_sect.size();
546  uint64_t tbss_offset = tbss_sect.size();
547
548  // allocate all local common symbols
549  com_end = symbol_list.localEnd();
550
551  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
552    if (ResolveInfo::Common == (*com_sym)->desc()) {
553      // We have to reset the description of the symbol here. When doing
554      // incremental linking, the output relocatable object may have common
555      // symbols. Therefore, we can not treat common symbols as normal symbols
556      // when emitting the regular name pools. We must change the symbols'
557      // description here.
558      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
559      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
560
561      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
562        // allocate TLS common symbol in tbss section
563        tbss_offset += ObjectBuilder::AppendFragment(*frag,
564                                                     *tbss_sect_data,
565                                                     (*com_sym)->value());
566        ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
567        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
568      }
569      // FIXME: how to identify small and large common symbols?
570      else {
571        bss_offset += ObjectBuilder::AppendFragment(*frag,
572                                                    *bss_sect_data,
573                                                    (*com_sym)->value());
574        ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
575        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
576      }
577    }
578  }
579
580  // allocate all global common symbols
581  com_end = symbol_list.commonEnd();
582  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
583    // We have to reset the description of the symbol here. When doing
584    // incremental linking, the output relocatable object may have common
585    // symbols. Therefore, we can not treat common symbols as normal symbols
586    // when emitting the regular name pools. We must change the symbols'
587    // description here.
588    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
589    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
590
591    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
592      // allocate TLS common symbol in tbss section
593      tbss_offset += ObjectBuilder::AppendFragment(*frag,
594                                                   *tbss_sect_data,
595                                                   (*com_sym)->value());
596      ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
597      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
598    }
599    // FIXME: how to identify small and large common symbols?
600    else {
601      bss_offset += ObjectBuilder::AppendFragment(*frag,
602                                                  *bss_sect_data,
603                                                  (*com_sym)->value());
604      ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
605      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
606    }
607  }
608
609  bss_sect.setSize(bss_offset);
610  tbss_sect.setSize(tbss_offset);
611  symbol_list.changeCommonsToGlobal();
612  return true;
613}
614
615uint64_t MipsGNULDBackend::getGP0(const Input& pInput) const
616{
617  return m_GP0Map.lookup(&pInput);
618}
619
620void MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder)
621{
622  // If we do not reserve any GOT entries, we do not need to re-define GOT
623  // symbol.
624  if (!m_pGOT->hasGOT1())
625    return;
626
627  // define symbol _GLOBAL_OFFSET_TABLE_
628  if ( m_pGOTSymbol != NULL ) {
629    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
630                     "_GLOBAL_OFFSET_TABLE_",
631                     ResolveInfo::Object,
632                     ResolveInfo::Define,
633                     ResolveInfo::Local,
634                     0x0, // size
635                     0x0, // value
636                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
637                     ResolveInfo::Hidden);
638  }
639  else {
640    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
641                     "_GLOBAL_OFFSET_TABLE_",
642                     ResolveInfo::Object,
643                     ResolveInfo::Define,
644                     ResolveInfo::Local,
645                     0x0, // size
646                     0x0, // value
647                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
648                     ResolveInfo::Hidden);
649  }
650}
651
652void MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder)
653{
654  // define symbol _PROCEDURE_LINKAGE_TABLE_
655  if ( m_pPLTSymbol != NULL ) {
656    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
657                     "_PROCEDURE_LINKAGE_TABLE_",
658                     ResolveInfo::Object,
659                     ResolveInfo::Define,
660                     ResolveInfo::Local,
661                     0x0, // size
662                     0x0, // value
663                     FragmentRef::Create(*(m_pPLT->begin()), 0x0),
664                     ResolveInfo::Hidden);
665  }
666  else {
667    m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
668                     "_PROCEDURE_LINKAGE_TABLE_",
669                     ResolveInfo::Object,
670                     ResolveInfo::Define,
671                     ResolveInfo::Local,
672                     0x0, // size
673                     0x0, // value
674                     FragmentRef::Create(*(m_pPLT->begin()), 0x0),
675                     ResolveInfo::Hidden);
676  }
677}
678
679/// doCreateProgramHdrs - backend can implement this function to create the
680/// target-dependent segments
681void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule)
682{
683  // TODO
684}
685
686bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel)
687{
688  uint64_t sym_value = 0x0;
689
690  LDSymbol* symbol = pRel.symInfo()->outSymbol();
691  if (symbol->hasFragRef()) {
692    uint64_t value = symbol->fragRef()->getOutputOffset();
693    uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr();
694    sym_value = addr + value;
695  }
696
697  Stub* stub =
698    getStubFactory()->create(pRel, sym_value, pBuilder, *getBRIslandFactory());
699
700  if (NULL == stub)
701    return false;
702
703  assert(NULL != stub->symInfo());
704  // increase the size of .symtab and .strtab
705  LDSection& symtab = getOutputFormat()->getSymTab();
706  LDSection& strtab = getOutputFormat()->getStrTab();
707  symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
708  strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
709
710  return true;
711}
712
713bool MipsGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder,
714                               bool& pFinished)
715{
716  assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
717
718  bool isRelaxed = false;
719
720  for (Module::obj_iterator input = pModule.obj_begin();
721       input != pModule.obj_end(); ++input) {
722    LDContext* context = (*input)->context();
723
724    for (LDContext::sect_iterator rs = context->relocSectBegin();
725         rs != context->relocSectEnd(); ++rs) {
726      LDSection* sec = *rs;
727
728      if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData())
729        continue;
730
731      for (RelocData::iterator reloc = sec->getRelocData()->begin();
732           reloc != sec->getRelocData()->end(); ++reloc) {
733        if (llvm::ELF::R_MIPS_26 != reloc->type())
734          continue;
735
736        if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc)))
737          isRelaxed = true;
738      }
739    }
740  }
741
742  SectionData* textData = getOutputFormat()->getText().getSectionData();
743
744  // find the first fragment w/ invalid offset due to stub insertion
745  Fragment* invalid = NULL;
746  pFinished = true;
747  for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(),
748                                     ie = getBRIslandFactory()->end();
749       ii != ie; ++ii)
750  {
751    BranchIsland& island = *ii;
752    if (island.end() == textData->end())
753      break;
754
755    Fragment* exit = island.end();
756    if ((island.offset() + island.size()) > exit->getOffset()) {
757      invalid = exit;
758      pFinished = false;
759      break;
760    }
761  }
762
763  // reset the offset of invalid fragments
764  while (NULL != invalid) {
765    invalid->setOffset(invalid->getPrevNode()->getOffset() +
766                       invalid->getPrevNode()->size());
767    invalid = invalid->getNextNode();
768  }
769
770  // reset the size of .text
771  if (isRelaxed)
772    getOutputFormat()->getText().setSize(textData->back().getOffset() +
773                                         textData->back().size());
774
775  return isRelaxed;
776}
777
778bool MipsGNULDBackend::initTargetStubs()
779{
780  if (NULL == getStubFactory())
781    return false;
782
783  getStubFactory()->addPrototype(new MipsLA25Stub(*this));
784  return true;
785}
786
787bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel,
788                                      Relocation::Type& pType,
789                                      uint32_t& pSymIdx,
790                                      uint32_t& pOffset) const
791{
792  return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset);
793}
794
795bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel,
796                                      Relocation::Type& pType,
797                                      uint32_t& pSymIdx,
798                                      uint32_t& pOffset,
799                                      int32_t& pAddend) const
800{
801  return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
802}
803
804bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel,
805                                      Relocation::Type& pType,
806                                      uint32_t& pSymIdx,
807                                      uint64_t& pOffset) const
808{
809  uint64_t r_info = 0x0;
810  if (llvm::sys::IsLittleEndianHost) {
811    pOffset = pRel.r_offset;
812    r_info  = pRel.r_info;
813  }
814  else {
815    pOffset = mcld::bswap64(pRel.r_offset);
816    r_info  = mcld::bswap64(pRel.r_info);
817  }
818
819  // MIPS 64 little endian (we do not support big endian now)
820  // has a "special" encoding of r_info relocation
821  // field. Instead of one 64 bit little endian number, it is a little
822  // endian 32 bit number followed by a 32 bit big endian number.
823  pType = mcld::bswap32(r_info >> 32);
824  pSymIdx = r_info & 0xffffffff;
825  return true;
826}
827
828bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel,
829                                      Relocation::Type& pType,
830                                      uint32_t& pSymIdx,
831                                      uint64_t& pOffset,
832                                      int64_t& pAddend) const
833{
834  uint64_t r_info = 0x0;
835  if (llvm::sys::IsLittleEndianHost) {
836    pOffset = pRel.r_offset;
837    r_info  = pRel.r_info;
838    pAddend = pRel.r_addend;
839  }
840  else {
841    pOffset = mcld::bswap64(pRel.r_offset);
842    r_info  = mcld::bswap64(pRel.r_info);
843    pAddend = mcld::bswap64(pRel.r_addend);
844  }
845
846  pType = mcld::bswap32(r_info >> 32);
847  pSymIdx = r_info & 0xffffffff;
848  return true;
849}
850
851void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel,
852                                      Relocation::Type pType,
853                                      uint32_t pSymIdx,
854                                      uint32_t pOffset) const
855{
856  GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset);
857}
858
859void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel,
860                                      Relocation::Type pType,
861                                      uint32_t pSymIdx,
862                                      uint32_t pOffset,
863                                      int32_t pAddend) const
864{
865  GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
866}
867
868void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel,
869                                      Relocation::Type pType,
870                                      uint32_t pSymIdx,
871                                      uint64_t pOffset) const
872{
873  uint64_t r_info = mcld::bswap32(pType);
874  r_info <<= 32;
875  r_info |= pSymIdx;
876
877  pRel.r_info = r_info;
878  pRel.r_offset = pOffset;
879}
880
881void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel,
882                                      Relocation::Type pType,
883                                      uint32_t pSymIdx,
884                                      uint64_t pOffset,
885                                      int64_t pAddend) const
886{
887  uint64_t r_info = mcld::bswap32(pType);
888  r_info <<= 32;
889  r_info |= pSymIdx;
890
891  pRel.r_info = r_info;
892  pRel.r_offset = pOffset;
893  pRel.r_addend = pAddend;
894}
895
896//===----------------------------------------------------------------------===//
897// Mips32GNULDBackend
898//===----------------------------------------------------------------------===//
899Mips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig,
900                                       MipsGNUInfo* pInfo)
901  : MipsGNULDBackend(pConfig, pInfo)
902{}
903
904bool Mips32GNULDBackend::initRelocator()
905{
906  if (NULL == m_pRelocator)
907    m_pRelocator = new Mips32Relocator(*this, config());
908
909  return true;
910}
911
912void Mips32GNULDBackend::initTargetSections(Module& pModule,
913                                            ObjectBuilder& pBuilder)
914{
915  MipsGNULDBackend::initTargetSections(pModule, pBuilder);
916
917  if (LinkerConfig::Object == config().codeGenType())
918    return;
919
920  ELFFileFormat* fileFormat = getOutputFormat();
921
922  // initialize .got
923  LDSection& got = fileFormat->getGOT();
924  m_pGOT = new Mips32GOT(got);
925
926  // initialize .got.plt
927  LDSection& gotplt = fileFormat->getGOTPLT();
928  m_pGOTPLT = new MipsGOTPLT(gotplt);
929
930  // initialize .plt
931  LDSection& plt = fileFormat->getPLT();
932  m_pPLT = new MipsPLT(plt);
933}
934
935size_t Mips32GNULDBackend::getRelEntrySize()
936{
937  return 8;
938}
939
940size_t Mips32GNULDBackend::getRelaEntrySize()
941{
942  return 12;
943}
944
945//===----------------------------------------------------------------------===//
946// Mips64GNULDBackend
947//===----------------------------------------------------------------------===//
948Mips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig,
949                                       MipsGNUInfo* pInfo)
950  : MipsGNULDBackend(pConfig, pInfo)
951{}
952
953bool Mips64GNULDBackend::initRelocator()
954{
955  if (NULL == m_pRelocator)
956    m_pRelocator = new Mips64Relocator(*this, config());
957
958  return true;
959}
960
961void Mips64GNULDBackend::initTargetSections(Module& pModule,
962                                            ObjectBuilder& pBuilder)
963{
964  MipsGNULDBackend::initTargetSections(pModule, pBuilder);
965
966  if (LinkerConfig::Object == config().codeGenType())
967    return;
968
969  ELFFileFormat* fileFormat = getOutputFormat();
970
971  // initialize .got
972  LDSection& got = fileFormat->getGOT();
973  m_pGOT = new Mips64GOT(got);
974
975  // initialize .got.plt
976  LDSection& gotplt = fileFormat->getGOTPLT();
977  m_pGOTPLT = new MipsGOTPLT(gotplt);
978
979  // initialize .plt
980  LDSection& plt = fileFormat->getPLT();
981  m_pPLT = new MipsPLT(plt);
982}
983
984size_t Mips64GNULDBackend::getRelEntrySize()
985{
986  return 16;
987}
988
989size_t Mips64GNULDBackend::getRelaEntrySize()
990{
991  return 24;
992}
993
994//===----------------------------------------------------------------------===//
995/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
996///
997static TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig)
998{
999  const llvm::Triple& triple = pConfig.targets().triple();
1000
1001  if (triple.isOSDarwin()) {
1002    assert(0 && "MachO linker is not supported yet");
1003  }
1004  if (triple.isOSWindows()) {
1005    assert(0 && "COFF linker is not supported yet");
1006  }
1007
1008  llvm::Triple::ArchType arch = triple.getArch();
1009
1010  if (llvm::Triple::mips64el == arch)
1011    return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple));
1012
1013  assert (arch == llvm::Triple::mipsel);
1014  return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple));
1015}
1016
1017//===----------------------------------------------------------------------===//
1018// Force static initialization.
1019//===----------------------------------------------------------------------===//
1020extern "C" void MCLDInitializeMipsLDBackend() {
1021  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
1022                                                createMipsLDBackend);
1023  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget,
1024                                                createMipsLDBackend);
1025}
1026