LLVM 20.0.0git
ELFLinkGraphBuilder.h
Go to the documentation of this file.
1//===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Generic ELF LinkGraph building code.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14#define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
15
17#include "llvm/Object/ELF.h"
18#include "llvm/Support/Debug.h"
19#include "llvm/Support/Error.h"
21
22#define DEBUG_TYPE "jitlink"
23
24namespace llvm {
25namespace jitlink {
26
27/// Common link-graph building code shared between all ELFFiles.
29public:
30 ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
32
33protected:
35 return llvm::is_contained(DwarfSectionNames, SectionName);
36 }
37
39 if (!CommonSection)
40 CommonSection = &G->createSection(
41 CommonSectionName, orc::MemProt::Read | orc::MemProt::Write);
42 return *CommonSection;
43 }
44
45 std::unique_ptr<LinkGraph> G;
46
47private:
48 static StringRef CommonSectionName;
49 static ArrayRef<const char *> DwarfSectionNames;
50
51 Section *CommonSection = nullptr;
52};
53
54/// LinkGraph building code that's specific to the given ELFT, but common
55/// across all architectures.
56template <typename ELFT>
59
60public:
62 SubtargetFeatures Features, StringRef FileName,
64
65 /// Debug sections are included in the graph by default. Use
66 /// setProcessDebugSections(false) to ignore them if debug info is not
67 /// needed.
69 this->ProcessDebugSections = ProcessDebugSections;
70 return *this;
71 }
72
73 /// Attempt to construct and return the LinkGraph.
75
76 /// Call to derived class to handle relocations. These require
77 /// architecture specific knowledge to map to JITLink edge kinds.
78 virtual Error addRelocations() = 0;
79
80protected:
83
84 bool isRelocatable() const {
85 return Obj.getHeader().e_type == llvm::ELF::ET_REL;
86 }
87
89 assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
90 GraphBlocks[SecIndex] = B;
91 }
92
94 return GraphBlocks.lookup(SecIndex);
95 }
96
98 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
99 GraphSymbols[SymIndex] = &Sym;
100 }
101
103 return GraphSymbols.lookup(SymIndex);
104 }
105
107 getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
108
109 /// Set the target flags on the given Symbol.
110 virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) {
111 return TargetFlagsType{};
112 }
113
114 /// Get the physical offset of the symbol on the target platform.
115 virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
116 TargetFlagsType Flags) {
117 return Sym.getValue();
118 }
119
123
124 /// Override in derived classes to suppress certain sections in the link
125 /// graph.
126 virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {
127 return false;
128 }
129
130 /// Traverse all matching ELFT::Rela relocation records in the given section.
131 /// The handler function Func should be callable with this signature:
132 /// Error(const typename ELFT::Rela &,
133 /// const typename ELFT::Shdr &, Section &)
134 ///
135 template <typename RelocHandlerMethod>
136 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
137 RelocHandlerMethod &&Func);
138
139 /// Traverse all matching ELFT::Rel relocation records in the given section.
140 /// The handler function Func should be callable with this signature:
141 /// Error(const typename ELFT::Rel &,
142 /// const typename ELFT::Shdr &, Section &)
143 ///
144 template <typename RelocHandlerMethod>
145 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
146 RelocHandlerMethod &&Func);
147
148 /// Traverse all matching rela relocation records in the given section.
149 /// Convenience wrapper to allow passing a member function for the handler.
150 ///
151 template <typename ClassT, typename RelocHandlerMethod>
152 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
153 ClassT *Instance, RelocHandlerMethod &&Method) {
155 RelSect,
156 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
157 return (Instance->*Method)(Rel, Target, GS);
158 });
159 }
160
161 /// Traverse all matching rel relocation records in the given section.
162 /// Convenience wrapper to allow passing a member function for the handler.
163 ///
164 template <typename ClassT, typename RelocHandlerMethod>
165 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
166 ClassT *Instance, RelocHandlerMethod &&Method) {
168 RelSect,
169 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
170 return (Instance->*Method)(Rel, Target, GS);
171 });
172 }
173
174 const ELFFile &Obj;
175
176 typename ELFFile::Elf_Shdr_Range Sections;
177 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
180
181 // Maps ELF section indexes to LinkGraph Blocks.
182 // Only SHF_ALLOC sections will have graph blocks.
185 DenseMap<const typename ELFFile::Elf_Shdr *,
188};
189
190template <typename ELFT>
192 const ELFFile &Obj, Triple TT, SubtargetFeatures Features,
193 StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
194 : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
195 FileName.str(), Triple(std::move(TT)), std::move(Features),
196 ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::Endianness),
197 std::move(GetEdgeKindName))),
198 Obj(Obj) {
200 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
201}
202
203template <typename ELFT>
205 if (!isRelocatable())
206 return make_error<JITLinkError>("Object is not a relocatable ELF file");
207
208 if (auto Err = prepare())
209 return std::move(Err);
210
211 if (auto Err = graphifySections())
212 return std::move(Err);
213
214 if (auto Err = graphifySymbols())
215 return std::move(Err);
216
217 if (auto Err = addRelocations())
218 return std::move(Err);
219
220 return std::move(G);
221}
222
223template <typename ELFT>
226 const typename ELFT::Sym &Sym, StringRef Name) {
229
230 switch (Sym.getBinding()) {
231 case ELF::STB_LOCAL:
232 S = Scope::Local;
233 break;
234 case ELF::STB_GLOBAL:
235 // Nothing to do here.
236 break;
237 case ELF::STB_WEAK:
239 L = Linkage::Weak;
240 break;
241 default:
242 return make_error<StringError>(
243 "Unrecognized symbol binding " +
244 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
246 }
247
248 switch (Sym.getVisibility()) {
249 case ELF::STV_DEFAULT:
251 // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
252 // Orc support.
253 // Otherwise nothing to do here.
254 break;
255 case ELF::STV_HIDDEN:
256 // Default scope -> Hidden scope. No effect on local scope.
257 if (S == Scope::Default)
258 S = Scope::Hidden;
259 break;
261 return make_error<StringError>(
262 "Unrecognized symbol visibility " +
263 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
265 }
266
267 return std::make_pair(L, S);
268}
269
270template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
271 LLVM_DEBUG(dbgs() << " Preparing to build...\n");
272
273 // Get the sections array.
274 if (auto SectionsOrErr = Obj.sections())
275 Sections = *SectionsOrErr;
276 else
277 return SectionsOrErr.takeError();
278
279 // Get the section string table.
280 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
281 SectionStringTab = *SectionStringTabOrErr;
282 else
283 return SectionStringTabOrErr.takeError();
284
285 // Get the SHT_SYMTAB section.
286 for (auto &Sec : Sections) {
287 if (Sec.sh_type == ELF::SHT_SYMTAB) {
288 if (!SymTabSec)
289 SymTabSec = &Sec;
290 else
291 return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
292 G->getName());
293 }
294
295 // Extended table.
296 if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
297 uint32_t SymtabNdx = Sec.sh_link;
298 if (SymtabNdx >= Sections.size())
299 return make_error<JITLinkError>("sh_link is out of bound");
300
301 auto ShndxTable = Obj.getSHNDXTable(Sec);
302 if (!ShndxTable)
303 return ShndxTable.takeError();
304
305 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
306 }
307 }
308
309 return Error::success();
310}
311
313 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
314
315 // For each section...
316 for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
317
318 auto &Sec = Sections[SecIndex];
319
320 // Start by getting the section name.
321 auto Name = Obj.getSectionName(Sec, SectionStringTab);
322 if (!Name)
323 return Name.takeError();
324 if (excludeSection(Sec)) {
325 LLVM_DEBUG({
326 dbgs() << " " << SecIndex << ": Skipping section \"" << *Name
327 << "\" explicitly\n";
328 });
329 continue;
330 }
331
332 // Skip null sections.
333 if (Sec.sh_type == ELF::SHT_NULL) {
334 LLVM_DEBUG({
335 dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";
336 });
337 continue;
338 }
339
340 // If the name indicates that it's a debug section then skip it: We don't
341 // support those yet.
342 if (!ProcessDebugSections && isDwarfSection(*Name)) {
343 LLVM_DEBUG({
344 dbgs() << " " << SecIndex << ": \"" << *Name
345 << "\" is a debug section: "
346 "No graph section will be created.\n";
347 });
348 continue;
349 }
350
351 LLVM_DEBUG({
352 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
353 << "\"\n";
354 });
355
356 // Get the section's memory protection flags.
358 if (Sec.sh_flags & ELF::SHF_EXECINSTR)
359 Prot |= orc::MemProt::Exec;
360 if (Sec.sh_flags & ELF::SHF_WRITE)
361 Prot |= orc::MemProt::Write;
362
363 // Look for existing sections first.
364 auto *GraphSec = G->findSectionByName(*Name);
365 if (!GraphSec) {
366 GraphSec = &G->createSection(*Name, Prot);
367 // Non-SHF_ALLOC sections get NoAlloc memory lifetimes.
368 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
369 GraphSec->setMemLifetime(orc::MemLifetime::NoAlloc);
370 LLVM_DEBUG({
371 dbgs() << " " << SecIndex << ": \"" << *Name
372 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
373 });
374 }
375 }
376
377 if (GraphSec->getMemProt() != Prot) {
378 std::string ErrMsg;
379 raw_string_ostream(ErrMsg)
380 << "In " << G->getName() << ", section " << *Name
381 << " is present more than once with different permissions: "
382 << GraphSec->getMemProt() << " vs " << Prot;
383 return make_error<JITLinkError>(std::move(ErrMsg));
384 }
385
386 Block *B = nullptr;
387 if (Sec.sh_type != ELF::SHT_NOBITS) {
388 auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
389 if (!Data)
390 return Data.takeError();
391
392 B = &G->createContentBlock(*GraphSec, *Data,
393 orc::ExecutorAddr(Sec.sh_addr),
394 Sec.sh_addralign, 0);
395 } else
396 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
397 orc::ExecutorAddr(Sec.sh_addr),
398 Sec.sh_addralign, 0);
399
400 if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
401 // Add live symbol to avoid dead-stripping for .ARM.exidx sections
402 G->addAnonymousSymbol(*B, orc::ExecutorAddrDiff(),
403 orc::ExecutorAddrDiff(), false, true);
404 }
405
406 setGraphBlock(SecIndex, B);
407 }
408
409 return Error::success();
410}
411
413 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
414
415 // No SYMTAB -- Bail out early.
416 if (!SymTabSec)
417 return Error::success();
418
419 // Get the section content as a Symbols array.
420 auto Symbols = Obj.symbols(SymTabSec);
421 if (!Symbols)
422 return Symbols.takeError();
423
424 // Get the string table for this section.
425 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
426 if (!StringTab)
427 return StringTab.takeError();
428
429 LLVM_DEBUG({
430 StringRef SymTabName;
431
432 if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
433 SymTabName = *SymTabNameOrErr;
434 else {
435 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
436 << toString(SymTabNameOrErr.takeError()) << "\n";
437 SymTabName = "<SHT_SYMTAB section with invalid name>";
438 }
439
440 dbgs() << " Adding symbols from symtab section \"" << SymTabName
441 << "\"\n";
442 });
443
444 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
445 auto &Sym = (*Symbols)[SymIndex];
446
447 // Check symbol type.
448 switch (Sym.getType()) {
449 case ELF::STT_FILE:
450 LLVM_DEBUG({
451 if (auto Name = Sym.getName(*StringTab))
452 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
453 << *Name << "\"\n";
454 else {
455 dbgs() << "Could not get STT_FILE symbol name: "
456 << toString(Name.takeError()) << "\n";
457 dbgs() << " " << SymIndex
458 << ": Skipping STT_FILE symbol with invalid name\n";
459 }
460 });
461 continue;
462 break;
463 }
464
465 // Get the symbol name.
466 auto Name = Sym.getName(*StringTab);
467 if (!Name)
468 return Name.takeError();
469
470 // Handle common symbols specially.
471 if (Sym.isCommon()) {
472 Symbol &GSym = G->addDefinedSymbol(
473 G->createZeroFillBlock(getCommonSection(), Sym.st_size,
474 orc::ExecutorAddr(), Sym.getValue(), 0),
475 0, *Name, Sym.st_size, Linkage::Weak, Scope::Default, false, false);
476 setGraphSymbol(SymIndex, GSym);
477 continue;
478 }
479
480 if (Sym.isDefined() &&
481 (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
482 Sym.getType() == ELF::STT_OBJECT ||
483 Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
484
485 // Map Visibility and Binding to Scope and Linkage:
486 Linkage L;
487 Scope S;
488 if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
489 std::tie(L, S) = *LSOrErr;
490 else
491 return LSOrErr.takeError();
492
493 // Handle extended tables.
494 unsigned Shndx = Sym.st_shndx;
495 if (Shndx == ELF::SHN_XINDEX) {
496 auto ShndxTable = ShndxTables.find(SymTabSec);
497 if (ShndxTable == ShndxTables.end())
498 continue;
499 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
500 Sym, SymIndex, ShndxTable->second);
501 if (!NdxOrErr)
502 return NdxOrErr.takeError();
503 Shndx = *NdxOrErr;
504 }
505 if (auto *B = getGraphBlock(Shndx)) {
506 LLVM_DEBUG({
507 dbgs() << " " << SymIndex
508 << ": Creating defined graph symbol for ELF symbol \"" << *Name
509 << "\"\n";
510 });
511
512 TargetFlagsType Flags = makeTargetFlags(Sym);
513 orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
514
515 if (Offset + Sym.st_size > B->getSize()) {
516 std::string ErrMsg;
517 raw_string_ostream ErrStream(ErrMsg);
518 ErrStream << "In " << G->getName() << ", symbol ";
519 if (!Name->empty())
520 ErrStream << *Name;
521 else
522 ErrStream << "<anon>";
523 ErrStream << " (" << (B->getAddress() + Offset) << " -- "
524 << (B->getAddress() + Offset + Sym.st_size) << ") extends "
525 << formatv("{0:x}", Offset + Sym.st_size - B->getSize())
526 << " bytes past the end of its containing block ("
527 << B->getRange() << ")";
528 return make_error<JITLinkError>(std::move(ErrMsg));
529 }
530
531 // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
532 // sections...) will appear in object code's symbol table, and LLVM does
533 // not use names on these temporary symbols (RISCV gnu toolchain uses
534 // names on these temporary symbols). If the symbol is unnamed, add an
535 // anonymous symbol.
536 auto &GSym =
537 Name->empty()
538 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
539 false, false)
540 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
541 S, Sym.getType() == ELF::STT_FUNC,
542 false);
543
544 GSym.setTargetFlags(Flags);
545 setGraphSymbol(SymIndex, GSym);
546 }
547 } else if (Sym.isUndefined() && Sym.isExternal()) {
548 LLVM_DEBUG({
549 dbgs() << " " << SymIndex
550 << ": Creating external graph symbol for ELF symbol \"" << *Name
551 << "\"\n";
552 });
553
554 if (Sym.getBinding() != ELF::STB_GLOBAL &&
555 Sym.getBinding() != ELF::STB_WEAK)
556 return make_error<StringError>(
557 "Invalid symbol binding " +
558 Twine(static_cast<int>(Sym.getBinding())) +
559 " for external symbol " + *Name,
561
562 // If L is Linkage::Weak that means this is a weakly referenced symbol.
563 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
564 Sym.getBinding() == ELF::STB_WEAK);
565 setGraphSymbol(SymIndex, GSym);
566 } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&
567 Sym.getType() == ELF::STT_NOTYPE &&
568 Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {
569 // Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and
570 // use this kind of null symbol as a placeholder.
571 LLVM_DEBUG({
572 dbgs() << " " << SymIndex << ": Creating null graph symbol\n";
573 });
574
575 auto SymName =
576 G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));
577 auto SymNameRef = StringRef(SymName.data(), SymName.size());
578 auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,
580 setGraphSymbol(SymIndex, GSym);
581 } else {
582 LLVM_DEBUG({
583 dbgs() << " " << SymIndex
584 << ": Not creating graph symbol for ELF symbol \"" << *Name
585 << "\" with unrecognized type\n";
586 });
587 }
588 }
589
590 return Error::success();
591}
592
593template <typename ELFT>
594template <typename RelocHandlerFunction>
596 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
597 // Only look into sections that store relocation entries.
598 if (RelSect.sh_type != ELF::SHT_RELA)
599 return Error::success();
600
601 // sh_info contains the section header index of the target (FixupSection),
602 // which is the section to which all relocations in RelSect apply.
603 auto FixupSection = Obj.getSection(RelSect.sh_info);
604 if (!FixupSection)
605 return FixupSection.takeError();
606
607 // Target sections have names in valid ELF object files.
608 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
609 if (!Name)
610 return Name.takeError();
611 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
612
613 // Consider skipping these relocations.
614 if (!ProcessDebugSections && isDwarfSection(*Name)) {
615 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
616 return Error::success();
617 }
618 if (excludeSection(**FixupSection)) {
619 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
620 return Error::success();
621 }
622
623 // Lookup the link-graph node corresponding to the target section name.
624 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
625 if (!BlockToFix)
626 return make_error<StringError>(
627 "Refencing a section that wasn't added to the graph: " + *Name,
629
630 auto RelEntries = Obj.relas(RelSect);
631 if (!RelEntries)
632 return RelEntries.takeError();
633
634 // Let the callee process relocation entries one by one.
635 for (const typename ELFT::Rela &R : *RelEntries)
636 if (Error Err = Func(R, **FixupSection, *BlockToFix))
637 return Err;
638
639 LLVM_DEBUG(dbgs() << "\n");
640 return Error::success();
641}
642
643template <typename ELFT>
644template <typename RelocHandlerFunction>
646 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
647 // Only look into sections that store relocation entries.
648 if (RelSect.sh_type != ELF::SHT_REL)
649 return Error::success();
650
651 // sh_info contains the section header index of the target (FixupSection),
652 // which is the section to which all relocations in RelSect apply.
653 auto FixupSection = Obj.getSection(RelSect.sh_info);
654 if (!FixupSection)
655 return FixupSection.takeError();
656
657 // Target sections have names in valid ELF object files.
658 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
659 if (!Name)
660 return Name.takeError();
661 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
662
663 // Consider skipping these relocations.
664 if (!ProcessDebugSections && isDwarfSection(*Name)) {
665 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
666 return Error::success();
667 }
668 if (excludeSection(**FixupSection)) {
669 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
670 return Error::success();
671 }
672
673 // Lookup the link-graph node corresponding to the target section name.
674 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
675 if (!BlockToFix)
676 return make_error<StringError>(
677 "Refencing a section that wasn't added to the graph: " + *Name,
679
680 auto RelEntries = Obj.rels(RelSect);
681 if (!RelEntries)
682 return RelEntries.takeError();
683
684 // Let the callee process relocation entries one by one.
685 for (const typename ELFT::Rel &R : *RelEntries)
686 if (Error Err = Func(R, **FixupSection, *BlockToFix))
687 return Err;
688
689 LLVM_DEBUG(dbgs() << "\n");
690 return Error::success();
691}
692
693} // end namespace jitlink
694} // end namespace llvm
695
696#undef DEBUG_TYPE
697
698#endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
bbsections prepare
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define G(x, y, z)
Definition: MD5.cpp:56
static bool isDwarfSection(const MCObjectFileInfo *FI, const MCSection *Section)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Manages the enabling and disabling of subtarget specific features.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
const Elf_Ehdr & getHeader() const
Definition: ELF.h:278
Represents an address in the executor process.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
@ STV_INTERNAL
Definition: ELF.h:1370
@ STV_HIDDEN
Definition: ELF.h:1371
@ STV_PROTECTED
Definition: ELF.h:1372
@ STV_DEFAULT
Definition: ELF.h:1369
@ ET_REL
Definition: ELF.h:117
@ SHT_REL
Definition: ELF.h:1097
@ SHT_NULL
Definition: ELF.h:1088
@ SHT_NOBITS
Definition: ELF.h:1096
@ SHT_SYMTAB
Definition: ELF.h:1090
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1104
@ SHT_ARM_EXIDX
Definition: ELF.h:1144
@ SHT_RELA
Definition: ELF.h:1092
@ STB_GLOBAL
Definition: ELF.h:1340
@ STB_LOCAL
Definition: ELF.h:1339
@ STB_GNU_UNIQUE
Definition: ELF.h:1342
@ STB_WEAK
Definition: ELF.h:1341
@ SHN_XINDEX
Definition: ELF.h:1082
@ SHF_ALLOC
Definition: ELF.h:1186
@ SHF_WRITE
Definition: ELF.h:1183
@ SHF_EXECINSTR
Definition: ELF.h:1189
@ STT_FUNC
Definition: ELF.h:1353
@ STT_NOTYPE
Definition: ELF.h:1351
@ STT_SECTION
Definition: ELF.h:1354
@ STT_FILE
Definition: ELF.h:1355
@ STT_OBJECT
Definition: ELF.h:1352
@ STT_TLS
Definition: ELF.h:1357
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
MemProt
Describes Read/Write/Exec permissions for memory.
Definition: MemoryFlags.h:27
@ NoAlloc
NoAlloc memory should not be allocated by the JITLinkMemoryManager at all.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1856
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1886
endianness
Definition: bit.h:70
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858