• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "mcld/IRBuilder.h"
17 #include "mcld/LinkerConfig.h"
18 #include "mcld/Module.h"
19 #include "mcld/Fragment/AlignFragment.h"
20 #include "mcld/Fragment/FillFragment.h"
21 #include "mcld/LD/BranchIslandFactory.h"
22 #include "mcld/LD/LDContext.h"
23 #include "mcld/LD/StubFactory.h"
24 #include "mcld/LD/ELFFileFormat.h"
25 #include "mcld/LD/ELFSegment.h"
26 #include "mcld/LD/ELFSegmentFactory.h"
27 #include "mcld/MC/Attribute.h"
28 #include "mcld/Object/ObjectBuilder.h"
29 #include "mcld/Support/MemoryRegion.h"
30 #include "mcld/Support/MemoryArea.h"
31 #include "mcld/Support/MsgHandling.h"
32 #include "mcld/Support/TargetRegistry.h"
33 #include "mcld/Target/OutputRelocSection.h"
34 
35 #include <llvm/ADT/Triple.h>
36 #include <llvm/Object/ELFTypes.h>
37 #include <llvm/Support/Casting.h>
38 #include <llvm/Support/ELF.h>
39 #include <llvm/Support/Host.h>
40 #include <llvm/Support/MipsABIFlags.h>
41 
42 #include <vector>
43 
44 namespace mcld {
45 
46 //===----------------------------------------------------------------------===//
47 // MipsGNULDBackend
48 //===----------------------------------------------------------------------===//
MipsGNULDBackend(const LinkerConfig & pConfig,MipsGNUInfo * pInfo)49 MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig,
50                                    MipsGNUInfo* pInfo)
51     : GNULDBackend(pConfig, pInfo),
52       m_pRelocator(NULL),
53       m_pGOT(NULL),
54       m_pPLT(NULL),
55       m_pGOTPLT(NULL),
56       m_pInfo(*pInfo),
57       m_pRelPlt(NULL),
58       m_pRelDyn(NULL),
59       m_pDynamic(NULL),
60       m_pAbiFlags(NULL),
61       m_pGOTSymbol(NULL),
62       m_pPLTSymbol(NULL),
63       m_pGpDispSymbol(NULL) {
64 }
65 
~MipsGNULDBackend()66 MipsGNULDBackend::~MipsGNULDBackend() {
67   delete m_pRelocator;
68   delete m_pPLT;
69   delete m_pRelPlt;
70   delete m_pRelDyn;
71   delete m_pDynamic;
72 }
73 
needsLA25Stub(Relocation::Type pType,const mcld::ResolveInfo * pSym)74 bool MipsGNULDBackend::needsLA25Stub(Relocation::Type pType,
75                                      const mcld::ResolveInfo* pSym) {
76   if (config().isCodeIndep())
77     return false;
78 
79   if (llvm::ELF::R_MIPS_26 != pType)
80     return false;
81 
82   if (pSym->isLocal())
83     return false;
84 
85   return true;
86 }
87 
addNonPICBranchSym(ResolveInfo * rsym)88 void MipsGNULDBackend::addNonPICBranchSym(ResolveInfo* rsym) {
89   m_HasNonPICBranchSyms.insert(rsym);
90 }
91 
hasNonPICBranch(const ResolveInfo * rsym) const92 bool MipsGNULDBackend::hasNonPICBranch(const ResolveInfo* rsym) const {
93   return m_HasNonPICBranchSyms.count(rsym);
94 }
95 
initTargetSections(Module & pModule,ObjectBuilder & pBuilder)96 void MipsGNULDBackend::initTargetSections(Module& pModule,
97                                           ObjectBuilder& pBuilder) {
98   if (LinkerConfig::Object == config().codeGenType())
99     return;
100 
101   ELFFileFormat* file_format = getOutputFormat();
102 
103   // initialize .rel.plt
104   LDSection& relplt = file_format->getRelPlt();
105   m_pRelPlt = new OutputRelocSection(pModule, relplt);
106 
107   // initialize .rel.dyn
108   LDSection& reldyn = file_format->getRelDyn();
109   m_pRelDyn = new OutputRelocSection(pModule, reldyn);
110 
111   // initialize .sdata
112   m_psdata = pBuilder.CreateSection(
113       ".sdata", LDFileFormat::Target, llvm::ELF::SHT_PROGBITS,
114       llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_MIPS_GPREL,
115       4);
116 
117   // initialize .MIPS.abiflags
118   m_pAbiFlags = pBuilder.CreateSection(".MIPS.abiflags", LDFileFormat::Target,
119                                        llvm::ELF::SHT_MIPS_ABIFLAGS,
120                                        llvm::ELF::SHF_ALLOC, 4);
121 }
122 
initTargetSymbols(IRBuilder & pBuilder,Module & pModule)123 void MipsGNULDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {
124   // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
125   // same name in input
126   m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
127       "_GLOBAL_OFFSET_TABLE_",
128       ResolveInfo::Object,
129       ResolveInfo::Define,
130       ResolveInfo::Local,
131       0x0,                  // size
132       0x0,                  // value
133       FragmentRef::Null(),  // FragRef
134       ResolveInfo::Hidden);
135 
136   // Define the symbol _PROCEDURE_LINKAGE_TABLE_ if there is a symbol with the
137   // same name in input
138   m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
139       "_PROCEDURE_LINKAGE_TABLE_",
140       ResolveInfo::Object,
141       ResolveInfo::Define,
142       ResolveInfo::Local,
143       0x0,                  // size
144       0x0,                  // value
145       FragmentRef::Null(),  // FragRef
146       ResolveInfo::Hidden);
147 
148   m_pGpDispSymbol =
149       pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
150           "_gp_disp",
151           ResolveInfo::Section,
152           ResolveInfo::Define,
153           ResolveInfo::Absolute,
154           0x0,                  // size
155           0x0,                  // value
156           FragmentRef::Null(),  // FragRef
157           ResolveInfo::Default);
158 
159   pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
160       "_gp",
161       ResolveInfo::NoType,
162       ResolveInfo::Define,
163       ResolveInfo::Absolute,
164       0x0,                  // size
165       0x0,                  // value
166       FragmentRef::Null(),  // FragRef
167       ResolveInfo::Default);
168 }
169 
getRelocator() const170 const Relocator* MipsGNULDBackend::getRelocator() const {
171   assert(m_pRelocator != NULL);
172   return m_pRelocator;
173 }
174 
getRelocator()175 Relocator* MipsGNULDBackend::getRelocator() {
176   assert(m_pRelocator != NULL);
177   return m_pRelocator;
178 }
179 
doPreLayout(IRBuilder & pBuilder)180 void MipsGNULDBackend::doPreLayout(IRBuilder& pBuilder) {
181   // initialize .dynamic data
182   if (!config().isCodeStatic() && m_pDynamic == NULL)
183     m_pDynamic = new MipsELFDynamic(*this, config());
184 
185   if (m_pAbiInfo.hasValue())
186     m_pAbiFlags->setSize(m_pAbiInfo->size());
187 
188   // set .got size
189   // when building shared object, the .got section is must.
190   if (LinkerConfig::Object != config().codeGenType()) {
191     if (LinkerConfig::DynObj == config().codeGenType() || m_pGOT->hasGOT1() ||
192         m_pGOTSymbol != NULL) {
193       m_pGOT->finalizeScanning(*m_pRelDyn);
194       m_pGOT->finalizeSectionSize();
195 
196       defineGOTSymbol(pBuilder);
197     }
198 
199     if (m_pGOTPLT->hasGOT1()) {
200       m_pGOTPLT->finalizeSectionSize();
201 
202       defineGOTPLTSymbol(pBuilder);
203     }
204 
205     if (m_pPLT->hasPLT1())
206       m_pPLT->finalizeSectionSize();
207 
208     ELFFileFormat* file_format = getOutputFormat();
209 
210     // set .rel.plt size
211     if (!m_pRelPlt->empty()) {
212       assert(
213           !config().isCodeStatic() &&
214           "static linkage should not result in a dynamic relocation section");
215       file_format->getRelPlt().setSize(m_pRelPlt->numOfRelocs() *
216                                        getRelEntrySize());
217     }
218 
219     // set .rel.dyn size
220     if (!m_pRelDyn->empty()) {
221       assert(
222           !config().isCodeStatic() &&
223           "static linkage should not result in a dynamic relocation section");
224       file_format->getRelDyn().setSize(m_pRelDyn->numOfRelocs() *
225                                        getRelEntrySize());
226     }
227   }
228 }
229 
doPostLayout(Module & pModule,IRBuilder & pBuilder)230 void MipsGNULDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) {
231   const ELFFileFormat* format = getOutputFormat();
232 
233   if (format->hasGOTPLT()) {
234     assert(m_pGOTPLT != NULL && "doPostLayout failed, m_pGOTPLT is NULL!");
235     m_pGOTPLT->applyAllGOTPLT(m_pPLT->addr());
236   }
237 
238   if (format->hasPLT()) {
239     assert(m_pPLT != NULL && "doPostLayout failed, m_pPLT is NULL!");
240     m_pPLT->applyAllPLT(*m_pGOTPLT);
241   }
242 
243   m_pInfo.setABIVersion(m_pPLT && m_pPLT->hasPLT1() ? 1 : 0);
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   assert(m_pDynamic != NULL);
250   return *m_pDynamic;
251 }
252 
253 /// dynamic - the dynamic section of the target machine.
254 /// Use co-variant return type to return its own dynamic section.
dynamic() const255 const MipsELFDynamic& MipsGNULDBackend::dynamic() const {
256   assert(m_pDynamic != NULL);
257   return *m_pDynamic;
258 }
259 
emitSectionData(const LDSection & pSection,MemoryRegion & pRegion) const260 uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
261                                            MemoryRegion& pRegion) const {
262   assert(pRegion.size() && "Size of MemoryRegion is zero!");
263 
264   const ELFFileFormat* file_format = getOutputFormat();
265 
266   if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) {
267     return m_pGOT->emit(pRegion);
268   }
269 
270   if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) {
271     return m_pPLT->emit(pRegion);
272   }
273 
274   if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) {
275     return m_pGOTPLT->emit(pRegion);
276   }
277 
278   if (&pSection == m_pAbiFlags && m_pAbiInfo.hasValue())
279     return MipsAbiFlags::emit(*m_pAbiInfo, pRegion);
280 
281   if (&pSection == m_psdata && m_psdata->hasSectionData()) {
282     const SectionData* sect_data = pSection.getSectionData();
283     SectionData::const_iterator frag_iter, frag_end = sect_data->end();
284     uint8_t* out_offset = pRegion.begin();
285     for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
286       size_t size = frag_iter->size();
287       switch (frag_iter->getKind()) {
288         case Fragment::Fillment: {
289           const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter);
290           if (fill_frag.getValueSize() == 0) {
291             // virtual fillment, ignore it.
292             break;
293           }
294           memset(out_offset, fill_frag.getValue(), fill_frag.size());
295           break;
296         }
297         case Fragment::Region: {
298           const RegionFragment& region_frag =
299               llvm::cast<RegionFragment>(*frag_iter);
300           const char* start = region_frag.getRegion().begin();
301           memcpy(out_offset, start, size);
302           break;
303         }
304         case Fragment::Alignment: {
305           const AlignFragment& align_frag =
306               llvm::cast<AlignFragment>(*frag_iter);
307           uint64_t count = size / align_frag.getValueSize();
308           switch (align_frag.getValueSize()) {
309             case 1u:
310               std::memset(out_offset, align_frag.getValue(), count);
311               break;
312             default:
313               llvm::report_fatal_error(
314                   "unsupported value size for align fragment emission yet.\n");
315               break;
316           }  // end switch
317           break;
318         }
319         case Fragment::Null: {
320           assert(0x0 == size);
321           break;
322         }
323         default:
324           llvm::report_fatal_error("unsupported fragment type.\n");
325           break;
326       }  // end switch
327       out_offset += size;
328     }
329     return pRegion.size();
330   }
331 
332   fatal(diag::unrecognized_output_sectoin) << pSection.name()
333                                            << "mclinker@googlegroups.com";
334   return 0;
335 }
336 
hasEntryInStrTab(const LDSymbol & pSym) const337 bool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const {
338   return ResolveInfo::Section != pSym.type() || m_pGpDispSymbol == &pSym;
339 }
340 
341 namespace {
342 struct DynsymGOTCompare {
343   const MipsGOT& m_pGOT;
344 
DynsymGOTComparemcld::__anon40431b780111::DynsymGOTCompare345   explicit DynsymGOTCompare(const MipsGOT& pGOT) : m_pGOT(pGOT) {}
346 
operator ()mcld::__anon40431b780111::DynsymGOTCompare347   bool operator()(const LDSymbol* X, const LDSymbol* Y) const {
348     return m_pGOT.dynSymOrderCompare(X, Y);
349   }
350 };
351 }  // anonymous namespace
352 
orderSymbolTable(Module & pModule)353 void MipsGNULDBackend::orderSymbolTable(Module& pModule) {
354   if (config().options().hasGNUHash()) {
355     // The MIPS ABI and .gnu.hash require .dynsym to be sorted
356     // in different ways. The MIPS ABI requires a mapping between
357     // the GOT and the symbol table. At the same time .gnu.hash
358     // needs symbols to be grouped by hash code.
359     llvm::errs() << ".gnu.hash is incompatible with the MIPS ABI\n";
360   }
361 
362   Module::SymbolTable& symbols = pModule.getSymbolTable();
363 
364   std::stable_sort(
365       symbols.dynamicBegin(), symbols.dynamicEnd(), DynsymGOTCompare(*m_pGOT));
366 }
367 
368 }  // namespace mcld
369 
370 namespace llvm {
371 namespace ELF {
372 // SHT_MIPS_OPTIONS section's block descriptor.
373 struct Elf_Options {
374   unsigned char kind;  // Determines interpretation of variable
375                        // part of descriptor. See ODK_xxx enumeration.
376   unsigned char size;  // Byte size of descriptor, including this header.
377   Elf64_Half section;  // Section header index of section affected,
378                        // or 0 for global options.
379   Elf64_Word info;     // Kind-specific information.
380 };
381 
382 // Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 32 bit ABI.
383 struct Elf32_RegInfo {
384   Elf32_Word ri_gprmask;     // Mask of general purpose registers used.
385   Elf32_Word ri_cprmask[4];  // Mask of co-processor registers used.
386   Elf32_Addr ri_gp_value;    // GP register value for this object file.
387 };
388 
389 // Content of ODK_REGINFO block in SHT_MIPS_OPTIONS section on 64 bit ABI.
390 struct Elf64_RegInfo {
391   Elf32_Word ri_gprmask;     // Mask of general purpose registers used.
392   Elf32_Word ri_pad;         // Padding.
393   Elf32_Word ri_cprmask[4];  // Mask of co-processor registers used.
394   Elf64_Addr ri_gp_value;    // GP register value for this object file.
395 };
396 
397 }  // namespace ELF
398 }  // namespace llvm
399 
400 namespace mcld {
401 
ArchName(uint64_t flagBits)402 static const char* ArchName(uint64_t flagBits) {
403   switch (flagBits) {
404     case llvm::ELF::EF_MIPS_ARCH_1:
405       return "mips1";
406     case llvm::ELF::EF_MIPS_ARCH_2:
407       return "mips2";
408     case llvm::ELF::EF_MIPS_ARCH_3:
409       return "mips3";
410     case llvm::ELF::EF_MIPS_ARCH_4:
411       return "mips4";
412     case llvm::ELF::EF_MIPS_ARCH_5:
413       return "mips5";
414     case llvm::ELF::EF_MIPS_ARCH_32:
415       return "mips32";
416     case llvm::ELF::EF_MIPS_ARCH_64:
417       return "mips64";
418     case llvm::ELF::EF_MIPS_ARCH_32R2:
419       return "mips32r2";
420     case llvm::ELF::EF_MIPS_ARCH_64R2:
421       return "mips64r2";
422     case llvm::ELF::EF_MIPS_ARCH_32R6:
423       return "mips32r6";
424     case llvm::ELF::EF_MIPS_ARCH_64R6:
425       return "mips64r6";
426     default:
427       return "Unknown Arch";
428   }
429 }
430 
mergeFlags(Input & pInput,const char * ELF_hdr)431 void MipsGNULDBackend::mergeFlags(Input& pInput, const char* ELF_hdr) {
432   bool isTarget64Bit = config().targets().triple().isArch64Bit();
433   bool isInput64Bit = ELF_hdr[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
434 
435   if (isTarget64Bit != isInput64Bit) {
436     fatal(diag::error_Mips_incompatible_class)
437         << (isTarget64Bit ? "ELFCLASS64" : "ELFCLASS32")
438         << (isInput64Bit ? "ELFCLASS64" : "ELFCLASS32") << pInput.name();
439     return;
440   }
441 
442   m_ElfFlagsMap[&pInput] =
443       isInput64Bit ?
444           reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(ELF_hdr)->e_flags :
445           reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(ELF_hdr)->e_flags;
446 }
447 
readSection(Input & pInput,SectionData & pSD)448 bool MipsGNULDBackend::readSection(Input& pInput, SectionData& pSD) {
449   if ((pSD.getSection().flag() & llvm::ELF::SHF_MIPS_GPREL) ||
450       (pSD.getSection().type() == llvm::ELF::SHT_MIPS_ABIFLAGS)) {
451     uint64_t offset = pInput.fileOffset() + pSD.getSection().offset();
452     uint64_t size = pSD.getSection().size();
453 
454     Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size);
455     ObjectBuilder::AppendFragment(*frag, pSD);
456     return true;
457   }
458 
459   if (pSD.getSection().type() == llvm::ELF::SHT_MIPS_OPTIONS) {
460     uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
461     uint32_t size = pSD.getSection().size();
462 
463     llvm::StringRef region = pInput.memArea()->request(offset, size);
464     if (region.size() > 0) {
465       const llvm::ELF::Elf_Options* optb =
466           reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin());
467       const llvm::ELF::Elf_Options* opte =
468           reinterpret_cast<const llvm::ELF::Elf_Options*>(region.begin() +
469                                                           size);
470 
471       for (const llvm::ELF::Elf_Options* opt = optb; opt < opte;
472            opt += opt->size) {
473         switch (opt->kind) {
474           default:
475             // Nothing to do.
476             break;
477           case llvm::ELF::ODK_REGINFO:
478             if (config().targets().triple().isArch32Bit()) {
479               const llvm::ELF::Elf32_RegInfo* reg =
480                   reinterpret_cast<const llvm::ELF::Elf32_RegInfo*>(opt + 1);
481               m_GP0Map[&pInput] = reg->ri_gp_value;
482             } else {
483               const llvm::ELF::Elf64_RegInfo* reg =
484                   reinterpret_cast<const llvm::ELF::Elf64_RegInfo*>(opt + 1);
485               m_GP0Map[&pInput] = reg->ri_gp_value;
486             }
487             break;
488         }
489       }
490     }
491 
492     return true;
493   }
494 
495   return GNULDBackend::readSection(pInput, pSD);
496 }
497 
getGOT()498 MipsGOT& MipsGNULDBackend::getGOT() {
499   assert(m_pGOT != NULL);
500   return *m_pGOT;
501 }
502 
getGOT() const503 const MipsGOT& MipsGNULDBackend::getGOT() const {
504   assert(m_pGOT != NULL);
505   return *m_pGOT;
506 }
507 
getPLT()508 MipsPLT& MipsGNULDBackend::getPLT() {
509   assert(m_pPLT != NULL);
510   return *m_pPLT;
511 }
512 
getPLT() const513 const MipsPLT& MipsGNULDBackend::getPLT() const {
514   assert(m_pPLT != NULL);
515   return *m_pPLT;
516 }
517 
getGOTPLT()518 MipsGOTPLT& MipsGNULDBackend::getGOTPLT() {
519   assert(m_pGOTPLT != NULL);
520   return *m_pGOTPLT;
521 }
522 
getGOTPLT() const523 const MipsGOTPLT& MipsGNULDBackend::getGOTPLT() const {
524   assert(m_pGOTPLT != NULL);
525   return *m_pGOTPLT;
526 }
527 
getRelPLT()528 OutputRelocSection& MipsGNULDBackend::getRelPLT() {
529   assert(m_pRelPlt != NULL);
530   return *m_pRelPlt;
531 }
532 
getRelPLT() const533 const OutputRelocSection& MipsGNULDBackend::getRelPLT() const {
534   assert(m_pRelPlt != NULL);
535   return *m_pRelPlt;
536 }
537 
getRelDyn()538 OutputRelocSection& MipsGNULDBackend::getRelDyn() {
539   assert(m_pRelDyn != NULL);
540   return *m_pRelDyn;
541 }
542 
getRelDyn() const543 const OutputRelocSection& MipsGNULDBackend::getRelDyn() const {
544   assert(m_pRelDyn != NULL);
545   return *m_pRelDyn;
546 }
547 
getTargetSectionOrder(const LDSection & pSectHdr) const548 unsigned int MipsGNULDBackend::getTargetSectionOrder(
549     const LDSection& pSectHdr) const {
550   const ELFFileFormat* file_format = getOutputFormat();
551 
552   if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT()))
553     return SHO_DATA;
554 
555   if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT()))
556     return SHO_DATA;
557 
558   if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
559     return SHO_PLT;
560 
561   if (&pSectHdr == m_psdata)
562     return SHO_SMALL_DATA;
563 
564   if (&pSectHdr == m_pAbiFlags)
565     return SHO_RO_NOTE;
566 
567   return SHO_UNDEFINED;
568 }
569 
570 /// finalizeSymbol - finalize the symbol value
finalizeTargetSymbols()571 bool MipsGNULDBackend::finalizeTargetSymbols() {
572   if (m_pGpDispSymbol != NULL)
573     m_pGpDispSymbol->setValue(m_pGOT->getGPDispAddress());
574 
575   return true;
576 }
577 
578 /// allocateCommonSymbols - allocate common symbols in the corresponding
579 /// sections. This is called at pre-layout stage.
580 /// FIXME: Mips needs to allocate small common symbol
allocateCommonSymbols(Module & pModule)581 bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule) {
582   SymbolCategory& symbol_list = pModule.getSymbolTable();
583 
584   if (symbol_list.emptyCommons() && symbol_list.emptyFiles() &&
585       symbol_list.emptyLocals() && symbol_list.emptyLocalDyns())
586     return true;
587 
588   SymbolCategory::iterator com_sym, com_end;
589 
590   // FIXME: If the order of common symbols is defined, then sort common symbols
591   // std::sort(com_sym, com_end, some kind of order);
592 
593   // get corresponding BSS LDSection
594   ELFFileFormat* file_format = getOutputFormat();
595   LDSection& bss_sect = file_format->getBSS();
596   LDSection& tbss_sect = file_format->getTBSS();
597 
598   // get or create corresponding BSS SectionData
599   SectionData* bss_sect_data = NULL;
600   if (bss_sect.hasSectionData())
601     bss_sect_data = bss_sect.getSectionData();
602   else
603     bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
604 
605   SectionData* tbss_sect_data = NULL;
606   if (tbss_sect.hasSectionData())
607     tbss_sect_data = tbss_sect.getSectionData();
608   else
609     tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
610 
611   // remember original BSS size
612   uint64_t bss_offset = bss_sect.size();
613   uint64_t tbss_offset = tbss_sect.size();
614 
615   // allocate all local common symbols
616   com_end = symbol_list.localEnd();
617 
618   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
619     if (ResolveInfo::Common == (*com_sym)->desc()) {
620       // We have to reset the description of the symbol here. When doing
621       // incremental linking, the output relocatable object may have common
622       // symbols. Therefore, we can not treat common symbols as normal symbols
623       // when emitting the regular name pools. We must change the symbols'
624       // description here.
625       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
626       Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
627 
628       if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
629         // allocate TLS common symbol in tbss section
630         tbss_offset += ObjectBuilder::AppendFragment(
631             *frag, *tbss_sect_data, (*com_sym)->value());
632         ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
633         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
634       } else {
635         // FIXME: how to identify small and large common symbols?
636         bss_offset += ObjectBuilder::AppendFragment(
637             *frag, *bss_sect_data, (*com_sym)->value());
638         ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
639         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
640       }
641     }
642   }
643 
644   // allocate all global common symbols
645   com_end = symbol_list.commonEnd();
646   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
647     // We have to reset the description of the symbol here. When doing
648     // incremental linking, the output relocatable object may have common
649     // symbols. Therefore, we can not treat common symbols as normal symbols
650     // when emitting the regular name pools. We must change the symbols'
651     // description here.
652     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
653     Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
654 
655     if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
656       // allocate TLS common symbol in tbss section
657       tbss_offset += ObjectBuilder::AppendFragment(
658           *frag, *tbss_sect_data, (*com_sym)->value());
659       ObjectBuilder::UpdateSectionAlign(tbss_sect, (*com_sym)->value());
660       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
661     } else {
662       // FIXME: how to identify small and large common symbols?
663       bss_offset += ObjectBuilder::AppendFragment(
664           *frag, *bss_sect_data, (*com_sym)->value());
665       ObjectBuilder::UpdateSectionAlign(bss_sect, (*com_sym)->value());
666       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
667     }
668   }
669 
670   bss_sect.setSize(bss_offset);
671   tbss_sect.setSize(tbss_offset);
672   symbol_list.changeCommonsToGlobal();
673   return true;
674 }
675 
getTPOffset(const Input & pInput) const676 uint64_t MipsGNULDBackend::getTPOffset(const Input& pInput) const {
677   return m_TpOffsetMap.lookup(&pInput);
678 }
679 
getDTPOffset(const Input & pInput) const680 uint64_t MipsGNULDBackend::getDTPOffset(const Input& pInput) const {
681   return m_DtpOffsetMap.lookup(&pInput);
682 }
683 
getGP0(const Input & pInput) const684 uint64_t MipsGNULDBackend::getGP0(const Input& pInput) const {
685   return m_GP0Map.lookup(&pInput);
686 }
687 
defineGOTSymbol(IRBuilder & pBuilder)688 void MipsGNULDBackend::defineGOTSymbol(IRBuilder& pBuilder) {
689   // If we do not reserve any GOT entries, we do not need to re-define GOT
690   // symbol.
691   if (!m_pGOT->hasGOT1())
692     return;
693 
694   // define symbol _GLOBAL_OFFSET_TABLE_
695   if (m_pGOTSymbol != NULL) {
696     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
697         "_GLOBAL_OFFSET_TABLE_",
698         ResolveInfo::Object,
699         ResolveInfo::Define,
700         ResolveInfo::Local,
701         0x0,  // size
702         0x0,  // value
703         FragmentRef::Create(*(m_pGOT->begin()), 0x0),
704         ResolveInfo::Hidden);
705   } else {
706     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
707         "_GLOBAL_OFFSET_TABLE_",
708         ResolveInfo::Object,
709         ResolveInfo::Define,
710         ResolveInfo::Local,
711         0x0,  // size
712         0x0,  // value
713         FragmentRef::Create(*(m_pGOT->begin()), 0x0),
714         ResolveInfo::Hidden);
715   }
716 }
717 
defineGOTPLTSymbol(IRBuilder & pBuilder)718 void MipsGNULDBackend::defineGOTPLTSymbol(IRBuilder& pBuilder) {
719   // define symbol _PROCEDURE_LINKAGE_TABLE_
720   if (m_pPLTSymbol != NULL) {
721     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
722         "_PROCEDURE_LINKAGE_TABLE_",
723         ResolveInfo::Object,
724         ResolveInfo::Define,
725         ResolveInfo::Local,
726         0x0,  // size
727         0x0,  // value
728         FragmentRef::Create(*(m_pPLT->begin()), 0x0),
729         ResolveInfo::Hidden);
730   } else {
731     m_pPLTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
732         "_PROCEDURE_LINKAGE_TABLE_",
733         ResolveInfo::Object,
734         ResolveInfo::Define,
735         ResolveInfo::Local,
736         0x0,  // size
737         0x0,  // value
738         FragmentRef::Create(*(m_pPLT->begin()), 0x0),
739         ResolveInfo::Hidden);
740   }
741 }
742 
743 /// doCreateProgramHdrs - backend can implement this function to create the
744 /// target-dependent segments
doCreateProgramHdrs(Module & pModule)745 void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule) {
746   if (!m_pAbiFlags || m_pAbiFlags->size() == 0)
747     return;
748 
749   // create PT_MIPS_ABIFLAGS segment
750   ELFSegmentFactory::iterator sit =
751       elfSegmentTable().find(llvm::ELF::PT_INTERP, 0x0, 0x0);
752   if (sit == elfSegmentTable().end())
753     sit = elfSegmentTable().find(llvm::ELF::PT_PHDR, 0x0, 0x0);
754   if (sit == elfSegmentTable().end())
755     sit = elfSegmentTable().begin();
756   else
757     ++sit;
758 
759   ELFSegment* abiSeg = elfSegmentTable().insert(sit,
760                                                 llvm::ELF::PT_MIPS_ABIFLAGS,
761                                                 llvm::ELF::PF_R);
762   abiSeg->setAlign(8);
763   abiSeg->append(m_pAbiFlags);
764 }
765 
relaxRelocation(IRBuilder & pBuilder,Relocation & pRel)766 bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) {
767   uint64_t sym_value = 0x0;
768 
769   LDSymbol* symbol = pRel.symInfo()->outSymbol();
770   if (symbol->hasFragRef()) {
771     uint64_t value = symbol->fragRef()->getOutputOffset();
772     uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr();
773     sym_value = addr + value;
774   }
775 
776   Stub* stub = getStubFactory()->create(
777       pRel, sym_value, pBuilder, *getBRIslandFactory());
778 
779   if (stub == NULL)
780     return false;
781 
782   assert(stub->symInfo() != NULL);
783   // reset the branch target of the reloc to this stub instead
784   pRel.setSymInfo(stub->symInfo());
785 
786   // increase the size of .symtab and .strtab
787   LDSection& symtab = getOutputFormat()->getSymTab();
788   LDSection& strtab = getOutputFormat()->getStrTab();
789   symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
790   strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
791 
792   return true;
793 }
794 
doRelax(Module & pModule,IRBuilder & pBuilder,bool & pFinished)795 bool MipsGNULDBackend::doRelax(Module& pModule,
796                                IRBuilder& pBuilder,
797                                bool& pFinished) {
798   assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
799 
800   bool isRelaxed = false;
801 
802   for (Module::obj_iterator input = pModule.obj_begin();
803        input != pModule.obj_end();
804        ++input) {
805     LDContext* context = (*input)->context();
806 
807     for (LDContext::sect_iterator rs = context->relocSectBegin();
808          rs != context->relocSectEnd();
809          ++rs) {
810       LDSection* sec = *rs;
811 
812       if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData())
813         continue;
814 
815       for (RelocData::iterator reloc = sec->getRelocData()->begin();
816            reloc != sec->getRelocData()->end();
817            ++reloc) {
818         if (llvm::ELF::R_MIPS_26 != reloc->type())
819           continue;
820 
821         if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc)))
822           isRelaxed = true;
823       }
824     }
825   }
826 
827   // find the first fragment w/ invalid offset due to stub insertion
828   std::vector<Fragment*> invalid_frags;
829   pFinished = true;
830   for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(),
831                                      ie = getBRIslandFactory()->end();
832        ii != ie;
833        ++ii) {
834     BranchIsland& island = *ii;
835     if (island.size() > stubGroupSize()) {
836       error(diag::err_no_space_to_place_stubs) << stubGroupSize();
837       return false;
838     }
839 
840     if (island.numOfStubs() == 0) {
841       continue;
842     }
843 
844     Fragment* exit = &*island.end();
845     if (exit == &*island.begin()->getParent()->end()) {
846       continue;
847     }
848 
849     if ((island.offset() + island.size()) > exit->getOffset()) {
850       if (invalid_frags.empty() ||
851           (invalid_frags.back()->getParent() != island.getParent())) {
852         invalid_frags.push_back(exit);
853         pFinished = false;
854       }
855       continue;
856     }
857   }
858 
859   // reset the offset of invalid fragments
860   for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie;
861        ++it) {
862     Fragment* invalid = *it;
863     while (invalid != NULL) {
864       invalid->setOffset(invalid->getPrevNode()->getOffset() +
865                          invalid->getPrevNode()->size());
866       invalid = invalid->getNextNode();
867     }
868   }
869 
870   // reset the size of section that has stubs inserted.
871   if (isRelaxed) {
872     SectionData* prev = NULL;
873     for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
874                                        island_end = getBRIslandFactory()->end();
875          island != island_end;
876          ++island) {
877       SectionData* sd = (*island).begin()->getParent();
878       if ((*island).numOfStubs() != 0) {
879         if (sd != prev) {
880           sd->getSection().setSize(sd->back().getOffset() + sd->back().size());
881         }
882       }
883       prev = sd;
884     }
885   }
886 
887   return isRelaxed;
888 }
889 
initTargetStubs()890 bool MipsGNULDBackend::initTargetStubs() {
891   if (getStubFactory() == NULL)
892     return false;
893 
894   getStubFactory()->addPrototype(new MipsLA25Stub(*this));
895   return true;
896 }
897 
readRelocation(const llvm::ELF::Elf32_Rel & pRel,Relocation::Type & pType,uint32_t & pSymIdx,uint32_t & pOffset) const898 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rel& pRel,
899                                       Relocation::Type& pType,
900                                       uint32_t& pSymIdx,
901                                       uint32_t& pOffset) const {
902   return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset);
903 }
904 
readRelocation(const llvm::ELF::Elf32_Rela & pRel,Relocation::Type & pType,uint32_t & pSymIdx,uint32_t & pOffset,int32_t & pAddend) const905 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf32_Rela& pRel,
906                                       Relocation::Type& pType,
907                                       uint32_t& pSymIdx,
908                                       uint32_t& pOffset,
909                                       int32_t& pAddend) const {
910   return GNULDBackend::readRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
911 }
912 
readRelocation(const llvm::ELF::Elf64_Rel & pRel,Relocation::Type & pType,uint32_t & pSymIdx,uint64_t & pOffset) const913 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rel& pRel,
914                                       Relocation::Type& pType,
915                                       uint32_t& pSymIdx,
916                                       uint64_t& pOffset) const {
917   uint64_t r_info = 0x0;
918   if (llvm::sys::IsLittleEndianHost) {
919     pOffset = pRel.r_offset;
920     r_info = pRel.r_info;
921   } else {
922     pOffset = mcld::bswap64(pRel.r_offset);
923     r_info = mcld::bswap64(pRel.r_info);
924   }
925 
926   // MIPS 64 little endian (we do not support big endian now)
927   // has a "special" encoding of r_info relocation
928   // field. Instead of one 64 bit little endian number, it is a little
929   // endian 32 bit number followed by a 32 bit big endian number.
930   pType = mcld::bswap32(r_info >> 32);
931   pSymIdx = r_info & 0xffffffff;
932   return true;
933 }
934 
readRelocation(const llvm::ELF::Elf64_Rela & pRel,Relocation::Type & pType,uint32_t & pSymIdx,uint64_t & pOffset,int64_t & pAddend) const935 bool MipsGNULDBackend::readRelocation(const llvm::ELF::Elf64_Rela& pRel,
936                                       Relocation::Type& pType,
937                                       uint32_t& pSymIdx,
938                                       uint64_t& pOffset,
939                                       int64_t& pAddend) const {
940   uint64_t r_info = 0x0;
941   if (llvm::sys::IsLittleEndianHost) {
942     pOffset = pRel.r_offset;
943     r_info = pRel.r_info;
944     pAddend = pRel.r_addend;
945   } else {
946     pOffset = mcld::bswap64(pRel.r_offset);
947     r_info = mcld::bswap64(pRel.r_info);
948     pAddend = mcld::bswap64(pRel.r_addend);
949   }
950 
951   pType = mcld::bswap32(r_info >> 32);
952   pSymIdx = r_info & 0xffffffff;
953   return true;
954 }
955 
emitRelocation(llvm::ELF::Elf32_Rel & pRel,Relocation::Type pType,uint32_t pSymIdx,uint32_t pOffset) const956 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rel& pRel,
957                                       Relocation::Type pType,
958                                       uint32_t pSymIdx,
959                                       uint32_t pOffset) const {
960   GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset);
961 }
962 
emitRelocation(llvm::ELF::Elf32_Rela & pRel,Relocation::Type pType,uint32_t pSymIdx,uint32_t pOffset,int32_t pAddend) const963 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf32_Rela& pRel,
964                                       Relocation::Type pType,
965                                       uint32_t pSymIdx,
966                                       uint32_t pOffset,
967                                       int32_t pAddend) const {
968   GNULDBackend::emitRelocation(pRel, pType, pSymIdx, pOffset, pAddend);
969 }
970 
emitRelocation(llvm::ELF::Elf64_Rel & pRel,Relocation::Type pType,uint32_t pSymIdx,uint64_t pOffset) const971 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rel& pRel,
972                                       Relocation::Type pType,
973                                       uint32_t pSymIdx,
974                                       uint64_t pOffset) const {
975   uint64_t r_info = mcld::bswap32(pType);
976   r_info <<= 32;
977   r_info |= pSymIdx;
978 
979   pRel.r_info = r_info;
980   pRel.r_offset = pOffset;
981 }
982 
emitRelocation(llvm::ELF::Elf64_Rela & pRel,Relocation::Type pType,uint32_t pSymIdx,uint64_t pOffset,int64_t pAddend) const983 void MipsGNULDBackend::emitRelocation(llvm::ELF::Elf64_Rela& pRel,
984                                       Relocation::Type pType,
985                                       uint32_t pSymIdx,
986                                       uint64_t pOffset,
987                                       int64_t pAddend) const {
988   uint64_t r_info = mcld::bswap32(pType);
989   r_info <<= 32;
990   r_info |= pSymIdx;
991 
992   pRel.r_info = r_info;
993   pRel.r_offset = pOffset;
994   pRel.r_addend = pAddend;
995 }
996 
997 namespace {
998 struct ISATreeEdge {
999   unsigned child;
1000   unsigned parent;
1001 };
1002 }
1003 
1004 static ISATreeEdge isaTree[] = {
1005     // MIPS32R6 and MIPS64R6 are not compatible with other extensions
1006 
1007     // MIPS64 extensions.
1008     {llvm::ELF::EF_MIPS_ARCH_64R2, llvm::ELF::EF_MIPS_ARCH_64},
1009     // MIPS V extensions.
1010     {llvm::ELF::EF_MIPS_ARCH_64, llvm::ELF::EF_MIPS_ARCH_5},
1011     // MIPS IV extensions.
1012     {llvm::ELF::EF_MIPS_ARCH_5, llvm::ELF::EF_MIPS_ARCH_4},
1013     // MIPS III extensions.
1014     {llvm::ELF::EF_MIPS_ARCH_4, llvm::ELF::EF_MIPS_ARCH_3},
1015     // MIPS32 extensions.
1016     {llvm::ELF::EF_MIPS_ARCH_32R2, llvm::ELF::EF_MIPS_ARCH_32},
1017     // MIPS II extensions.
1018     {llvm::ELF::EF_MIPS_ARCH_3, llvm::ELF::EF_MIPS_ARCH_2},
1019     {llvm::ELF::EF_MIPS_ARCH_32, llvm::ELF::EF_MIPS_ARCH_2},
1020     // MIPS I extensions.
1021     {llvm::ELF::EF_MIPS_ARCH_2, llvm::ELF::EF_MIPS_ARCH_1},
1022 };
1023 
isIsaMatched(uint32_t base,uint32_t ext)1024 static bool isIsaMatched(uint32_t base, uint32_t ext) {
1025   if (base == ext)
1026     return true;
1027   if (base == llvm::ELF::EF_MIPS_ARCH_32 &&
1028       isIsaMatched(llvm::ELF::EF_MIPS_ARCH_64, ext))
1029     return true;
1030   if (base == llvm::ELF::EF_MIPS_ARCH_32R2 &&
1031       isIsaMatched(llvm::ELF::EF_MIPS_ARCH_64R2, ext))
1032     return true;
1033   for (const auto &edge : isaTree) {
1034     if (ext == edge.child) {
1035       ext = edge.parent;
1036       if (ext == base)
1037         return true;
1038     }
1039   }
1040   return false;
1041 }
1042 
getAbiFlags(const Input & pInput,uint64_t elfFlags,bool & hasFlags,MipsAbiFlags & pFlags)1043 static bool getAbiFlags(const Input& pInput, uint64_t elfFlags, bool& hasFlags,
1044                         MipsAbiFlags& pFlags) {
1045   MipsAbiFlags pElfFlags = {};
1046   if (!MipsAbiFlags::fillByElfFlags(pInput, elfFlags, pElfFlags))
1047     return false;
1048 
1049   const LDContext* ctx = pInput.context();
1050   for (auto it = ctx->sectBegin(), ie = ctx->sectEnd(); it != ie; ++it)
1051     if ((*it)->type() == llvm::ELF::SHT_MIPS_ABIFLAGS) {
1052       if (!MipsAbiFlags::fillBySection(pInput, **it, pFlags))
1053         return false;
1054       if (!MipsAbiFlags::isCompatible(pInput, pElfFlags, pFlags))
1055         return false;
1056       hasFlags = true;
1057       return true;
1058     }
1059 
1060   pFlags = pElfFlags;
1061   return true;
1062 }
1063 
getNanName(uint64_t flags)1064 static const char* getNanName(uint64_t flags) {
1065   return flags & llvm::ELF::EF_MIPS_NAN2008 ? "2008" : "legacy";
1066 }
1067 
mergeElfFlags(const Input & pInput,uint64_t & oldElfFlags,uint64_t newElfFlags)1068 static bool mergeElfFlags(const Input& pInput, uint64_t& oldElfFlags,
1069                           uint64_t newElfFlags) {
1070   // PIC code is inherently CPIC and may not set CPIC flag explicitly.
1071   // Ensure that this flag will exist in the linked file.
1072   if (newElfFlags & llvm::ELF::EF_MIPS_PIC)
1073     newElfFlags |= llvm::ELF::EF_MIPS_CPIC;
1074 
1075   if (newElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE_M16) {
1076     error(diag::error_Mips_m16_unsupported) << pInput.name();
1077     return false;
1078   }
1079 
1080   if (!oldElfFlags) {
1081     oldElfFlags = newElfFlags;
1082     return true;
1083   }
1084 
1085   uint64_t newPic =
1086       newElfFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC);
1087   uint64_t oldPic =
1088       oldElfFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC);
1089 
1090   // Check PIC / CPIC flags compatibility.
1091   if ((newPic != 0) != (oldPic != 0))
1092     warning(diag::warn_Mips_abicalls_linking) << pInput.name();
1093 
1094   if (!(newPic & llvm::ELF::EF_MIPS_PIC))
1095     oldElfFlags &= ~llvm::ELF::EF_MIPS_PIC;
1096   if (newPic)
1097     oldElfFlags |= llvm::ELF::EF_MIPS_CPIC;
1098 
1099   // Check ISA compatibility.
1100   uint64_t newArch = newElfFlags & llvm::ELF::EF_MIPS_ARCH;
1101   uint64_t oldArch = oldElfFlags & llvm::ELF::EF_MIPS_ARCH;
1102   if (!isIsaMatched(newArch, oldArch)) {
1103     if (!isIsaMatched(oldArch, newArch)) {
1104       error(diag::error_Mips_inconsistent_arch)
1105           << ArchName(oldArch) << ArchName(newArch) << pInput.name();
1106       return false;
1107     }
1108     oldElfFlags &= ~llvm::ELF::EF_MIPS_ARCH;
1109     oldElfFlags |= newArch;
1110   }
1111 
1112   // Check ABI compatibility.
1113   uint32_t newAbi = newElfFlags & llvm::ELF::EF_MIPS_ABI;
1114   uint32_t oldAbi = oldElfFlags & llvm::ELF::EF_MIPS_ABI;
1115   if (newAbi != oldAbi && newAbi && oldAbi) {
1116     error(diag::error_Mips_inconsistent_abi) << pInput.name();
1117     return false;
1118   }
1119 
1120   // Check -mnan flags compatibility.
1121   if ((newElfFlags & llvm::ELF::EF_MIPS_NAN2008) !=
1122       (oldElfFlags & llvm::ELF::EF_MIPS_NAN2008)) {
1123     // Linking -mnan=2008 and -mnan=legacy modules
1124     error(diag::error_Mips_inconsistent_mnan)
1125         << getNanName(oldElfFlags) << getNanName(newElfFlags) << pInput.name();
1126     return false;
1127   }
1128 
1129   // Check ASE compatibility.
1130   uint64_t newAse = newElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE;
1131   uint64_t oldAse = oldElfFlags & llvm::ELF::EF_MIPS_ARCH_ASE;
1132   if (newAse != oldAse)
1133     oldElfFlags |= newAse;
1134 
1135   // Check FP64 compatibility.
1136   if ((newElfFlags & llvm::ELF::EF_MIPS_FP64) !=
1137       (oldElfFlags & llvm::ELF::EF_MIPS_FP64)) {
1138     // Linking -mnan=2008 and -mnan=legacy modules
1139     error(diag::error_Mips_inconsistent_fp64) << pInput.name();
1140     return false;
1141   }
1142 
1143   oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_NOREORDER;
1144   oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_MICROMIPS;
1145   oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_NAN2008;
1146   oldElfFlags |= newElfFlags & llvm::ELF::EF_MIPS_32BITMODE;
1147 
1148   return true;
1149 }
1150 
saveTPOffset(const Input & pInput)1151 void MipsGNULDBackend::saveTPOffset(const Input& pInput) {
1152   const LDContext* ctx = pInput.context();
1153   for (auto it = ctx->sectBegin(), ie = ctx->sectEnd(); it != ie; ++it) {
1154     LDSection* sect = *it;
1155     if (sect->flag() & llvm::ELF::SHF_TLS) {
1156       m_TpOffsetMap[&pInput] = sect->addr() + 0x7000;
1157       m_DtpOffsetMap[&pInput] = sect->addr() + 0x8000;
1158       break;
1159     }
1160   }
1161 }
1162 
preMergeSections(Module & pModule)1163 void MipsGNULDBackend::preMergeSections(Module& pModule) {
1164   uint64_t elfFlags = 0;
1165   bool hasAbiFlags = false;
1166   MipsAbiFlags abiFlags = {};
1167   for (const Input *input : pModule.getObjectList()) {
1168     if (input->type() != Input::Object)
1169       continue;
1170 
1171     uint64_t newElfFlags = m_ElfFlagsMap[input];
1172 
1173     MipsAbiFlags newAbiFlags = {};
1174     if (!getAbiFlags(*input, newElfFlags, hasAbiFlags, newAbiFlags))
1175       continue;
1176 
1177     if (!mergeElfFlags(*input, elfFlags, newElfFlags))
1178       continue;
1179 
1180     if (!MipsAbiFlags::merge(*input, abiFlags, newAbiFlags))
1181       continue;
1182 
1183     saveTPOffset(*input);
1184   }
1185 
1186   m_pInfo.setElfFlags(elfFlags);
1187   if (hasAbiFlags)
1188     m_pAbiInfo = abiFlags;
1189 }
1190 
mergeSection(Module & pModule,const Input & pInput,LDSection & pSection)1191 bool MipsGNULDBackend::mergeSection(Module& pModule, const Input& pInput,
1192                                     LDSection& pSection) {
1193   if (pSection.flag() & llvm::ELF::SHF_MIPS_GPREL) {
1194     SectionData* sd = NULL;
1195     if (!m_psdata->hasSectionData()) {
1196       sd = IRBuilder::CreateSectionData(*m_psdata);
1197       m_psdata->setSectionData(sd);
1198     }
1199     sd = m_psdata->getSectionData();
1200     moveSectionData(*pSection.getSectionData(), *sd);
1201   } else if (pSection.type() == llvm::ELF::SHT_MIPS_ABIFLAGS) {
1202     // Nothing to do because we handle all .MIPS.abiflags sections
1203     // in the preMergeSections method.
1204   } else {
1205     ObjectBuilder builder(pModule);
1206     builder.MergeSection(pInput, pSection);
1207   }
1208   return true;
1209 }
1210 
moveSectionData(SectionData & pFrom,SectionData & pTo)1211 void MipsGNULDBackend::moveSectionData(SectionData& pFrom, SectionData& pTo) {
1212   assert(&pFrom != &pTo && "Cannot move section data to itself!");
1213 
1214   uint64_t offset = pTo.getSection().size();
1215   AlignFragment* align = NULL;
1216   if (pFrom.getSection().align() > 1) {
1217     // if the align constraint is larger than 1, append an alignment
1218     unsigned int alignment = pFrom.getSection().align();
1219     align = new AlignFragment(/*alignment*/ alignment,
1220                               /*the filled value*/ 0x0,
1221                               /*the size of filled value*/ 1u,
1222                               /*max bytes to emit*/ alignment - 1);
1223     align->setOffset(offset);
1224     align->setParent(&pTo);
1225     pTo.getFragmentList().push_back(align);
1226     offset += align->size();
1227   }
1228 
1229   // move fragments from pFrom to pTO
1230   SectionData::FragmentListType& from_list = pFrom.getFragmentList();
1231   SectionData::FragmentListType& to_list = pTo.getFragmentList();
1232   SectionData::FragmentListType::iterator frag, fragEnd = from_list.end();
1233   for (frag = from_list.begin(); frag != fragEnd; ++frag) {
1234     frag->setParent(&pTo);
1235     frag->setOffset(offset);
1236     offset += frag->size();
1237   }
1238   to_list.splice(to_list.end(), from_list);
1239 
1240   // set up pTo's header
1241   pTo.getSection().setSize(offset);
1242 }
1243 
1244 //===----------------------------------------------------------------------===//
1245 // Mips32GNULDBackend
1246 //===----------------------------------------------------------------------===//
Mips32GNULDBackend(const LinkerConfig & pConfig,MipsGNUInfo * pInfo)1247 Mips32GNULDBackend::Mips32GNULDBackend(const LinkerConfig& pConfig,
1248                                        MipsGNUInfo* pInfo)
1249     : MipsGNULDBackend(pConfig, pInfo) {
1250 }
1251 
initRelocator()1252 bool Mips32GNULDBackend::initRelocator() {
1253   if (m_pRelocator == NULL)
1254     m_pRelocator = new Mips32Relocator(*this, config());
1255 
1256   return true;
1257 }
1258 
initTargetSections(Module & pModule,ObjectBuilder & pBuilder)1259 void Mips32GNULDBackend::initTargetSections(Module& pModule,
1260                                             ObjectBuilder& pBuilder) {
1261   MipsGNULDBackend::initTargetSections(pModule, pBuilder);
1262 
1263   if (LinkerConfig::Object == config().codeGenType())
1264     return;
1265 
1266   ELFFileFormat* fileFormat = getOutputFormat();
1267 
1268   // initialize .got
1269   LDSection& got = fileFormat->getGOT();
1270   m_pGOT = new Mips32GOT(got);
1271 
1272   // initialize .got.plt
1273   LDSection& gotplt = fileFormat->getGOTPLT();
1274   m_pGOTPLT = new MipsGOTPLT(gotplt);
1275 
1276   // initialize .plt
1277   LDSection& plt = fileFormat->getPLT();
1278   m_pPLT = new MipsPLT(plt);
1279 }
1280 
getRelEntrySize()1281 size_t Mips32GNULDBackend::getRelEntrySize() {
1282   return 8;
1283 }
1284 
getRelaEntrySize()1285 size_t Mips32GNULDBackend::getRelaEntrySize() {
1286   return 12;
1287 }
1288 
1289 //===----------------------------------------------------------------------===//
1290 // Mips64GNULDBackend
1291 //===----------------------------------------------------------------------===//
Mips64GNULDBackend(const LinkerConfig & pConfig,MipsGNUInfo * pInfo)1292 Mips64GNULDBackend::Mips64GNULDBackend(const LinkerConfig& pConfig,
1293                                        MipsGNUInfo* pInfo)
1294     : MipsGNULDBackend(pConfig, pInfo) {
1295 }
1296 
initRelocator()1297 bool Mips64GNULDBackend::initRelocator() {
1298   if (m_pRelocator == NULL)
1299     m_pRelocator = new Mips64Relocator(*this, config());
1300 
1301   return true;
1302 }
1303 
initTargetSections(Module & pModule,ObjectBuilder & pBuilder)1304 void Mips64GNULDBackend::initTargetSections(Module& pModule,
1305                                             ObjectBuilder& pBuilder) {
1306   MipsGNULDBackend::initTargetSections(pModule, pBuilder);
1307 
1308   if (LinkerConfig::Object == config().codeGenType())
1309     return;
1310 
1311   ELFFileFormat* fileFormat = getOutputFormat();
1312 
1313   // initialize .got
1314   LDSection& got = fileFormat->getGOT();
1315   m_pGOT = new Mips64GOT(got);
1316 
1317   // initialize .got.plt
1318   LDSection& gotplt = fileFormat->getGOTPLT();
1319   m_pGOTPLT = new MipsGOTPLT(gotplt);
1320 
1321   // initialize .plt
1322   LDSection& plt = fileFormat->getPLT();
1323   m_pPLT = new MipsPLT(plt);
1324 }
1325 
getRelEntrySize()1326 size_t Mips64GNULDBackend::getRelEntrySize() {
1327   return 16;
1328 }
1329 
getRelaEntrySize()1330 size_t Mips64GNULDBackend::getRelaEntrySize() {
1331   return 24;
1332 }
1333 
1334 //===----------------------------------------------------------------------===//
1335 /// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
1336 ///
createMipsLDBackend(const LinkerConfig & pConfig)1337 static TargetLDBackend* createMipsLDBackend(const LinkerConfig& pConfig) {
1338   const llvm::Triple& triple = pConfig.targets().triple();
1339 
1340   if (triple.isOSDarwin()) {
1341     assert(0 && "MachO linker is not supported yet");
1342   }
1343   if (triple.isOSWindows()) {
1344     assert(0 && "COFF linker is not supported yet");
1345   }
1346 
1347   llvm::Triple::ArchType arch = triple.getArch();
1348 
1349   if (llvm::Triple::mips64el == arch)
1350     return new Mips64GNULDBackend(pConfig, new MipsGNUInfo(triple));
1351 
1352   assert(arch == llvm::Triple::mipsel);
1353   return new Mips32GNULDBackend(pConfig, new MipsGNUInfo(triple));
1354 }
1355 
1356 }  // namespace mcld
1357 
1358 //===----------------------------------------------------------------------===//
1359 // Force static initialization.
1360 //===----------------------------------------------------------------------===//
MCLDInitializeMipsLDBackend()1361 extern "C" void MCLDInitializeMipsLDBackend() {
1362   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
1363                                                 mcld::createMipsLDBackend);
1364   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMips64elTarget,
1365                                                 mcld::createMipsLDBackend);
1366 }
1367