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