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 std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
63 SubtargetFeatures Features, StringRef FileName,
65
66 /// Debug sections are included in the graph by default. Use
67 /// setProcessDebugSections(false) to ignore them if debug info is not
68 /// needed.
70 this->ProcessDebugSections = ProcessDebugSections;
71 return *this;
72 }
73
74 /// Attempt to construct and return the LinkGraph.
76
77 /// Call to derived class to handle relocations. These require
78 /// architecture specific knowledge to map to JITLink edge kinds.
79 virtual Error addRelocations() = 0;
80
81protected:
84
85 bool isRelocatable() const {
86 return Obj.getHeader().e_type == llvm::ELF::ET_REL;
87 }
88
90 assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
91 GraphBlocks[SecIndex] = B;
92 }
93
95 return GraphBlocks.lookup(SecIndex);
96 }
97
99 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
100 GraphSymbols[SymIndex] = &Sym;
101 }
102
104 return GraphSymbols.lookup(SymIndex);
105 }
106
108 getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
109
110 /// Set the target flags on the given Symbol.
111 virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) {
112 return TargetFlagsType{};
113 }
114
115 /// Get the physical offset of the symbol on the target platform.
116 virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
117 TargetFlagsType Flags) {
118 return Sym.getValue();
119 }
120
124
125 /// Override in derived classes to suppress certain sections in the link
126 /// graph.
127 virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {
128 return false;
129 }
130
131 /// Traverse all matching ELFT::Rela relocation records in the given section.
132 /// The handler function Func should be callable with this signature:
133 /// Error(const typename ELFT::Rela &,
134 /// const typename ELFT::Shdr &, Section &)
135 ///
136 template <typename RelocHandlerMethod>
137 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
138 RelocHandlerMethod &&Func);
139
140 /// Traverse all matching ELFT::Rel relocation records in the given section.
141 /// The handler function Func should be callable with this signature:
142 /// Error(const typename ELFT::Rel &,
143 /// const typename ELFT::Shdr &, Section &)
144 ///
145 template <typename RelocHandlerMethod>
146 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
147 RelocHandlerMethod &&Func);
148
149 /// Traverse all matching rela relocation records in the given section.
150 /// Convenience wrapper to allow passing a member function for the handler.
151 ///
152 template <typename ClassT, typename RelocHandlerMethod>
153 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
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 /// Traverse all matching rel relocation records in the given section.
163 /// Convenience wrapper to allow passing a member function for the handler.
164 ///
165 template <typename ClassT, typename RelocHandlerMethod>
166 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
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
175 const ELFFile &Obj;
176
177 typename ELFFile::Elf_Shdr_Range Sections;
178 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
181
182 // Maps ELF section indexes to LinkGraph Blocks.
183 // Only SHF_ALLOC sections will have graph blocks.
186 DenseMap<const typename ELFFile::Elf_Shdr *,
189};
190
191template <typename ELFT>
193 const ELFFile &Obj, std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
194 SubtargetFeatures Features, StringRef FileName,
196 : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
197 FileName.str(), std::move(SSP), Triple(std::move(TT)),
198 std::move(Features), ELFT::Is64Bits ? 8 : 4,
199 llvm::endianness(ELFT::Endianness), std::move(GetEdgeKindName))),
200 Obj(Obj) {
202 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
203}
204
205template <typename ELFT>
207 if (!isRelocatable())
208 return make_error<JITLinkError>("Object is not a relocatable ELF file");
209
210 if (auto Err = prepare())
211 return std::move(Err);
212
213 if (auto Err = graphifySections())
214 return std::move(Err);
215
216 if (auto Err = graphifySymbols())
217 return std::move(Err);
218
219 if (auto Err = addRelocations())
220 return std::move(Err);
221
222 return std::move(G);
223}
224
225template <typename ELFT>
228 const typename ELFT::Sym &Sym, StringRef Name) {
231
232 switch (Sym.getBinding()) {
233 case ELF::STB_LOCAL:
234 S = Scope::Local;
235 break;
236 case ELF::STB_GLOBAL:
237 // Nothing to do here.
238 break;
239 case ELF::STB_WEAK:
241 L = Linkage::Weak;
242 break;
243 default:
244 return make_error<StringError>(
245 "Unrecognized symbol binding " +
246 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
248 }
249
250 switch (Sym.getVisibility()) {
251 case ELF::STV_DEFAULT:
253 // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
254 // Orc support.
255 // Otherwise nothing to do here.
256 break;
257 case ELF::STV_HIDDEN:
258 // Default scope -> Hidden scope. No effect on local scope.
259 if (S == Scope::Default)
260 S = Scope::Hidden;
261 break;
263 return make_error<StringError>(
264 "Unrecognized symbol visibility " +
265 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
267 }
268
269 return std::make_pair(L, S);
270}
271
272template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
273 LLVM_DEBUG(dbgs() << " Preparing to build...\n");
274
275 // Get the sections array.
276 if (auto SectionsOrErr = Obj.sections())
277 Sections = *SectionsOrErr;
278 else
279 return SectionsOrErr.takeError();
280
281 // Get the section string table.
282 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
283 SectionStringTab = *SectionStringTabOrErr;
284 else
285 return SectionStringTabOrErr.takeError();
286
287 // Get the SHT_SYMTAB section.
288 for (auto &Sec : Sections) {
289 if (Sec.sh_type == ELF::SHT_SYMTAB) {
290 if (!SymTabSec)
291 SymTabSec = &Sec;
292 else
293 return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
294 G->getName());
295 }
296
297 // Extended table.
298 if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
299 uint32_t SymtabNdx = Sec.sh_link;
300 if (SymtabNdx >= Sections.size())
301 return make_error<JITLinkError>("sh_link is out of bound");
302
303 auto ShndxTable = Obj.getSHNDXTable(Sec);
304 if (!ShndxTable)
305 return ShndxTable.takeError();
306
307 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
308 }
309 }
310
311 return Error::success();
312}
313
315 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
316
317 // For each section...
318 for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
319
320 auto &Sec = Sections[SecIndex];
321
322 // Start by getting the section name.
323 auto Name = Obj.getSectionName(Sec, SectionStringTab);
324 if (!Name)
325 return Name.takeError();
326 if (excludeSection(Sec)) {
327 LLVM_DEBUG({
328 dbgs() << " " << SecIndex << ": Skipping section \"" << *Name
329 << "\" explicitly\n";
330 });
331 continue;
332 }
333
334 // Skip null sections.
335 if (Sec.sh_type == ELF::SHT_NULL) {
336 LLVM_DEBUG({
337 dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";
338 });
339 continue;
340 }
341
342 // If the name indicates that it's a debug section then skip it: We don't
343 // support those yet.
344 if (!ProcessDebugSections && isDwarfSection(*Name)) {
345 LLVM_DEBUG({
346 dbgs() << " " << SecIndex << ": \"" << *Name
347 << "\" is a debug section: "
348 "No graph section will be created.\n";
349 });
350 continue;
351 }
352
353 LLVM_DEBUG({
354 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
355 << "\"\n";
356 });
357
358 // Get the section's memory protection flags.
360 if (Sec.sh_flags & ELF::SHF_EXECINSTR)
361 Prot |= orc::MemProt::Exec;
362 if (Sec.sh_flags & ELF::SHF_WRITE)
363 Prot |= orc::MemProt::Write;
364
365 // Look for existing sections first.
366 auto *GraphSec = G->findSectionByName(*Name);
367 if (!GraphSec) {
368 GraphSec = &G->createSection(*Name, Prot);
369 // Non-SHF_ALLOC sections get NoAlloc memory lifetimes.
370 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
371 GraphSec->setMemLifetime(orc::MemLifetime::NoAlloc);
372 LLVM_DEBUG({
373 dbgs() << " " << SecIndex << ": \"" << *Name
374 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
375 });
376 }
377 }
378
379 if (GraphSec->getMemProt() != Prot) {
380 std::string ErrMsg;
381 raw_string_ostream(ErrMsg)
382 << "In " << G->getName() << ", section " << *Name
383 << " is present more than once with different permissions: "
384 << GraphSec->getMemProt() << " vs " << Prot;
385 return make_error<JITLinkError>(std::move(ErrMsg));
386 }
387
388 Block *B = nullptr;
389 if (Sec.sh_type != ELF::SHT_NOBITS) {
390 auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
391 if (!Data)
392 return Data.takeError();
393
394 B = &G->createContentBlock(*GraphSec, *Data,
395 orc::ExecutorAddr(Sec.sh_addr),
396 Sec.sh_addralign, 0);
397 } else
398 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
399 orc::ExecutorAddr(Sec.sh_addr),
400 Sec.sh_addralign, 0);
401
402 if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
403 // Add live symbol to avoid dead-stripping for .ARM.exidx sections
404 G->addAnonymousSymbol(*B, orc::ExecutorAddrDiff(),
405 orc::ExecutorAddrDiff(), false, true);
406 }
407
408 setGraphBlock(SecIndex, B);
409 }
410
411 return Error::success();
412}
413
415 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
416
417 // No SYMTAB -- Bail out early.
418 if (!SymTabSec)
419 return Error::success();
420
421 // Get the section content as a Symbols array.
422 auto Symbols = Obj.symbols(SymTabSec);
423 if (!Symbols)
424 return Symbols.takeError();
425
426 // Get the string table for this section.
427 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
428 if (!StringTab)
429 return StringTab.takeError();
430
431 LLVM_DEBUG({
432 StringRef SymTabName;
433
434 if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
435 SymTabName = *SymTabNameOrErr;
436 else {
437 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
438 << toString(SymTabNameOrErr.takeError()) << "\n";
439 SymTabName = "<SHT_SYMTAB section with invalid name>";
440 }
441
442 dbgs() << " Adding symbols from symtab section \"" << SymTabName
443 << "\"\n";
444 });
445
446 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
447 auto &Sym = (*Symbols)[SymIndex];
448
449 // Check symbol type.
450 switch (Sym.getType()) {
451 case ELF::STT_FILE:
452 LLVM_DEBUG({
453 if (auto Name = Sym.getName(*StringTab))
454 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
455 << *Name << "\"\n";
456 else {
457 dbgs() << "Could not get STT_FILE symbol name: "
458 << toString(Name.takeError()) << "\n";
459 dbgs() << " " << SymIndex
460 << ": Skipping STT_FILE symbol with invalid name\n";
461 }
462 });
463 continue;
464 break;
465 }
466
467 // Get the symbol name.
468 auto Name = Sym.getName(*StringTab);
469 if (!Name)
470 return Name.takeError();
471
472 // Handle common symbols specially.
473 if (Sym.isCommon()) {
474 Symbol &GSym = G->addDefinedSymbol(
475 G->createZeroFillBlock(getCommonSection(), Sym.st_size,
476 orc::ExecutorAddr(), Sym.getValue(), 0),
477 0, *Name, Sym.st_size, Linkage::Weak, Scope::Default, false, false);
478 setGraphSymbol(SymIndex, GSym);
479 continue;
480 }
481
482 if (Sym.isDefined() &&
483 (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
484 Sym.getType() == ELF::STT_OBJECT ||
485 Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
486
487 // Map Visibility and Binding to Scope and Linkage:
488 Linkage L;
489 Scope S;
490 if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
491 std::tie(L, S) = *LSOrErr;
492 else
493 return LSOrErr.takeError();
494
495 // Handle extended tables.
496 unsigned Shndx = Sym.st_shndx;
497 if (Shndx == ELF::SHN_XINDEX) {
498 auto ShndxTable = ShndxTables.find(SymTabSec);
499 if (ShndxTable == ShndxTables.end())
500 continue;
501 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
502 Sym, SymIndex, ShndxTable->second);
503 if (!NdxOrErr)
504 return NdxOrErr.takeError();
505 Shndx = *NdxOrErr;
506 }
507 if (auto *B = getGraphBlock(Shndx)) {
508 LLVM_DEBUG({
509 dbgs() << " " << SymIndex
510 << ": Creating defined graph symbol for ELF symbol \"" << *Name
511 << "\"\n";
512 });
513
514 TargetFlagsType Flags = makeTargetFlags(Sym);
515 orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
516
517 if (Offset + Sym.st_size > B->getSize()) {
518 std::string ErrMsg;
519 raw_string_ostream ErrStream(ErrMsg);
520 ErrStream << "In " << G->getName() << ", symbol ";
521 if (!Name->empty())
522 ErrStream << *Name;
523 else
524 ErrStream << "<anon>";
525 ErrStream << " (" << (B->getAddress() + Offset) << " -- "
526 << (B->getAddress() + Offset + Sym.st_size) << ") extends "
527 << formatv("{0:x}", Offset + Sym.st_size - B->getSize())
528 << " bytes past the end of its containing block ("
529 << B->getRange() << ")";
530 return make_error<JITLinkError>(std::move(ErrMsg));
531 }
532
533 // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
534 // sections...) will appear in object code's symbol table, and LLVM does
535 // not use names on these temporary symbols (RISCV gnu toolchain uses
536 // names on these temporary symbols). If the symbol is unnamed, add an
537 // anonymous symbol.
538 auto &GSym =
539 Name->empty()
540 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
541 false, false)
542 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
543 S, Sym.getType() == ELF::STT_FUNC,
544 false);
545
546 GSym.setTargetFlags(Flags);
547 setGraphSymbol(SymIndex, GSym);
548 }
549 } else if (Sym.isUndefined() && Sym.isExternal()) {
550 LLVM_DEBUG({
551 dbgs() << " " << SymIndex
552 << ": Creating external graph symbol for ELF symbol \"" << *Name
553 << "\"\n";
554 });
555
556 if (Sym.getBinding() != ELF::STB_GLOBAL &&
557 Sym.getBinding() != ELF::STB_WEAK)
558 return make_error<StringError>(
559 "Invalid symbol binding " +
560 Twine(static_cast<int>(Sym.getBinding())) +
561 " for external symbol " + *Name,
563
564 // If L is Linkage::Weak that means this is a weakly referenced symbol.
565 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
566 Sym.getBinding() == ELF::STB_WEAK);
567 setGraphSymbol(SymIndex, GSym);
568 } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&
569 Sym.getType() == ELF::STT_NOTYPE &&
570 Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {
571 // Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and
572 // use this kind of null symbol as a placeholder.
573 LLVM_DEBUG({
574 dbgs() << " " << SymIndex << ": Creating null graph symbol\n";
575 });
576
577 auto SymName =
578 G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));
579 auto SymNameRef = StringRef(SymName.data(), SymName.size());
580 auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,
582 setGraphSymbol(SymIndex, GSym);
583 } else {
584 LLVM_DEBUG({
585 dbgs() << " " << SymIndex
586 << ": Not creating graph symbol for ELF symbol \"" << *Name
587 << "\" with unrecognized type\n";
588 });
589 }
590 }
591
592 return Error::success();
593}
594
595template <typename ELFT>
596template <typename RelocHandlerFunction>
598 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
599 // Only look into sections that store relocation entries.
600 if (RelSect.sh_type != ELF::SHT_RELA)
601 return Error::success();
602
603 // sh_info contains the section header index of the target (FixupSection),
604 // which is the section to which all relocations in RelSect apply.
605 auto FixupSection = Obj.getSection(RelSect.sh_info);
606 if (!FixupSection)
607 return FixupSection.takeError();
608
609 // Target sections have names in valid ELF object files.
610 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
611 if (!Name)
612 return Name.takeError();
613 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
614
615 // Consider skipping these relocations.
616 if (!ProcessDebugSections && isDwarfSection(*Name)) {
617 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
618 return Error::success();
619 }
620 if (excludeSection(**FixupSection)) {
621 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
622 return Error::success();
623 }
624
625 // Lookup the link-graph node corresponding to the target section name.
626 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
627 if (!BlockToFix)
628 return make_error<StringError>(
629 "Refencing a section that wasn't added to the graph: " + *Name,
631
632 auto RelEntries = Obj.relas(RelSect);
633 if (!RelEntries)
634 return RelEntries.takeError();
635
636 // Let the callee process relocation entries one by one.
637 for (const typename ELFT::Rela &R : *RelEntries)
638 if (Error Err = Func(R, **FixupSection, *BlockToFix))
639 return Err;
640
641 LLVM_DEBUG(dbgs() << "\n");
642 return Error::success();
643}
644
645template <typename ELFT>
646template <typename RelocHandlerFunction>
648 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
649 // Only look into sections that store relocation entries.
650 if (RelSect.sh_type != ELF::SHT_REL)
651 return Error::success();
652
653 // sh_info contains the section header index of the target (FixupSection),
654 // which is the section to which all relocations in RelSect apply.
655 auto FixupSection = Obj.getSection(RelSect.sh_info);
656 if (!FixupSection)
657 return FixupSection.takeError();
658
659 // Target sections have names in valid ELF object files.
660 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
661 if (!Name)
662 return Name.takeError();
663 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
664
665 // Consider skipping these relocations.
666 if (!ProcessDebugSections && isDwarfSection(*Name)) {
667 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
668 return Error::success();
669 }
670 if (excludeSection(**FixupSection)) {
671 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
672 return Error::success();
673 }
674
675 // Lookup the link-graph node corresponding to the target section name.
676 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
677 if (!BlockToFix)
678 return make_error<StringError>(
679 "Refencing a section that wasn't added to the graph: " + *Name,
681
682 auto RelEntries = Obj.rels(RelSect);
683 if (!RelEntries)
684 return RelEntries.takeError();
685
686 // Let the callee process relocation entries one by one.
687 for (const typename ELFT::Rel &R : *RelEntries)
688 if (Error Err = Func(R, **FixupSection, *BlockToFix))
689 return Err;
690
691 LLVM_DEBUG(dbgs() << "\n");
692 return Error::success();
693}
694
695} // end namespace jitlink
696} // end namespace llvm
697
698#undef DEBUG_TYPE
699
700#endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
bbsections prepare
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DEBUG(...)
Definition: Debug.h:106
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:51
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:279
Represents an address in the executor process.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
@ SHN_XINDEX
Definition: ELF.h:1083
@ SHT_REL
Definition: ELF.h:1098
@ SHT_NULL
Definition: ELF.h:1089
@ SHT_NOBITS
Definition: ELF.h:1097
@ SHT_SYMTAB
Definition: ELF.h:1091
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1105
@ SHT_ARM_EXIDX
Definition: ELF.h:1146
@ SHT_RELA
Definition: ELF.h:1093
@ SHF_ALLOC
Definition: ELF.h:1188
@ SHF_WRITE
Definition: ELF.h:1185
@ SHF_EXECINSTR
Definition: ELF.h:1191
@ STB_GLOBAL
Definition: ELF.h:1342
@ STB_LOCAL
Definition: ELF.h:1341
@ STB_GNU_UNIQUE
Definition: ELF.h:1344
@ STB_WEAK
Definition: ELF.h:1343
@ ET_REL
Definition: ELF.h:117
@ STT_FUNC
Definition: ELF.h:1355
@ STT_NOTYPE
Definition: ELF.h:1353
@ STT_SECTION
Definition: ELF.h:1356
@ STT_FILE
Definition: ELF.h:1357
@ STT_OBJECT
Definition: ELF.h:1354
@ STT_TLS
Definition: ELF.h:1359
@ STV_INTERNAL
Definition: ELF.h:1372
@ STV_HIDDEN
Definition: ELF.h:1373
@ STV_PROTECTED
Definition: ELF.h:1374
@ STV_DEFAULT
Definition: ELF.h:1371
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(bool Validate, const char *Fmt, 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:1873
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1903
const char * toString(DWARFSectionKind Kind)
endianness
Definition: bit.h:70
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858