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
10#include "Mips.h"
11#include "MipsELFDynamic.h"
12#include "MipsLDBackend.h"
13#include "MipsRelocationFactory.h"
14
15#include <llvm/ADT/Triple.h>
16#include <llvm/Support/ELF.h>
17
18#include <mcld/LD/FillFragment.h>
19#include <mcld/LD/SectionMap.h>
20#include <mcld/MC/MCLDInfo.h>
21#include <mcld/MC/MCLinker.h>
22#include <mcld/Support/MemoryRegion.h>
23#include <mcld/Support/MsgHandling.h>
24#include <mcld/Support/TargetRegistry.h>
25#include <mcld/Target/OutputRelocSection.h>
26
27enum {
28  // The original o32 abi.
29  E_MIPS_ABI_O32    = 0x00001000,
30  // O32 extended to work on 64 bit architectures.
31  E_MIPS_ABI_O64    = 0x00002000,
32  // EABI in 32 bit mode.
33  E_MIPS_ABI_EABI32 = 0x00003000,
34  // EABI in 64 bit mode.
35  E_MIPS_ABI_EABI64 = 0x00004000
36};
37
38namespace mcld {
39
40MipsGNULDBackend::MipsGNULDBackend()
41  : m_pRelocFactory(NULL),
42    m_pGOT(NULL),
43    m_pRelDyn(NULL),
44    m_pDynamic(NULL),
45    m_pGOTSymbol(NULL),
46    m_pGpDispSymbol(NULL)
47{
48}
49
50MipsGNULDBackend::~MipsGNULDBackend()
51{
52  if (NULL != m_pRelocFactory)
53    delete m_pRelocFactory;
54  if (NULL != m_pGOT)
55    delete m_pGOT;
56  if (NULL != m_pRelDyn)
57    delete m_pRelDyn;
58  if (NULL != m_pDynamic)
59    delete m_pDynamic;
60}
61
62bool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
63{
64  // Nothing to do because we do not support
65  // any MIPS specific sections now.
66  return true;
67}
68
69void MipsGNULDBackend::initTargetSections(MCLinker& pLinker)
70{
71}
72
73void MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker, const Output& pOutput)
74{
75  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
76  // same name in input
77  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
78                   "_GLOBAL_OFFSET_TABLE_",
79                   false,
80                   ResolveInfo::Object,
81                   ResolveInfo::Define,
82                   ResolveInfo::Local,
83                   0x0,  // size
84                   0x0,  // value
85                   NULL, // FragRef
86                   ResolveInfo::Hidden);
87
88  m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
89                   "_gp_disp",
90                   false,
91                   ResolveInfo::Section,
92                   ResolveInfo::Define,
93                   ResolveInfo::Absolute,
94                   0x0,  // size
95                   0x0,  // value
96                   NULL, // FragRef
97                   ResolveInfo::Default);
98
99  if (NULL != m_pGpDispSymbol) {
100    m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
101  }
102}
103
104bool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker)
105{
106  if (NULL == m_pRelocFactory) {
107    m_pRelocFactory = new MipsRelocationFactory(1024, *this);
108    m_pRelocFactory->setLayout(pLinker.getLayout());
109  }
110  return true;
111}
112
113RelocationFactory* MipsGNULDBackend::getRelocFactory()
114{
115  assert(NULL != m_pRelocFactory);
116  return m_pRelocFactory;
117}
118
119void MipsGNULDBackend::scanRelocation(Relocation& pReloc,
120                                      const LDSymbol& pInputSym,
121                                      MCLinker& pLinker,
122                                      const MCLDInfo& pLDInfo,
123                                      const Output& pOutput,
124                                      const LDSection& pSection)
125{
126  // rsym - The relocation target symbol
127  ResolveInfo* rsym = pReloc.symInfo();
128  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
129
130  assert(NULL != pSection.getLink());
131  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) {
132    if (rsym->isLocal()) {
133      updateAddend(pReloc, pInputSym, pLinker.getLayout());
134    }
135    return;
136  }
137
138  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies
139  // that a .got section is needed.
140  if (NULL == m_pGOT && NULL != m_pGOTSymbol) {
141    if (rsym == m_pGOTSymbol->resolveInfo()) {
142      createGOT(pLinker, pOutput);
143    }
144  }
145
146  // Skip relocation against _gp_disp
147  if (strcmp("_gp_disp", pInputSym.name()) == 0)
148    return;
149
150  // We test isLocal or if pInputSym is not a dynamic symbol
151  // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn()
152  // Don't put undef symbols into local entries.
153  if ((rsym->isLocal() || !isDynamicSymbol(pInputSym, pOutput) ||
154      !rsym->isDyn()) && !rsym->isUndef())
155    scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
156  else
157    scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
158}
159
160uint32_t MipsGNULDBackend::machine() const
161{
162  return llvm::ELF::EM_MIPS;
163}
164
165uint8_t MipsGNULDBackend::OSABI() const
166{
167  return llvm::ELF::ELFOSABI_NONE;
168}
169
170uint8_t MipsGNULDBackend::ABIVersion() const
171{
172  return 0;
173}
174
175uint64_t MipsGNULDBackend::flags() const
176{
177  // TODO: (simon) The correct flag's set depend on command line
178  // arguments and flags from input .o files.
179  return llvm::ELF::EF_MIPS_ARCH_32R2 |
180         llvm::ELF::EF_MIPS_NOREORDER |
181         llvm::ELF::EF_MIPS_PIC |
182         llvm::ELF::EF_MIPS_CPIC |
183         E_MIPS_ABI_O32;
184}
185
186bool MipsGNULDBackend::isLittleEndian() const
187{
188  // Now we support little endian (mipsel) target only.
189  return true;
190}
191
192unsigned int MipsGNULDBackend::bitclass() const
193{
194  return 32;
195}
196
197uint64_t MipsGNULDBackend::defaultTextSegmentAddr() const
198{
199  return 0x80000;
200}
201
202uint64_t MipsGNULDBackend::abiPageSize(const MCLDInfo& pInfo) const
203{
204  if (pInfo.options().maxPageSize() > 0)
205    return pInfo.options().maxPageSize();
206  else
207    return static_cast<uint64_t>(0x10000);
208}
209
210void MipsGNULDBackend::doPreLayout(const Output& pOutput,
211                                   const MCLDInfo& pInfo,
212                                   MCLinker& pLinker)
213{
214  // when building shared object, the .got section is must.
215  if (pOutput.type() == Output::DynObj && NULL == m_pGOT) {
216      createGOT(pLinker, pOutput);
217  }
218}
219
220void MipsGNULDBackend::doPostLayout(const Output& pOutput,
221                                    const MCLDInfo& pInfo,
222                                    MCLinker& pLinker)
223{
224}
225
226/// dynamic - the dynamic section of the target machine.
227/// Use co-variant return type to return its own dynamic section.
228MipsELFDynamic& MipsGNULDBackend::dynamic()
229{
230  if (NULL == m_pDynamic)
231    m_pDynamic = new MipsELFDynamic(*this);
232
233  return *m_pDynamic;
234}
235
236/// dynamic - the dynamic section of the target machine.
237/// Use co-variant return type to return its own dynamic section.
238const MipsELFDynamic& MipsGNULDBackend::dynamic() const
239{
240  assert( NULL != m_pDynamic);
241  return *m_pDynamic;
242}
243
244uint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput,
245                                           const LDSection& pSection,
246                                           const MCLDInfo& pInfo,
247                                           const Layout& pLayout,
248                                           MemoryRegion& pRegion) const
249{
250  assert(pRegion.size() && "Size of MemoryRegion is zero!");
251
252  const ELFFileFormat* file_format = getOutputFormat(pOutput);
253
254  if (&pSection == &(file_format->getGOT())) {
255    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
256    uint64_t result = m_pGOT->emit(pRegion);
257    return result;
258  }
259
260  fatal(diag::unrecognized_output_sectoin)
261          << pSection.name()
262          << "mclinker@googlegroups.com";
263  return 0;
264}
265/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
266bool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const
267{
268  return std::find(m_GlobalGOTSyms.begin(),
269                   m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
270}
271
272/// emitDynamicSymbol - emit dynamic symbol.
273void MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
274                                         Output& pOutput,
275                                         LDSymbol& pSymbol,
276                                         const Layout& pLayout,
277                                         char* strtab,
278                                         size_t strtabsize,
279                                         size_t symtabIdx)
280{
281  // maintain output's symbol and index map
282  bool sym_exist = false;
283  HashTableType::entry_type* entry = 0;
284  entry = m_pSymIndexMap->insert(&pSymbol, sym_exist);
285  entry->setValue(symtabIdx);
286
287  // FIXME: check the endian between host and target
288  // write out symbol
289  sym32.st_name  = strtabsize;
290  sym32.st_value = pSymbol.value();
291  sym32.st_size  = getSymbolSize(pSymbol);
292  sym32.st_info  = getSymbolInfo(pSymbol);
293  sym32.st_other = pSymbol.visibility();
294  sym32.st_shndx = getSymbolShndx(pSymbol, pLayout);
295  // write out string
296  strcpy((strtab + strtabsize), pSymbol.name());
297}
298
299/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
300///
301/// the size of these tables should be computed before layout
302/// layout should computes the start offset of these tables
303void MipsGNULDBackend::emitDynNamePools(Output& pOutput,
304                                        SymbolCategory& pSymbols,
305                                        const Layout& pLayout,
306                                        const MCLDInfo& pLDInfo)
307{
308  assert(pOutput.hasMemArea());
309  ELFFileFormat* file_format = getOutputFormat(pOutput);
310
311  LDSection& symtab_sect = file_format->getDynSymTab();
312  LDSection& strtab_sect = file_format->getDynStrTab();
313  LDSection& hash_sect   = file_format->getHashTab();
314  LDSection& dyn_sect    = file_format->getDynamic();
315
316  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
317                                                           symtab_sect.size());
318  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
319                                                           strtab_sect.size());
320  MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
321                                                         hash_sect.size());
322  MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
323                                                        dyn_sect.size());
324  // set up symtab_region
325  llvm::ELF::Elf32_Sym* symtab32 = NULL;
326  symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
327
328  symtab32[0].st_name  = 0;
329  symtab32[0].st_value = 0;
330  symtab32[0].st_size  = 0;
331  symtab32[0].st_info  = 0;
332  symtab32[0].st_other = 0;
333  symtab32[0].st_shndx = 0;
334
335  // set up strtab_region
336  char* strtab = (char*)strtab_region->start();
337  strtab[0] = '\0';
338
339  bool sym_exist = false;
340  HashTableType::entry_type* entry = 0;
341
342  // add index 0 symbol into SymIndexMap
343  entry = m_pSymIndexMap->insert(NULL, sym_exist);
344  entry->setValue(0);
345
346  size_t symtabIdx = 1;
347  size_t strtabsize = 1;
348
349  // emit of .dynsym, and .dynstr except GOT entries
350  for (SymbolCategory::iterator symbol = pSymbols.begin(),
351       sym_end = pSymbols.end(); symbol != sym_end; ++symbol) {
352    if (!isDynamicSymbol(**symbol, pOutput))
353      continue;
354
355    if (isGlobalGOTSymbol(**symbol))
356      continue;
357
358    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
359                      strtabsize, symtabIdx);
360
361    // sum up counters
362    ++symtabIdx;
363    strtabsize += (*symbol)->nameSize() + 1;
364  }
365
366  // emit global GOT
367  for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
368       symbol_end = m_GlobalGOTSyms.end();
369       symbol != symbol_end; ++symbol) {
370
371    // Make sure this golbal GOT entry is a dynamic symbol.
372    // If not, something is wrong earlier when putting this symbol into
373    //  global GOT.
374    if (!isDynamicSymbol(**symbol, pOutput))
375      fatal(diag::mips_got_symbol) << (*symbol)->name();
376
377    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
378                      strtabsize, symtabIdx);
379
380    // sum up counters
381    ++symtabIdx;
382    strtabsize += (*symbol)->nameSize() + 1;
383  }
384
385  // emit DT_NEED
386  // add DT_NEED strings into .dynstr
387  // Rules:
388  //   1. ignore --no-add-needed
389  //   2. force count in --no-as-needed
390  //   3. judge --as-needed
391  ELFDynamic::iterator dt_need = dynamic().needBegin();
392  InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
393  for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
394    if (Input::DynObj == (*input)->type()) {
395      // --add-needed
396      if ((*input)->attribute()->isAddNeeded()) {
397        // --no-as-needed
398        if (!(*input)->attribute()->isAsNeeded()) {
399          strcpy((strtab + strtabsize), (*input)->name().c_str());
400          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
401          strtabsize += (*input)->name().size() + 1;
402          ++dt_need;
403        }
404        // --as-needed
405        else if ((*input)->isNeeded()) {
406          strcpy((strtab + strtabsize), (*input)->name().c_str());
407          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
408          strtabsize += (*input)->name().size() + 1;
409          ++dt_need;
410        }
411      }
412    }
413  } // for
414
415  // emit soname
416  // initialize value of ELF .dynamic section
417  if (Output::DynObj == pOutput.type())
418    dynamic().applySoname(strtabsize);
419  dynamic().applyEntries(pLDInfo, *file_format);
420  dynamic().emit(dyn_sect, *dyn_region);
421
422  strcpy((strtab + strtabsize), pOutput.name().c_str());
423  strtabsize += pOutput.name().size() + 1;
424
425  // emit hash table
426  // FIXME: this verion only emit SVR4 hash section.
427  //        Please add GNU new hash section
428
429  // both 32 and 64 bits hash table use 32-bit entry
430  // set up hash_region
431  uint32_t* word_array = (uint32_t*)hash_region->start();
432  uint32_t& nbucket = word_array[0];
433  uint32_t& nchain  = word_array[1];
434
435  nbucket = getHashBucketCount(symtabIdx, false);
436  nchain  = symtabIdx;
437
438  uint32_t* bucket = (word_array + 2);
439  uint32_t* chain  = (bucket + nbucket);
440
441  // initialize bucket
442  bzero((void*)bucket, nbucket);
443
444  StringHash<ELF> hash_func;
445
446  for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
447    llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
448    size_t bucket_pos = hash_func(name) % nbucket;
449    chain[sym_idx] = bucket[bucket_pos];
450    bucket[bucket_pos] = sym_idx;
451  }
452
453}
454
455MipsGOT& MipsGNULDBackend::getGOT()
456{
457  assert(NULL != m_pGOT);
458  return *m_pGOT;
459}
460
461const MipsGOT& MipsGNULDBackend::getGOT() const
462{
463  assert(NULL != m_pGOT);
464  return *m_pGOT;
465}
466
467OutputRelocSection& MipsGNULDBackend::getRelDyn()
468{
469  assert(NULL != m_pRelDyn);
470  return *m_pRelDyn;
471}
472
473const OutputRelocSection& MipsGNULDBackend::getRelDyn() const
474{
475  assert(NULL != m_pRelDyn);
476  return *m_pRelDyn;
477}
478
479unsigned int
480MipsGNULDBackend::getTargetSectionOrder(const Output& pOutput,
481                                        const LDSection& pSectHdr,
482                                        const MCLDInfo& pInfo) const
483{
484  const ELFFileFormat* file_format = getOutputFormat(pOutput);
485
486  if (&pSectHdr == &file_format->getGOT())
487    return SHO_DATA;
488
489  return SHO_UNDEFINED;
490}
491
492/// finalizeSymbol - finalize the symbol value
493bool MipsGNULDBackend::finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput)
494{
495  if (NULL != m_pGpDispSymbol)
496    m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
497  return true;
498}
499
500/// allocateCommonSymbols - allocate common symbols in the corresponding
501/// sections.
502/// @refer Google gold linker: common.cc: 214
503/// FIXME: Mips needs to allocate small common symbol
504bool
505MipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
506{
507  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
508
509  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
510    return true;
511
512  SymbolCategory::iterator com_sym, com_end;
513
514  // FIXME: If the order of common symbols is defined, then sort common symbols
515  // std::sort(com_sym, com_end, some kind of order);
516
517  // get or create corresponding BSS LDSection
518  LDSection* bss_sect = &pLinker.getOrCreateOutputSectHdr(".bss",
519                                   LDFileFormat::BSS,
520                                   llvm::ELF::SHT_NOBITS,
521                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
522
523  LDSection* tbss_sect = &pLinker.getOrCreateOutputSectHdr(
524                                   ".tbss",
525                                   LDFileFormat::BSS,
526                                   llvm::ELF::SHT_NOBITS,
527                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
528
529  // FIXME: .sbss amd .lbss currently unused.
530  /*
531  LDSection* sbss_sect = &pLinker.getOrCreateOutputSectHdr(
532                                   ".sbss",
533                                   LDFileFormat::BSS,
534                                   llvm::ELF::SHT_NOBITS,
535                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC |
536                                   llvm::ELF::SHF_MIPS_GPREL);
537
538  LDSection* lbss_sect = &pLinker.getOrCreateOutputSectHdr(
539                                   ".lbss",
540                                   LDFileFormat::BSS,
541                                   llvm::ELF::SHT_NOBITS,
542                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC |
543                                   llvm::ELF::SHF_MIPS_LOCAL);
544  */
545
546  assert(NULL != bss_sect && NULL != tbss_sect);
547
548  // get or create corresponding BSS SectionData
549  SectionData& bss_sect_data = pLinker.getOrCreateSectData(*bss_sect);
550  SectionData& tbss_sect_data = pLinker.getOrCreateSectData(*tbss_sect);
551
552  // remember original BSS size
553  uint64_t bss_offset  = bss_sect->size();
554  uint64_t tbss_offset = tbss_sect->size();
555
556  // allocate all local common symbols
557  com_end = symbol_list.localEnd();
558
559  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
560    if (ResolveInfo::Common == (*com_sym)->desc()) {
561      // We have to reset the description of the symbol here. When doing
562      // incremental linking, the output relocatable object may have common
563      // symbols. Therefore, we can not treat common symbols as normal symbols
564      // when emitting the regular name pools. We must change the symbols'
565      // description here.
566      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
567      Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
568      (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
569
570      if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
571        // allocate TLS common symbol in tbss section
572        tbss_offset += pLinker.getLayout().appendFragment(*frag,
573                                                          tbss_sect_data,
574                                                          (*com_sym)->value());
575      }
576      // FIXME: how to identify small and large common symbols?
577      else {
578        bss_offset += pLinker.getLayout().appendFragment(*frag,
579                                                         bss_sect_data,
580                                                         (*com_sym)->value());
581      }
582    }
583  }
584
585  // allocate all global common symbols
586  com_end = symbol_list.commonEnd();
587  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
588    // We have to reset the description of the symbol here. When doing
589    // incremental linking, the output relocatable object may have common
590    // symbols. Therefore, we can not treat common symbols as normal symbols
591    // when emitting the regular name pools. We must change the symbols'
592    // description here.
593    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
594    Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
595    (*com_sym)->setFragmentRef(new FragmentRef(*frag, 0));
596
597    if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
598      // allocate TLS common symbol in tbss section
599      tbss_offset += pLinker.getLayout().appendFragment(*frag,
600                                                        tbss_sect_data,
601                                                        (*com_sym)->value());
602    }
603    // FIXME: how to identify small and large common symbols?
604    else {
605      bss_offset += pLinker.getLayout().appendFragment(*frag,
606                                                       bss_sect_data,
607                                                       (*com_sym)->value());
608    }
609  }
610
611  bss_sect->setSize(bss_offset);
612  tbss_sect->setSize(tbss_offset);
613  symbol_list.changeCommonsToGlobal();
614  return true;
615}
616
617void MipsGNULDBackend::updateAddend(Relocation& pReloc,
618                                   const LDSymbol& pInputSym,
619                                   const Layout& pLayout) const
620{
621  // Update value keep in addend if we meet a section symbol
622  if (pReloc.symInfo()->type() == ResolveInfo::Section) {
623    pReloc.setAddend(pLayout.getOutputOffset(
624                     *pInputSym.fragRef()) + pReloc.addend());
625  }
626}
627
628void MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
629                                      const LDSymbol& pInputSym,
630                                      MCLinker& pLinker,
631                                      const MCLDInfo& pLDInfo,
632                                      const Output& pOutput)
633{
634  ResolveInfo* rsym = pReloc.symInfo();
635
636  updateAddend(pReloc, pInputSym, pLinker.getLayout());
637
638  switch (pReloc.type()){
639    case llvm::ELF::R_MIPS_NONE:
640    case llvm::ELF::R_MIPS_16:
641      break;
642    case llvm::ELF::R_MIPS_32:
643      if (Output::DynObj == pOutput.type()) {
644        // TODO: (simon) The gold linker does not create an entry in .rel.dyn
645        // section if the symbol section flags contains SHF_EXECINSTR.
646        // 1. Find the reason of this condition.
647        // 2. Check this condition here.
648        if (NULL == m_pRelDyn)
649          createRelDyn(pLinker, pOutput);
650
651        m_pRelDyn->reserveEntry(*m_pRelocFactory);
652        rsym->setReserved(rsym->reserved() | ReserveRel);
653
654        // Remeber this rsym is a local GOT entry (as if it needs an entry).
655        // Actually we don't allocate an GOT entry.
656        if (NULL == m_pGOT)
657          createGOT(pLinker, pOutput);
658        m_pGOT->setLocal(rsym);
659      }
660      break;
661    case llvm::ELF::R_MIPS_REL32:
662    case llvm::ELF::R_MIPS_26:
663    case llvm::ELF::R_MIPS_HI16:
664    case llvm::ELF::R_MIPS_LO16:
665    case llvm::ELF::R_MIPS_PC16:
666    case llvm::ELF::R_MIPS_SHIFT5:
667    case llvm::ELF::R_MIPS_SHIFT6:
668    case llvm::ELF::R_MIPS_64:
669    case llvm::ELF::R_MIPS_GOT_PAGE:
670    case llvm::ELF::R_MIPS_GOT_OFST:
671    case llvm::ELF::R_MIPS_SUB:
672    case llvm::ELF::R_MIPS_INSERT_A:
673    case llvm::ELF::R_MIPS_INSERT_B:
674    case llvm::ELF::R_MIPS_DELETE:
675    case llvm::ELF::R_MIPS_HIGHER:
676    case llvm::ELF::R_MIPS_HIGHEST:
677    case llvm::ELF::R_MIPS_SCN_DISP:
678    case llvm::ELF::R_MIPS_REL16:
679    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
680    case llvm::ELF::R_MIPS_PJUMP:
681    case llvm::ELF::R_MIPS_RELGOT:
682    case llvm::ELF::R_MIPS_JALR:
683    case llvm::ELF::R_MIPS_GLOB_DAT:
684    case llvm::ELF::R_MIPS_COPY:
685    case llvm::ELF::R_MIPS_JUMP_SLOT:
686      break;
687    case llvm::ELF::R_MIPS_GOT16:
688    case llvm::ELF::R_MIPS_CALL16:
689      if (NULL == m_pGOT)
690        createGOT(pLinker, pOutput);
691
692      // For got16 section based relocations, we need to reserve got entries.
693      if (rsym->type() == ResolveInfo::Section) {
694        m_pGOT->reserveLocalEntry();
695        // Remeber this rsym is a local GOT entry
696        m_pGOT->setLocal(rsym);
697        return;
698      }
699
700      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
701        m_pGOT->reserveLocalEntry();
702        rsym->setReserved(rsym->reserved() | ReserveGot);
703        // Remeber this rsym is a local GOT entry
704        m_pGOT->setLocal(rsym);
705      }
706      break;
707    case llvm::ELF::R_MIPS_GPREL32:
708    case llvm::ELF::R_MIPS_GPREL16:
709    case llvm::ELF::R_MIPS_LITERAL:
710      break;
711    case llvm::ELF::R_MIPS_GOT_DISP:
712    case llvm::ELF::R_MIPS_GOT_HI16:
713    case llvm::ELF::R_MIPS_CALL_HI16:
714    case llvm::ELF::R_MIPS_GOT_LO16:
715    case llvm::ELF::R_MIPS_CALL_LO16:
716      break;
717    case llvm::ELF::R_MIPS_TLS_DTPMOD32:
718    case llvm::ELF::R_MIPS_TLS_DTPREL32:
719    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
720    case llvm::ELF::R_MIPS_TLS_DTPREL64:
721    case llvm::ELF::R_MIPS_TLS_GD:
722    case llvm::ELF::R_MIPS_TLS_LDM:
723    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
724    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
725    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
726    case llvm::ELF::R_MIPS_TLS_TPREL32:
727    case llvm::ELF::R_MIPS_TLS_TPREL64:
728    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
729    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
730      break;
731    default:
732      fatal(diag::unknown_relocation) << (int)pReloc.type()
733                                      << pReloc.symInfo()->name();
734  }
735}
736
737void MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
738                                       const LDSymbol& pInputSym,
739                                       MCLinker& pLinker,
740                                       const MCLDInfo& pLDInfo,
741                                       const Output& pOutput)
742{
743  ResolveInfo* rsym = pReloc.symInfo();
744
745  switch (pReloc.type()){
746    case llvm::ELF::R_MIPS_NONE:
747    case llvm::ELF::R_MIPS_INSERT_A:
748    case llvm::ELF::R_MIPS_INSERT_B:
749    case llvm::ELF::R_MIPS_DELETE:
750    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
751    case llvm::ELF::R_MIPS_TLS_DTPREL64:
752    case llvm::ELF::R_MIPS_REL16:
753    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
754    case llvm::ELF::R_MIPS_PJUMP:
755    case llvm::ELF::R_MIPS_RELGOT:
756    case llvm::ELF::R_MIPS_TLS_TPREL64:
757      break;
758    case llvm::ELF::R_MIPS_32:
759    case llvm::ELF::R_MIPS_64:
760    case llvm::ELF::R_MIPS_HI16:
761    case llvm::ELF::R_MIPS_LO16:
762      if (symbolNeedsDynRel(*rsym, false, pLDInfo, pOutput, true)) {
763        if (NULL == m_pRelDyn)
764          createRelDyn(pLinker, pOutput);
765
766        m_pRelDyn->reserveEntry(*m_pRelocFactory);
767        rsym->setReserved(rsym->reserved() | ReserveRel);
768
769        // Remeber this rsym is a global GOT entry (as if it needs an entry).
770        // Actually we don't allocate an GOT entry.
771        if (NULL == m_pGOT)
772          createGOT(pLinker, pOutput);
773        m_pGOT->setGlobal(rsym);
774      }
775      break;
776    case llvm::ELF::R_MIPS_GOT16:
777    case llvm::ELF::R_MIPS_CALL16:
778    case llvm::ELF::R_MIPS_GOT_DISP:
779    case llvm::ELF::R_MIPS_GOT_HI16:
780    case llvm::ELF::R_MIPS_CALL_HI16:
781    case llvm::ELF::R_MIPS_GOT_LO16:
782    case llvm::ELF::R_MIPS_CALL_LO16:
783    case llvm::ELF::R_MIPS_GOT_PAGE:
784    case llvm::ELF::R_MIPS_GOT_OFST:
785      if (NULL == m_pGOT)
786        createGOT(pLinker, pOutput);
787
788      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
789        m_pGOT->reserveGlobalEntry();
790        rsym->setReserved(rsym->reserved() | ReserveGot);
791        m_GlobalGOTSyms.push_back(rsym->outSymbol());
792        // Remeber this rsym is a global GOT entry
793        m_pGOT->setGlobal(rsym);
794      }
795      break;
796    case llvm::ELF::R_MIPS_LITERAL:
797    case llvm::ELF::R_MIPS_GPREL32:
798      fatal(diag::invalid_global_relocation) << (int)pReloc.type()
799                                             << pReloc.symInfo()->name();
800      break;
801    case llvm::ELF::R_MIPS_GPREL16:
802      break;
803    case llvm::ELF::R_MIPS_26:
804    case llvm::ELF::R_MIPS_PC16:
805      break;
806    case llvm::ELF::R_MIPS_16:
807    case llvm::ELF::R_MIPS_SHIFT5:
808    case llvm::ELF::R_MIPS_SHIFT6:
809    case llvm::ELF::R_MIPS_SUB:
810    case llvm::ELF::R_MIPS_HIGHER:
811    case llvm::ELF::R_MIPS_HIGHEST:
812    case llvm::ELF::R_MIPS_SCN_DISP:
813      break;
814    case llvm::ELF::R_MIPS_TLS_DTPREL32:
815    case llvm::ELF::R_MIPS_TLS_GD:
816    case llvm::ELF::R_MIPS_TLS_LDM:
817    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
818    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
819    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
820    case llvm::ELF::R_MIPS_TLS_TPREL32:
821    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
822    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
823      break;
824    case llvm::ELF::R_MIPS_REL32:
825      break;
826    case llvm::ELF::R_MIPS_JALR:
827      break;
828    case llvm::ELF::R_MIPS_COPY:
829    case llvm::ELF::R_MIPS_GLOB_DAT:
830    case llvm::ELF::R_MIPS_JUMP_SLOT:
831      fatal(diag::dynamic_relocation) << (int)pReloc.type();
832      break;
833    default:
834      fatal(diag::unknown_relocation) << (int)pReloc.type()
835                                      << pReloc.symInfo()->name();
836  }
837}
838
839void MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput)
840{
841  ELFFileFormat* file_format = getOutputFormat(pOutput);
842
843  LDSection& got = file_format->getGOT();
844  m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got));
845
846  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
847  if ( m_pGOTSymbol != NULL ) {
848    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
849                     "_GLOBAL_OFFSET_TABLE_",
850                     false,
851                     ResolveInfo::Object,
852                     ResolveInfo::Define,
853                     ResolveInfo::Local,
854                     0x0, // size
855                     0x0, // value
856                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
857                     ResolveInfo::Hidden);
858  }
859  else {
860    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
861                     "_GLOBAL_OFFSET_TABLE_",
862                     false,
863                     ResolveInfo::Object,
864                     ResolveInfo::Define,
865                     ResolveInfo::Local,
866                     0x0, // size
867                     0x0, // value
868                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
869                     ResolveInfo::Hidden);
870  }
871}
872
873void MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput)
874{
875  ELFFileFormat* file_format = getOutputFormat(pOutput);
876
877  // get .rel.dyn LDSection and create SectionData
878  LDSection& reldyn = file_format->getRelDyn();
879  // create SectionData and ARMRelDynSection
880  m_pRelDyn = new OutputRelocSection(reldyn,
881                                     pLinker.getOrCreateSectData(reldyn),
882                                     8);
883}
884
885//===----------------------------------------------------------------------===//
886/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
887///
888static TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
889                                            const std::string& pTriple)
890{
891  llvm::Triple theTriple(pTriple);
892  if (theTriple.isOSDarwin()) {
893    assert(0 && "MachO linker is not supported yet");
894  }
895  if (theTriple.isOSWindows()) {
896    assert(0 && "COFF linker is not supported yet");
897  }
898  return new MipsGNULDBackend();
899}
900
901} // namespace of mcld
902
903//=============================
904// Force static initialization.
905extern "C" void LLVMInitializeMipsLDBackend() {
906  // Register the linker backend
907  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
908                                                mcld::createMipsLDBackend);
909}
910