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