LLVM 17.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/// Ling-graph building code that's specific to the given ELFT, but common
55/// across all architectures.
56template <typename ELFT>
59
60public:
62 LinkGraph::FeatureVector 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 auto I = GraphBlocks.find(SecIndex);
95 if (I == GraphBlocks.end())
96 return nullptr;
97 return I->second;
98 }
99
101 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
102 GraphSymbols[SymIndex] = &Sym;
103 }
104
106 auto I = GraphSymbols.find(SymIndex);
107 if (I == GraphSymbols.end())
108 return nullptr;
109 return I->second;
110 }
111
113 getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
114
115 /// Set the target flags on the given Symbol.
116 virtual TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) {
117 return TargetFlagsType{};
118 }
119
120 /// Get the physical offset of the symbol on the target platform.
121 virtual orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym,
123 return Sym.getValue();
124 }
125
129
130 /// Override in derived classes to suppress certain sections in the link
131 /// graph.
132 virtual bool excludeSection(const typename ELFT::Shdr &Sect) const {
133 return false;
134 }
135
136 /// Traverse all matching ELFT::Rela relocation records in the given section.
137 /// The handler function Func should be callable with this signature:
138 /// Error(const typename ELFT::Rela &,
139 /// const typename ELFT::Shdr &, Section &)
140 ///
141 template <typename RelocHandlerMethod>
142 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
143 RelocHandlerMethod &&Func);
144
145 /// Traverse all matching ELFT::Rel relocation records in the given section.
146 /// The handler function Func should be callable with this signature:
147 /// Error(const typename ELFT::Rel &,
148 /// const typename ELFT::Shdr &, Section &)
149 ///
150 template <typename RelocHandlerMethod>
151 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
152 RelocHandlerMethod &&Func);
153
154 /// Traverse all matching rela relocation records in the given section.
155 /// Convenience wrapper to allow passing a member function for the handler.
156 ///
157 template <typename ClassT, typename RelocHandlerMethod>
158 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
159 ClassT *Instance, RelocHandlerMethod &&Method) {
161 RelSect,
162 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
163 return (Instance->*Method)(Rel, Target, GS);
164 });
165 }
166
167 /// Traverse all matching rel relocation records in the given section.
168 /// Convenience wrapper to allow passing a member function for the handler.
169 ///
170 template <typename ClassT, typename RelocHandlerMethod>
171 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
172 ClassT *Instance, RelocHandlerMethod &&Method) {
174 RelSect,
175 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
176 return (Instance->*Method)(Rel, Target, GS);
177 });
178 }
179
180 const ELFFile &Obj;
181
182 typename ELFFile::Elf_Shdr_Range Sections;
183 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
186
187 // Maps ELF section indexes to LinkGraph Blocks.
188 // Only SHF_ALLOC sections will have graph blocks.
191 DenseMap<const typename ELFFile::Elf_Shdr *,
194};
195
196template <typename ELFT>
198 const ELFFile &Obj, Triple TT, LinkGraph::FeatureVector Features,
199 StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
200 : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
201 FileName.str(), Triple(std::move(TT)), std::move(Features),
202 ELFT::Is64Bits ? 8 : 4, support::endianness(ELFT::TargetEndianness),
203 std::move(GetEdgeKindName))),
204 Obj(Obj) {
206 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
207}
208
209template <typename ELFT>
211 if (!isRelocatable())
212 return make_error<JITLinkError>("Object is not a relocatable ELF file");
213
214 if (auto Err = prepare())
215 return std::move(Err);
216
217 if (auto Err = graphifySections())
218 return std::move(Err);
219
220 if (auto Err = graphifySymbols())
221 return std::move(Err);
222
223 if (auto Err = addRelocations())
224 return std::move(Err);
225
226 return std::move(G);
227}
228
229template <typename ELFT>
232 const typename ELFT::Sym &Sym, StringRef Name) {
235
236 switch (Sym.getBinding()) {
237 case ELF::STB_LOCAL:
238 S = Scope::Local;
239 break;
240 case ELF::STB_GLOBAL:
241 // Nothing to do here.
242 break;
243 case ELF::STB_WEAK:
245 L = Linkage::Weak;
246 break;
247 default:
248 return make_error<StringError>(
249 "Unrecognized symbol binding " +
250 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
252 }
253
254 switch (Sym.getVisibility()) {
255 case ELF::STV_DEFAULT:
257 // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
258 // Orc support.
259 // Otherwise nothing to do here.
260 break;
261 case ELF::STV_HIDDEN:
262 // Default scope -> Hidden scope. No effect on local scope.
263 if (S == Scope::Default)
264 S = Scope::Hidden;
265 break;
267 return make_error<StringError>(
268 "Unrecognized symbol visibility " +
269 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
271 }
272
273 return std::make_pair(L, S);
274}
275
276template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
277 LLVM_DEBUG(dbgs() << " Preparing to build...\n");
278
279 // Get the sections array.
280 if (auto SectionsOrErr = Obj.sections())
281 Sections = *SectionsOrErr;
282 else
283 return SectionsOrErr.takeError();
284
285 // Get the section string table.
286 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
287 SectionStringTab = *SectionStringTabOrErr;
288 else
289 return SectionStringTabOrErr.takeError();
290
291 // Get the SHT_SYMTAB section.
292 for (auto &Sec : Sections) {
293 if (Sec.sh_type == ELF::SHT_SYMTAB) {
294 if (!SymTabSec)
295 SymTabSec = &Sec;
296 else
297 return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
298 G->getName());
299 }
300
301 // Extended table.
302 if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
303 uint32_t SymtabNdx = Sec.sh_link;
304 if (SymtabNdx >= Sections.size())
305 return make_error<JITLinkError>("sh_link is out of bound");
306
307 auto ShndxTable = Obj.getSHNDXTable(Sec);
308 if (!ShndxTable)
309 return ShndxTable.takeError();
310
311 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
312 }
313 }
314
315 return Error::success();
316}
317
319 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
320
321 // For each section...
322 for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
323
324 auto &Sec = Sections[SecIndex];
325
326 // Start by getting the section name.
327 auto Name = Obj.getSectionName(Sec, SectionStringTab);
328 if (!Name)
329 return Name.takeError();
330 if (excludeSection(Sec)) {
331 LLVM_DEBUG({
332 dbgs() << " " << SecIndex << ": Skipping section \"" << *Name
333 << "\" explicitly\n";
334 });
335 continue;
336 }
337
338 // Skip null sections.
339 if (Sec.sh_type == ELF::SHT_NULL) {
340 LLVM_DEBUG({
341 dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";
342 });
343 continue;
344 }
345
346 // If the name indicates that it's a debug section then skip it: We don't
347 // support those yet.
348 if (!ProcessDebugSections && isDwarfSection(*Name)) {
349 LLVM_DEBUG({
350 dbgs() << " " << SecIndex << ": \"" << *Name
351 << "\" is a debug section: "
352 "No graph section will be created.\n";
353 });
354 continue;
355 }
356
357 LLVM_DEBUG({
358 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
359 << "\"\n";
360 });
361
362 // Get the section's memory protection flags.
364 if (Sec.sh_flags & ELF::SHF_EXECINSTR)
365 Prot |= orc::MemProt::Exec;
366 if (Sec.sh_flags & ELF::SHF_WRITE)
367 Prot |= orc::MemProt::Write;
368
369 // Look for existing sections first.
370 auto *GraphSec = G->findSectionByName(*Name);
371 if (!GraphSec) {
372 GraphSec = &G->createSection(*Name, Prot);
373 // Non-SHF_ALLOC sections get NoAlloc memory lifetimes.
374 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
375 GraphSec->setMemLifetimePolicy(orc::MemLifetimePolicy::NoAlloc);
376 LLVM_DEBUG({
377 dbgs() << " " << SecIndex << ": \"" << *Name
378 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
379 });
380 }
381 }
382
383 assert(GraphSec->getMemProt() == Prot && "MemProt should match");
384
385 Block *B = nullptr;
386 if (Sec.sh_type != ELF::SHT_NOBITS) {
387 auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
388 if (!Data)
389 return Data.takeError();
390
391 B = &G->createContentBlock(*GraphSec, *Data,
392 orc::ExecutorAddr(Sec.sh_addr),
393 Sec.sh_addralign, 0);
394 } else
395 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
396 orc::ExecutorAddr(Sec.sh_addr),
397 Sec.sh_addralign, 0);
398
399 setGraphBlock(SecIndex, B);
400 }
401
402 return Error::success();
403}
404
406 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
407
408 // No SYMTAB -- Bail out early.
409 if (!SymTabSec)
410 return Error::success();
411
412 // Get the section content as a Symbols array.
413 auto Symbols = Obj.symbols(SymTabSec);
414 if (!Symbols)
415 return Symbols.takeError();
416
417 // Get the string table for this section.
418 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
419 if (!StringTab)
420 return StringTab.takeError();
421
422 LLVM_DEBUG({
423 StringRef SymTabName;
424
425 if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
426 SymTabName = *SymTabNameOrErr;
427 else {
428 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
429 << toString(SymTabNameOrErr.takeError()) << "\n";
430 SymTabName = "<SHT_SYMTAB section with invalid name>";
431 }
432
433 dbgs() << " Adding symbols from symtab section \"" << SymTabName
434 << "\"\n";
435 });
436
437 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
438 auto &Sym = (*Symbols)[SymIndex];
439
440 // Check symbol type.
441 switch (Sym.getType()) {
442 case ELF::STT_FILE:
443 LLVM_DEBUG({
444 if (auto Name = Sym.getName(*StringTab))
445 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
446 << *Name << "\"\n";
447 else {
448 dbgs() << "Could not get STT_FILE symbol name: "
449 << toString(Name.takeError()) << "\n";
450 dbgs() << " " << SymIndex
451 << ": Skipping STT_FILE symbol with invalid name\n";
452 }
453 });
454 continue;
455 break;
456 }
457
458 // Get the symbol name.
459 auto Name = Sym.getName(*StringTab);
460 if (!Name)
461 return Name.takeError();
462
463 // Handle common symbols specially.
464 if (Sym.isCommon()) {
465 Symbol &GSym = G->addDefinedSymbol(
466 G->createZeroFillBlock(getCommonSection(), Sym.st_size,
467 orc::ExecutorAddr(), Sym.getValue(), 0),
468 0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false);
469 setGraphSymbol(SymIndex, GSym);
470 continue;
471 }
472
473 if (Sym.isDefined() &&
474 (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
475 Sym.getType() == ELF::STT_OBJECT ||
476 Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
477
478 // Map Visibility and Binding to Scope and Linkage:
479 Linkage L;
480 Scope S;
481 if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
482 std::tie(L, S) = *LSOrErr;
483 else
484 return LSOrErr.takeError();
485
486 // Handle extended tables.
487 unsigned Shndx = Sym.st_shndx;
488 if (Shndx == ELF::SHN_XINDEX) {
489 auto ShndxTable = ShndxTables.find(SymTabSec);
490 if (ShndxTable == ShndxTables.end())
491 continue;
492 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
493 Sym, SymIndex, ShndxTable->second);
494 if (!NdxOrErr)
495 return NdxOrErr.takeError();
496 Shndx = *NdxOrErr;
497 }
498 if (auto *B = getGraphBlock(Shndx)) {
499 LLVM_DEBUG({
500 dbgs() << " " << SymIndex
501 << ": Creating defined graph symbol for ELF symbol \"" << *Name
502 << "\"\n";
503 });
504
505 TargetFlagsType Flags = makeTargetFlags(Sym);
506 orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);
507
508 // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
509 // sections...) will appear in object code's symbol table, and LLVM does
510 // not use names on these temporary symbols (RISCV gnu toolchain uses
511 // names on these temporary symbols). If the symbol is unnamed, add an
512 // anonymous symbol.
513 auto &GSym =
514 Name->empty()
515 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,
516 false, false)
517 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,
518 S, Sym.getType() == ELF::STT_FUNC,
519 false);
520
521 GSym.setTargetFlags(Flags);
522 setGraphSymbol(SymIndex, GSym);
523 }
524 } else if (Sym.isUndefined() && Sym.isExternal()) {
525 LLVM_DEBUG({
526 dbgs() << " " << SymIndex
527 << ": Creating external graph symbol for ELF symbol \"" << *Name
528 << "\"\n";
529 });
530
531 if (Sym.getBinding() != ELF::STB_GLOBAL &&
532 Sym.getBinding() != ELF::STB_WEAK)
533 return make_error<StringError>(
534 "Invalid symbol binding " +
535 Twine(static_cast<int>(Sym.getBinding())) +
536 " for external symbol " + *Name,
538
539 // If L is Linkage::Weak that means this is a weakly referenced symbol.
540 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
541 Sym.getBinding() == ELF::STB_WEAK);
542 setGraphSymbol(SymIndex, GSym);
543 } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&
544 Sym.getType() == ELF::STT_NOTYPE &&
545 Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {
546 // Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and
547 // use this kind of null symbol as a placeholder.
548 LLVM_DEBUG({
549 dbgs() << " " << SymIndex << ": Creating null graph symbol\n";
550 });
551
552 auto SymName =
553 G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));
554 auto SymNameRef = StringRef(SymName.data(), SymName.size());
555 auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,
557 setGraphSymbol(SymIndex, GSym);
558 } else {
559 LLVM_DEBUG({
560 dbgs() << " " << SymIndex
561 << ": Not creating graph symbol for ELF symbol \"" << *Name
562 << "\" with unrecognized type\n";
563 });
564 }
565 }
566
567 return Error::success();
568}
569
570template <typename ELFT>
571template <typename RelocHandlerFunction>
573 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
574 // Only look into sections that store relocation entries.
575 if (RelSect.sh_type != ELF::SHT_RELA)
576 return Error::success();
577
578 // sh_info contains the section header index of the target (FixupSection),
579 // which is the section to which all relocations in RelSect apply.
580 auto FixupSection = Obj.getSection(RelSect.sh_info);
581 if (!FixupSection)
582 return FixupSection.takeError();
583
584 // Target sections have names in valid ELF object files.
585 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
586 if (!Name)
587 return Name.takeError();
588 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
589
590 // Consider skipping these relocations.
591 if (!ProcessDebugSections && isDwarfSection(*Name)) {
592 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
593 return Error::success();
594 }
595 if (excludeSection(**FixupSection)) {
596 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
597 return Error::success();
598 }
599
600 // Lookup the link-graph node corresponding to the target section name.
601 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
602 if (!BlockToFix)
603 return make_error<StringError>(
604 "Refencing a section that wasn't added to the graph: " + *Name,
606
607 auto RelEntries = Obj.relas(RelSect);
608 if (!RelEntries)
609 return RelEntries.takeError();
610
611 // Let the callee process relocation entries one by one.
612 for (const typename ELFT::Rela &R : *RelEntries)
613 if (Error Err = Func(R, **FixupSection, *BlockToFix))
614 return Err;
615
616 LLVM_DEBUG(dbgs() << "\n");
617 return Error::success();
618}
619
620template <typename ELFT>
621template <typename RelocHandlerFunction>
623 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {
624 // Only look into sections that store relocation entries.
625 if (RelSect.sh_type != ELF::SHT_REL)
626 return Error::success();
627
628 // sh_info contains the section header index of the target (FixupSection),
629 // which is the section to which all relocations in RelSect apply.
630 auto FixupSection = Obj.getSection(RelSect.sh_info);
631 if (!FixupSection)
632 return FixupSection.takeError();
633
634 // Target sections have names in valid ELF object files.
635 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
636 if (!Name)
637 return Name.takeError();
638 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
639
640 // Consider skipping these relocations.
641 if (!ProcessDebugSections && isDwarfSection(*Name)) {
642 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
643 return Error::success();
644 }
645 if (excludeSection(**FixupSection)) {
646 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
647 return Error::success();
648 }
649
650 // Lookup the link-graph node corresponding to the target section name.
651 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
652 if (!BlockToFix)
653 return make_error<StringError>(
654 "Refencing a section that wasn't added to the graph: " + *Name,
656
657 auto RelEntries = Obj.rels(RelSect);
658 if (!RelEntries)
659 return RelEntries.takeError();
660
661 // Let the callee process relocation entries one by one.
662 for (const typename ELFT::Rel &R : *RelEntries)
663 if (Error Err = Func(R, **FixupSection, *BlockToFix))
664 return Err;
665
666 LLVM_DEBUG(dbgs() << "\n");
667 return Error::success();
668}
669
670} // end namespace jitlink
671} // end namespace llvm
672
673#undef DEBUG_TYPE
674
675#endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
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:463
#define I(x, y, z)
Definition: MD5.cpp:58
#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())
@ Flags
Definition: TextStubV5.cpp:93
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:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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:192
Represents an address in the executor process.
@ SHF_ALLOC
Definition: ELF.h:1088
@ SHF_WRITE
Definition: ELF.h:1085
@ SHF_EXECINSTR
Definition: ELF.h:1091
@ STV_INTERNAL
Definition: ELF.h:1272
@ STV_HIDDEN
Definition: ELF.h:1273
@ STV_PROTECTED
Definition: ELF.h:1274
@ STV_DEFAULT
Definition: ELF.h:1271
@ SHN_XINDEX
Definition: ELF.h:993
@ SHT_REL
Definition: ELF.h:1008
@ SHT_NULL
Definition: ELF.h:999
@ SHT_NOBITS
Definition: ELF.h:1007
@ SHT_SYMTAB
Definition: ELF.h:1001
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:1015
@ SHT_RELA
Definition: ELF.h:1003
@ STB_GLOBAL
Definition: ELF.h:1242
@ STB_LOCAL
Definition: ELF.h:1241
@ STB_GNU_UNIQUE
Definition: ELF.h:1244
@ STB_WEAK
Definition: ELF.h:1243
@ ET_REL
Definition: ELF.h:116
@ STT_FUNC
Definition: ELF.h:1255
@ STT_NOTYPE
Definition: ELF.h:1253
@ STT_SECTION
Definition: ELF.h:1256
@ STT_FILE
Definition: ELF.h:1257
@ STT_OBJECT
Definition: ELF.h:1254
@ STT_TLS
Definition: ELF.h:1259
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:406
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
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:1946
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1976
Definition: BitVector.h:858