LLVM: lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h Source File (original) (raw)
124
125
126
127 virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {
128 return false;
129 }
130
131
132
133
134
135
136 template
138 RelocHandlerMethod &&Func);
139
140
141
142
143
144
145 template
147 RelocHandlerMethod &&Func);
148
149
150
151
152 template <typename ClassT, typename RelocHandlerMethod>
154 ClassT *Instance, RelocHandlerMethod &&Method) {
156 RelSect,
157 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
158 return (Instance->*Method)(Rel, Target, GS);
159 });
160 }
161
162
163
164
165 template <typename ClassT, typename RelocHandlerMethod>
167 ClassT *Instance, RelocHandlerMethod &&Method) {
169 RelSect,
170 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
171 return (Instance->*Method)(Rel, Target, GS);
172 });
173 }
174
176
177 typename ELFFile::Elf_Shdr_Range Sections;
178 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
181
182
183
186 DenseMap<const typename ELFFile::Elf_Shdr *,
189};
190
191template
193 const ELFFile &Obj, std::shared_ptrorc::SymbolStringPool SSP, Triple TT,
198 std::move(GetEdgeKindName))),
201 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
202}
203
204template
208
209 if (auto Err = prepare())
210 return std::move(Err);
211
213 return std::move(Err);
214
216 return std::move(Err);
217
219 return std::move(Err);
220
221 return std::move(G);
222}
223
224template
227 const typename ELFT::Sym &Sym, StringRef Name) {
230
231 switch (Sym.getBinding()) {
234 break;
236
237 break;
241 break;
242 default:
244 "Unrecognized symbol binding " +
245 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
247 }
248
249 switch (Sym.getVisibility()) {
252
253
254
255 break;
257
260 break;
263 "Unrecognized symbol visibility " +
264 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
266 }
267
268 return std::make_pair(L, S);
269}
270
273
274
275 if (auto SectionsOrErr = Obj.sections())
277 else
278 return SectionsOrErr.takeError();
279
280
281 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
283 else
284 return SectionStringTabOrErr.takeError();
285
286
291 else
293 G->getName());
294 }
295
296
298 uint32_t SymtabNdx = Sec.sh_link;
299 if (SymtabNdx >= Sections.size())
301
302 auto ShndxTable = Obj.getSHNDXTable(Sec);
303 if (!ShndxTable)
304 return ShndxTable.takeError();
305
307 }
308 }
309
311}
312
314 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
315
316
318
319 auto &Sec = Sections[SecIndex];
320
321
323 if (!Name)
324 return Name.takeError();
327 dbgs() << " " << SecIndex << ": Skipping section \"" << *Name
328 << "\" explicitly\n";
329 });
330 continue;
331 }
332
333
336 dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";
337 });
338 continue;
339 }
340
341
342
345 dbgs() << " " << SecIndex << ": \"" << *Name
346 << "\" is a debug section: "
347 "No graph section will be created.\n";
348 });
349 continue;
350 }
351
353 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
354 << "\"\n";
355 });
356
357
363
364
365 auto *GraphSec = G->findSectionByName(*Name);
366 if (!GraphSec) {
367 GraphSec = &G->createSection(*Name, Prot);
368
372 dbgs() << " " << SecIndex << ": \"" << *Name
373 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
374 });
375 }
376 }
377
378 if (GraphSec->getMemProt() != Prot) {
379 std::string ErrMsg;
381 << "In " << G->getName() << ", section " << *Name
382 << " is present more than once with different permissions: "
383 << GraphSec->getMemProt() << " vs " << Prot;
385 }
386
389 auto Data = Obj.template getSectionContentsAsArray(Sec);
391 return Data.takeError();
392
393 B = &G->createContentBlock(*GraphSec, *Data,
395 Sec.sh_addralign, 0);
396 } else
397 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
399 Sec.sh_addralign, 0);
400
402
405 }
406
408 }
409
411}
412
414 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
415
416
419
420
422 if (!Symbols)
423 return Symbols.takeError();
424
425
427 if (!StringTab)
428 return StringTab.takeError();
429
432
434 SymTabName = *SymTabNameOrErr;
435 else {
436 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
437 << toString(SymTabNameOrErr.takeError()) << "\n";
438 SymTabName = "<SHT_SYMTAB section with invalid name>";
439 }
440
441 dbgs() << " Adding symbols from symtab section \"" << SymTabName
442 << "\"\n";
443 });
444
445 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
446 auto &Sym = (*Symbols)[SymIndex];
447
448
449 switch (Sym.getType()) {
452 if (auto Name = Sym.getName(*StringTab))
453 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
454 << *Name << "\"\n";
455 else {
456 dbgs() << "Could not get STT_FILE symbol name: "
457 << toString(Name.takeError()) << "\n";
458 dbgs() << " " << SymIndex
459 << ": Skipping STT_FILE symbol with invalid name\n";
460 }
461 });
462 continue;
463 break;
464 }
465
466
467 auto Name = Sym.getName(*StringTab);
468 if (!Name)
469 return Name.takeError();
470
471
472 if (Sym.isCommon()) {
473 Symbol &GSym = G->addDefinedSymbol(
478 continue;
479 }
480
481 if (Sym.isDefined() &&
485
486
490 std::tie(L, S) = *LSOrErr;
491 else
492 return LSOrErr.takeError();
493
494
495 unsigned Shndx = Sym.st_shndx;
499 continue;
501 Sym, SymIndex, ShndxTable->second);
502 if (!NdxOrErr)
503 return NdxOrErr.takeError();
504 Shndx = *NdxOrErr;
505 }
508 dbgs() << " " << SymIndex
509 << ": Creating defined graph symbol for ELF symbol \"" << *Name
510 << "\"\n";
511 });
512
515
516 if (Offset + Sym.st_size > B->getSize()) {
517 std::string ErrMsg;
519 ErrStream << "In " << G->getName() << ", symbol ";
520 if (!Name->empty())
521 ErrStream << *Name;
522 else
523 ErrStream << "";
524 ErrStream << " (" << (B->getAddress() + Offset) << " -- "
525 << (B->getAddress() + Offset + Sym.st_size) << ") extends "
526 << formatv("{0:x}", Offset + Sym.st_size - B->getSize())
527 << " bytes past the end of its containing block ("
528 << B->getRange() << ")";
530 }
531
532
533
534
535
536
537 auto &GSym =
538 Name->empty()
539 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
540 false, false)
541 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
543 false);
544
545 GSym.setTargetFlags(Flags);
547 }
548 } else if (Sym.isUndefined() && Sym.isExternal()) {
550 dbgs() << " " << SymIndex
551 << ": Creating external graph symbol for ELF symbol \"" << *Name
552 << "\"\n";
553 });
554
558 "Invalid symbol binding " +
559 Twine(static_cast<int>(Sym.getBinding())) +
560 " for external symbol " + *Name,
562
563
564 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
567 } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&
569 Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {
570
571
573 dbgs() << " " << SymIndex << ": Creating null graph symbol\n";
574 });
575
576 auto SymName =
577 G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));
578 auto SymNameRef = StringRef(SymName.data(), SymName.size());
579 auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,
582 } else {
584 dbgs() << " " << SymIndex
585 << ": Not creating graph symbol for ELF symbol \"" << *Name
586 << "\" with unrecognized type\n";
587 });
588 }
589 }
590
592}
597 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
598
601
602
603
604 auto FixupSection = Obj.getSection(RelSect.sh_info);
605 if (!FixupSection)
606 return FixupSection.takeError();
607
608
610 if (!Name)
611 return Name.takeError();
613
614
616 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
618 }
620 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
622 }
623
624
625 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
626 if (!BlockToFix)
628 "Refencing a section that wasn't added to the graph: " + *Name,
630
631 auto RelEntries = Obj.relas(RelSect);
632 if (!RelEntries)
633 return RelEntries.takeError();
634
635
636 for (const typename ELFT::Rela &R : *RelEntries)
637 if (Error Err = Func(R, **FixupSection, *BlockToFix))
638 return Err;
639
642}
647 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
648
651
652
653
654 auto FixupSection = Obj.getSection(RelSect.sh_info);
655 if (!FixupSection)
656 return FixupSection.takeError();
657
658
660 if (!Name)
661 return Name.takeError();
663
664
666 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
668 }
670 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
672 }
673
674
675 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
676 if (!BlockToFix)
678 "Refencing a section that wasn't added to the graph: " + *Name,
680
681 auto RelEntries = Obj.rels(RelSect);
682 if (!RelEntries)
683 return RelEntries.takeError();
684
685
686 for (const typename ELFT::Rel &R : *RelEntries)
687 if (Error Err = Func(R, **FixupSection, *BlockToFix))
688 return Err;
689
692}