MipsLDBackend.cpp revision 551ae4ebd3e9d137ea668fb83ae4a55b8cfba451
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        ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
552        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
553      }
554      // FIXME: how to identify small and large common symbols?
555      else {
556        bss_offset += ObjectBuilder::AppendFragment(*frag,
557                                                    *bss_sect_data,
558                                                    (*com_sym)->value());
559        ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
560        (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
561      }
562    }
563  }
564
565  // allocate all global common symbols
566  com_end = symbol_list.commonEnd();
567  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
568    // We have to reset the description of the symbol here. When doing
569    // incremental linking, the output relocatable object may have common
570    // symbols. Therefore, we can not treat common symbols as normal symbols
571    // when emitting the regular name pools. We must change the symbols'
572    // description here.
573    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
574    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
575
576    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
577      // allocate TLS common symbol in tbss section
578      tbss_offset += ObjectBuilder::AppendFragment(*frag,
579                                                   *tbss_sect_data,
580                                                   (*com_sym)->value());
581      ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
582      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
583    }
584    // FIXME: how to identify small and large common symbols?
585    else {
586      bss_offset += ObjectBuilder::AppendFragment(*frag,
587                                                  *bss_sect_data,
588                                                  (*com_sym)->value());
589      ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
590      (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
591    }
592  }
593
594  bss_sect.setSize(bss_offset);
595  tbss_sect.setSize(tbss_offset);
596  symbol_list.changeCommonsToGlobal();
597  return true;
598}
599
600uint64_t MipsGNULDBackend::getGP0(const Input& pInput) const
601{
602  return m_GP0Map.lookup(&pInput);
603}
604
605void MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder)
606{
607  // If we do not reserve any GOT entries, we do not need to re-define GOT
608  // symbol.
609  if (!m_pGOT->hasGOT1())
610    return;
611
612  // define symbol _GLOBAL_OFFSET_TABLE_
613  if ( m_pGOTSymbol != NULL ) {
614    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
615                     "_GLOBAL_OFFSET_TABLE_",
616                     ResolveInfo::Object,
617                     ResolveInfo::Define,
618                     ResolveInfo::Local,
619                     0x0, // size
620                     0x0, // value
621                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
622                     ResolveInfo::Hidden);
623  }
624  else {
625    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
626                     "_GLOBAL_OFFSET_TABLE_",
627                     ResolveInfo::Object,
628                     ResolveInfo::Define,
629                     ResolveInfo::Local,
630                     0x0, // size
631                     0x0, // value
632                     FragmentRef::Create(*(m_pGOT->begin()), 0x0),
633                     ResolveInfo::Hidden);
634  }
635}
636
637void MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder)
638{
639  // define symbol _PROCEDURE_LINKAGE_TABLE_
640  if ( m_pPLTSymbol != NULL ) {
641    pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
642                     "_PROCEDURE_LINKAGE_TABLE_",
643                     ResolveInfo::Object,
644                     ResolveInfo::Define,
645                     ResolveInfo::Local,
646                     0x0, // size
647                     0x0, // value
648                     FragmentRef::Create(*(m_pPLT->begin()), 0x0),
649                     ResolveInfo::Hidden);
650  }
651  else {
652    m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
653                     "_PROCEDURE_LINKAGE_TABLE_",
654                     ResolveInfo::Object,
655                     ResolveInfo::Define,
656                     ResolveInfo::Local,
657                     0x0, // size
658                     0x0, // value
659                     FragmentRef::Create(*(m_pPLT->begin()), 0x0),
660                     ResolveInfo::Hidden);
661  }
662}
663
664/// doCreateProgramHdrs - backend can implement this function to create the
665/// target-dependent segments
666void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule)
667{
668  // TODO
669}
670
671bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel)
672{
673  uint64_t sym_value = 0x0;
674
675  LDSymbol* symbol = pRel.symInfo()->outSymbol();
676  if (symbol->hasFragRef()) {
677    uint64_t value = symbol->fragRef()->getOutputOffset();
678    uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr();
679    sym_value = addr + value;
680  }
681
682  Stub* stub =
683    getStubFactory()->create(pRel, sym_value, pBuilder, *getBRIslandFactory());
684
685  if (NULL == stub)
686    return false;
687
688  assert(NULL != stub->symInfo());
689  // increase the size of .symtab and .strtab
690  LDSection& symtab = getOutputFormat()->getSymTab();
691  LDSection& strtab = getOutputFormat()->getStrTab();
692  symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
693  strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
694
695  return true;
696}
697
698bool MipsGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder,
699                               bool& pFinished)
700{
701  assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
702
703  bool isRelaxed = false;
704
705  for (Module::obj_iterator input = pModule.obj_begin();
706       input != pModule.obj_end(); ++input) {
707    LDContext* context = (*input)->context();
708
709    for (LDContext::sect_iterator rs = context->relocSectBegin();
710         rs != context->relocSectEnd(); ++rs) {
711      LDSection* sec = *rs;
712
713      if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData())
714        continue;
715
716      for (RelocData::iterator reloc = sec->getRelocData()->begin();
717           reloc != sec->getRelocData()->end(); ++reloc) {
718        if (llvm::ELF::R_MIPS_26 != reloc->type())
719          continue;
720
721        if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc)))
722          isRelaxed = true;
723      }
724    }
725  }
726
727  SectionData* textData = getOutputFormat()->getText().getSectionData();
728
729  // find the first fragment w/ invalid offset due to stub insertion
730  Fragment* invalid = NULL;
731  pFinished = true;
732  for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(),
733                                     ie = getBRIslandFactory()->end();
734       ii != ie; ++ii)
735  {
736    BranchIsland& island = *ii;
737    if (island.end() == textData->end())
738      break;
739
740    Fragment* exit = island.end();
741    if ((island.offset() + island.size()) > exit->getOffset()) {
742      invalid = exit;
743      pFinished = false;
744      break;
745    }
746  }
747
748  // reset the offset of invalid fragments
749  while (NULL != invalid) {
750    invalid->setOffset(invalid->getPrevNode()->getOffset() +
751                       invalid->getPrevNode()->size());
752    invalid = invalid->getNextNode();
753  }
754
755  // reset the size of .text
756  if (isRelaxed)
757    getOutputFormat()->getText().setSize(textData->back().getOffset() +
758                                         textData->back().size());
759
760  return isRelaxed;
761}
762
763bool MipsGNULDBackend::initTargetStubs()
764{
765  if (NULL == getStubFactory())
766    return false;
767
768  getStubFactory()->addPrototype(new MipsLA25Stub(*this));
769  return true;
770}
771
772bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel,
773                                      Relocation::Type& pType,
774                                      uint32_t& pSymIdx,
775                                      uint32_t& pOffset) const
776{
777  return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset);
778}
779
780bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel,
781                                      Relocation::Type& pType,
782                                      uint32_t& pSymIdx,
783                                      uint32_t& pOffset,
784                                      int32_t& pAddend) const
785{
786  return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
787}
788
789bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel,
790                                      Relocation::Type& pType,
791                                      uint32_t& pSymIdx,
792                                      uint64_t& pOffset) const
793{
794  uint64_t r_info = 0x0;
795  if (llvm::sys::IsLittleEndianHost) {
796    pOffset = pRel.r_offset;
797    r_info  = pRel.r_info;
798  }
799  else {
800    pOffset = mcld::bswap64(pRel.r_offset);
801    r_info  = mcld::bswap64(pRel.r_info);
802  }
803
804  // MIPS 64 little endian (we do not support big endian now)
805  // has a "special" encoding of r_info relocation
806  // field. Instead of one 64 bit little endian number, it is a little
807  // endian 32 bit number followed by a 32 bit big endian number.
808  pType = mcld::bswap32(r_info >> 32);
809  pSymIdx = r_info & 0xffffffff;
810  return true;
811}
812
813bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel,
814                                      Relocation::Type& pType,
815                                      uint32_t& pSymIdx,
816                                      uint64_t& pOffset,
817                                      int64_t& pAddend) const
818{
819  uint64_t r_info = 0x0;
820  if (llvm::sys::IsLittleEndianHost) {
821    pOffset = pRel.r_offset;
822    r_info  = pRel.r_info;
823    pAddend = pRel.r_addend;
824  }
825  else {
826    pOffset = mcld::bswap64(pRel.r_offset);
827    r_info  = mcld::bswap64(pRel.r_info);
828    pAddend = mcld::bswap64(pRel.r_addend);
829  }
830
831  pType = mcld::bswap32(r_info >> 32);
832  pSymIdx = r_info & 0xffffffff;
833  return true;
834}
835
836void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel,
837                                      Relocation::Type pType,
838                                      uint32_t pSymIdx,
839                                      uint32_t pOffset) const
840{
841  GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset);
842}
843
844void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel,
845                                      Relocation::Type pType,
846                                      uint32_t pSymIdx,
847                                      uint32_t pOffset,
848                                      int32_t pAddend) const
849{
850  GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
851}
852
853void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel,
854                                      Relocation::Type pType,
855                                      uint32_t pSymIdx,
856                                      uint64_t pOffset) const
857{
858  uint64_t r_info = mcld::bswap32(pType);
859  r_info <<= 32;
860  r_info |= pSymIdx;
861
862  pRel.r_info = r_info;
863  pRel.r_offset = pOffset;
864}
865
866void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel,
867                                      Relocation::Type pType,
868                                      uint32_t pSymIdx,
869                                      uint64_t pOffset,
870                                      int64_t pAddend) const
871{
872  uint64_t r_info = mcld::bswap32(pType);
873  r_info <<= 32;
874  r_info |= pSymIdx;
875
876  pRel.r_info = r_info;
877  pRel.r_offset = pOffset;
878  pRel.r_addend = pAddend;
879}
880
881//===----------------------------------------------------------------------===//
882// Mips32GNULDBackend
883//===----------------------------------------------------------------------===//
884Mips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig,
885                                       MipsGNUInfo* pInfo)
886  : MipsGNULDBackend(pConfig, pInfo)
887{}
888
889bool Mips32GNULDBackend::initRelocator()
890{
891  if (NULL == m_pRelocator)
892    m_pRelocator = new Mips32Relocator(*this, config());
893
894  return true;
895}
896
897void Mips32GNULDBackend::initTargetSections(Module& pModule,
898                                            ObjectBuilder& pBuilder)
899{
900  MipsGNULDBackend::initTargetSections(pModule, pBuilder);
901
902  if (LinkerConfig::Object == config().codeGenType())
903    return;
904
905  ELFFileFormat* fileFormat = getOutputFormat();
906
907  // initialize .got
908  LDSection& got = fileFormat->getGOT();
909  m_pGOT = new Mips32GOT(got);
910
911  // initialize .got.plt
912  LDSection& gotplt = fileFormat->getGOTPLT();
913  m_pGOTPLT = new MipsGOTPLT(gotplt);
914
915  // initialize .plt
916  LDSection& plt = fileFormat->getPLT();
917  m_pPLT = new MipsPLT(plt);
918}
919
920size_t Mips32GNULDBackend::getRelEntrySize()
921{
922  return 8;
923}
924
925size_t Mips32GNULDBackend::getRelaEntrySize()
926{
927  return 12;
928}
929
930//===----------------------------------------------------------------------===//
931// Mips64GNULDBackend
932//===----------------------------------------------------------------------===//
933Mips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig,
934                                       MipsGNUInfo* pInfo)
935  : MipsGNULDBackend(pConfig, pInfo)
936{}
937
938bool Mips64GNULDBackend::initRelocator()
939{
940  if (NULL == m_pRelocator)
941    m_pRelocator = new Mips64Relocator(*this, config());
942
943  return true;
944}
945
946void Mips64GNULDBackend::initTargetSections(Module& pModule,
947                                            ObjectBuilder& pBuilder)
948{
949  MipsGNULDBackend::initTargetSections(pModule, pBuilder);
950
951  if (LinkerConfig::Object == config().codeGenType())
952    return;
953
954  ELFFileFormat* fileFormat = getOutputFormat();
955
956  // initialize .got
957  LDSection& got = fileFormat->getGOT();
958  m_pGOT = new Mips64GOT(got);
959
960  // initialize .got.plt
961  LDSection& gotplt = fileFormat->getGOTPLT();
962  m_pGOTPLT = new MipsGOTPLT(gotplt);
963
964  // initialize .plt
965  LDSection& plt = fileFormat->getPLT();
966  m_pPLT = new MipsPLT(plt);
967}
968
969size_t Mips64GNULDBackend::getRelEntrySize()
970{
971  return 16;
972}
973
974size_t Mips64GNULDBackend::getRelaEntrySize()
975{
976  return 24;
977}
978
979//===----------------------------------------------------------------------===//
980/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
981///
982static TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig)
983{
984  const llvm::Triple& triple = pConfig.targets().triple();
985
986  if (triple.isOSDarwin()) {
987    assert(0 && "MachO linker is not supported yet");
988  }
989  if (triple.isOSWindows()) {
990    assert(0 && "COFF linker is not supported yet");
991  }
992
993  llvm::Triple::ArchType arch = triple.getArch();
994
995  if (llvm::Triple::mips64el == arch)
996    return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple));
997
998  assert (arch == llvm::Triple::mipsel);
999  return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple));
1000}
1001
1002//===----------------------------------------------------------------------===//
1003// Force static initialization.
1004//===----------------------------------------------------------------------===//
1005extern "C" void MCLDInitializeMipsLDBackend() {
1006  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
1007                                                createMipsLDBackend);
1008  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget,
1009                                                createMipsLDBackend);
1010}
1011