1 //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Generic ELF LinkGraph building code.
11 //===----------------------------------------------------------------------===//
13 #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
16 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
17 #include "llvm/Object/ELF.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/FormatVariadic.h"
22 #define DEBUG_TYPE "jitlink"
27 /// Common link-graph building code shared between all ELFFiles.
28 class ELFLinkGraphBuilderBase
{
30 ELFLinkGraphBuilderBase(std::unique_ptr
<LinkGraph
> G
) : G(std::move(G
)) {}
31 virtual ~ELFLinkGraphBuilderBase();
34 static bool isDwarfSection(StringRef SectionName
) {
35 return llvm::is_contained(DwarfSectionNames
, SectionName
);
38 Section
&getCommonSection() {
40 CommonSection
= &G
->createSection(
41 CommonSectionName
, orc::MemProt::Read
| orc::MemProt::Write
);
42 return *CommonSection
;
45 std::unique_ptr
<LinkGraph
> G
;
48 static StringRef CommonSectionName
;
49 static ArrayRef
<const char *> DwarfSectionNames
;
51 Section
*CommonSection
= nullptr;
54 /// LinkGraph building code that's specific to the given ELFT, but common
55 /// across all architectures.
56 template <typename ELFT
>
57 class ELFLinkGraphBuilder
: public ELFLinkGraphBuilderBase
{
58 using ELFFile
= object::ELFFile
<ELFT
>;
61 ELFLinkGraphBuilder(const object::ELFFile
<ELFT
> &Obj
, Triple TT
,
62 SubtargetFeatures Features
, StringRef FileName
,
63 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName
);
65 /// Debug sections are included in the graph by default. Use
66 /// setProcessDebugSections(false) to ignore them if debug info is not
68 ELFLinkGraphBuilder
&setProcessDebugSections(bool ProcessDebugSections
) {
69 this->ProcessDebugSections
= ProcessDebugSections
;
73 /// Attempt to construct and return the LinkGraph.
74 Expected
<std::unique_ptr
<LinkGraph
>> buildGraph();
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;
81 using ELFSectionIndex
= unsigned;
82 using ELFSymbolIndex
= unsigned;
84 bool isRelocatable() const {
85 return Obj
.getHeader().e_type
== llvm::ELF::ET_REL
;
88 void setGraphBlock(ELFSectionIndex SecIndex
, Block
*B
) {
89 assert(!GraphBlocks
.count(SecIndex
) && "Duplicate section at index");
90 GraphBlocks
[SecIndex
] = B
;
93 Block
*getGraphBlock(ELFSectionIndex SecIndex
) {
94 return GraphBlocks
.lookup(SecIndex
);
97 void setGraphSymbol(ELFSymbolIndex SymIndex
, Symbol
&Sym
) {
98 assert(!GraphSymbols
.count(SymIndex
) && "Duplicate symbol at index");
99 GraphSymbols
[SymIndex
] = &Sym
;
102 Symbol
*getGraphSymbol(ELFSymbolIndex SymIndex
) {
103 return GraphSymbols
.lookup(SymIndex
);
106 Expected
<std::pair
<Linkage
, Scope
>>
107 getSymbolLinkageAndScope(const typename
ELFT::Sym
&Sym
, StringRef Name
);
109 /// Set the target flags on the given Symbol.
110 virtual TargetFlagsType
makeTargetFlags(const typename
ELFT::Sym
&Sym
) {
111 return TargetFlagsType
{};
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();
121 Error
graphifySections();
122 Error
graphifySymbols();
124 /// Override in derived classes to suppress certain sections in the link
126 virtual bool excludeSection(const typename
ELFT::Shdr
&Sect
) const {
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 &)
135 template <typename RelocHandlerMethod
>
136 Error
forEachRelaRelocation(const typename
ELFT::Shdr
&RelSect
,
137 RelocHandlerMethod
&&Func
);
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 &)
144 template <typename RelocHandlerMethod
>
145 Error
forEachRelRelocation(const typename
ELFT::Shdr
&RelSect
,
146 RelocHandlerMethod
&&Func
);
148 /// Traverse all matching rela relocation records in the given section.
149 /// Convenience wrapper to allow passing a member function for the handler.
151 template <typename ClassT
, typename RelocHandlerMethod
>
152 Error
forEachRelaRelocation(const typename
ELFT::Shdr
&RelSect
,
153 ClassT
*Instance
, RelocHandlerMethod
&&Method
) {
154 return forEachRelaRelocation(
156 [Instance
, Method
](const auto &Rel
, const auto &Target
, auto &GS
) {
157 return (Instance
->*Method
)(Rel
, Target
, GS
);
161 /// Traverse all matching rel relocation records in the given section.
162 /// Convenience wrapper to allow passing a member function for the handler.
164 template <typename ClassT
, typename RelocHandlerMethod
>
165 Error
forEachRelRelocation(const typename
ELFT::Shdr
&RelSect
,
166 ClassT
*Instance
, RelocHandlerMethod
&&Method
) {
167 return forEachRelRelocation(
169 [Instance
, Method
](const auto &Rel
, const auto &Target
, auto &GS
) {
170 return (Instance
->*Method
)(Rel
, Target
, GS
);
176 typename
ELFFile::Elf_Shdr_Range Sections
;
177 const typename
ELFFile::Elf_Shdr
*SymTabSec
= nullptr;
178 StringRef SectionStringTab
;
179 bool ProcessDebugSections
= true;
181 // Maps ELF section indexes to LinkGraph Blocks.
182 // Only SHF_ALLOC sections will have graph blocks.
183 DenseMap
<ELFSectionIndex
, Block
*> GraphBlocks
;
184 DenseMap
<ELFSymbolIndex
, Symbol
*> GraphSymbols
;
185 DenseMap
<const typename
ELFFile::Elf_Shdr
*,
186 ArrayRef
<typename
ELFFile::Elf_Word
>>
190 template <typename ELFT
>
191 ELFLinkGraphBuilder
<ELFT
>::ELFLinkGraphBuilder(
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::TargetEndianness
),
197 std::move(GetEdgeKindName
))),
200 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName
<< "\""; });
203 template <typename ELFT
>
204 Expected
<std::unique_ptr
<LinkGraph
>> ELFLinkGraphBuilder
<ELFT
>::buildGraph() {
205 if (!isRelocatable())
206 return make_error
<JITLinkError
>("Object is not a relocatable ELF file");
208 if (auto Err
= prepare())
209 return std::move(Err
);
211 if (auto Err
= graphifySections())
212 return std::move(Err
);
214 if (auto Err
= graphifySymbols())
215 return std::move(Err
);
217 if (auto Err
= addRelocations())
218 return std::move(Err
);
223 template <typename ELFT
>
224 Expected
<std::pair
<Linkage
, Scope
>>
225 ELFLinkGraphBuilder
<ELFT
>::getSymbolLinkageAndScope(
226 const typename
ELFT::Sym
&Sym
, StringRef Name
) {
227 Linkage L
= Linkage::Strong
;
228 Scope S
= Scope::Default
;
230 switch (Sym
.getBinding()) {
234 case ELF::STB_GLOBAL
:
235 // Nothing to do here.
238 case ELF::STB_GNU_UNIQUE
:
242 return make_error
<StringError
>(
243 "Unrecognized symbol binding " +
244 Twine(static_cast<int>(Sym
.getBinding())) + " for " + Name
,
245 inconvertibleErrorCode());
248 switch (Sym
.getVisibility()) {
249 case ELF::STV_DEFAULT
:
250 case ELF::STV_PROTECTED
:
251 // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
253 // Otherwise nothing to do here.
255 case ELF::STV_HIDDEN
:
256 // Default scope -> Hidden scope. No effect on local scope.
257 if (S
== Scope::Default
)
260 case ELF::STV_INTERNAL
:
261 return make_error
<StringError
>(
262 "Unrecognized symbol visibility " +
263 Twine(static_cast<int>(Sym
.getVisibility())) + " for " + Name
,
264 inconvertibleErrorCode());
267 return std::make_pair(L
, S
);
270 template <typename ELFT
> Error ELFLinkGraphBuilder
<ELFT
>::prepare() {
271 LLVM_DEBUG(dbgs() << " Preparing to build...\n");
273 // Get the sections array.
274 if (auto SectionsOrErr
= Obj
.sections())
275 Sections
= *SectionsOrErr
;
277 return SectionsOrErr
.takeError();
279 // Get the section string table.
280 if (auto SectionStringTabOrErr
= Obj
.getSectionStringTable(Sections
))
281 SectionStringTab
= *SectionStringTabOrErr
;
283 return SectionStringTabOrErr
.takeError();
285 // Get the SHT_SYMTAB section.
286 for (auto &Sec
: Sections
) {
287 if (Sec
.sh_type
== ELF::SHT_SYMTAB
) {
291 return make_error
<JITLinkError
>("Multiple SHT_SYMTAB sections in " +
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");
301 auto ShndxTable
= Obj
.getSHNDXTable(Sec
);
303 return ShndxTable
.takeError();
305 ShndxTables
.insert({&Sections
[SymtabNdx
], *ShndxTable
});
309 return Error::success();
312 template <typename ELFT
> Error ELFLinkGraphBuilder
<ELFT
>::graphifySections() {
313 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
315 // For each section...
316 for (ELFSectionIndex SecIndex
= 0; SecIndex
!= Sections
.size(); ++SecIndex
) {
318 auto &Sec
= Sections
[SecIndex
];
320 // Start by getting the section name.
321 auto Name
= Obj
.getSectionName(Sec
, SectionStringTab
);
323 return Name
.takeError();
324 if (excludeSection(Sec
)) {
326 dbgs() << " " << SecIndex
<< ": Skipping section \"" << *Name
327 << "\" explicitly\n";
332 // Skip null sections.
333 if (Sec
.sh_type
== ELF::SHT_NULL
) {
335 dbgs() << " " << SecIndex
<< ": has type SHT_NULL. Skipping.\n";
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
)) {
344 dbgs() << " " << SecIndex
<< ": \"" << *Name
345 << "\" is a debug section: "
346 "No graph section will be created.\n";
352 dbgs() << " " << SecIndex
<< ": Creating section for \"" << *Name
356 // Get the section's memory protection flags.
357 orc::MemProt Prot
= orc::MemProt::Read
;
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
;
363 // Look for existing sections first.
364 auto *GraphSec
= G
->findSectionByName(*Name
);
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
);
371 dbgs() << " " << SecIndex
<< ": \"" << *Name
372 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";
377 if (GraphSec
->getMemProt() != Prot
) {
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
));
387 if (Sec
.sh_type
!= ELF::SHT_NOBITS
) {
388 auto Data
= Obj
.template getSectionContentsAsArray
<char>(Sec
);
390 return Data
.takeError();
392 B
= &G
->createContentBlock(*GraphSec
, *Data
,
393 orc::ExecutorAddr(Sec
.sh_addr
),
394 Sec
.sh_addralign
, 0);
396 B
= &G
->createZeroFillBlock(*GraphSec
, Sec
.sh_size
,
397 orc::ExecutorAddr(Sec
.sh_addr
),
398 Sec
.sh_addralign
, 0);
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);
406 setGraphBlock(SecIndex
, B
);
409 return Error::success();
412 template <typename ELFT
> Error ELFLinkGraphBuilder
<ELFT
>::graphifySymbols() {
413 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
415 // No SYMTAB -- Bail out early.
417 return Error::success();
419 // Get the section content as a Symbols array.
420 auto Symbols
= Obj
.symbols(SymTabSec
);
422 return Symbols
.takeError();
424 // Get the string table for this section.
425 auto StringTab
= Obj
.getStringTableForSymtab(*SymTabSec
, Sections
);
427 return StringTab
.takeError();
430 StringRef SymTabName
;
432 if (auto SymTabNameOrErr
= Obj
.getSectionName(*SymTabSec
, SectionStringTab
))
433 SymTabName
= *SymTabNameOrErr
;
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>";
440 dbgs() << " Adding symbols from symtab section \"" << SymTabName
444 for (ELFSymbolIndex SymIndex
= 0; SymIndex
!= Symbols
->size(); ++SymIndex
) {
445 auto &Sym
= (*Symbols
)[SymIndex
];
447 // Check symbol type.
448 switch (Sym
.getType()) {
451 if (auto Name
= Sym
.getName(*StringTab
))
452 dbgs() << " " << SymIndex
<< ": Skipping STT_FILE symbol \""
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";
465 // Get the symbol name.
466 auto Name
= Sym
.getName(*StringTab
);
468 return Name
.takeError();
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::Strong
, Scope::Default
, false, false);
476 setGraphSymbol(SymIndex
, GSym
);
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
)) {
485 // Map Visibility and Binding to Scope and Linkage:
488 if (auto LSOrErr
= getSymbolLinkageAndScope(Sym
, *Name
))
489 std::tie(L
, S
) = *LSOrErr
;
491 return LSOrErr
.takeError();
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())
499 auto NdxOrErr
= object::getExtendedSymbolTableIndex
<ELFT
>(
500 Sym
, SymIndex
, ShndxTable
->second
);
502 return NdxOrErr
.takeError();
505 if (auto *B
= getGraphBlock(Shndx
)) {
507 dbgs() << " " << SymIndex
508 << ": Creating defined graph symbol for ELF symbol \"" << *Name
512 TargetFlagsType Flags
= makeTargetFlags(Sym
);
513 orc::ExecutorAddrDiff Offset
= getRawOffset(Sym
, Flags
);
515 if (Offset
+ Sym
.st_size
> B
->getSize()) {
517 raw_string_ostream
ErrStream(ErrMsg
);
518 ErrStream
<< "In " << G
->getName() << ", symbol ";
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
));
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
538 ? G
->addAnonymousSymbol(*B
, Offset
, Sym
.st_size
,
540 : G
->addDefinedSymbol(*B
, Offset
, *Name
, Sym
.st_size
, L
,
541 S
, Sym
.getType() == ELF::STT_FUNC
,
544 GSym
.setTargetFlags(Flags
);
545 setGraphSymbol(SymIndex
, GSym
);
547 } else if (Sym
.isUndefined() && Sym
.isExternal()) {
549 dbgs() << " " << SymIndex
550 << ": Creating external graph symbol for ELF symbol \"" << *Name
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
,
560 inconvertibleErrorCode());
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.
572 dbgs() << " " << SymIndex
<< ": Creating null graph symbol\n";
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,
579 Linkage::Strong
, Scope::Local
, false);
580 setGraphSymbol(SymIndex
, GSym
);
583 dbgs() << " " << SymIndex
584 << ": Not creating graph symbol for ELF symbol \"" << *Name
585 << "\" with unrecognized type\n";
590 return Error::success();
593 template <typename ELFT
>
594 template <typename RelocHandlerFunction
>
595 Error ELFLinkGraphBuilder
<ELFT
>::forEachRelaRelocation(
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();
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
);
605 return FixupSection
.takeError();
607 // Target sections have names in valid ELF object files.
608 Expected
<StringRef
> Name
= Obj
.getSectionName(**FixupSection
);
610 return Name
.takeError();
611 LLVM_DEBUG(dbgs() << " " << *Name
<< ":\n");
613 // Consider skipping these relocations.
614 if (!ProcessDebugSections
&& isDwarfSection(*Name
)) {
615 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
616 return Error::success();
618 if (excludeSection(**FixupSection
)) {
619 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
620 return Error::success();
623 // Lookup the link-graph node corresponding to the target section name.
624 auto *BlockToFix
= getGraphBlock(RelSect
.sh_info
);
626 return make_error
<StringError
>(
627 "Refencing a section that wasn't added to the graph: " + *Name
,
628 inconvertibleErrorCode());
630 auto RelEntries
= Obj
.relas(RelSect
);
632 return RelEntries
.takeError();
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
))
639 LLVM_DEBUG(dbgs() << "\n");
640 return Error::success();
643 template <typename ELFT
>
644 template <typename RelocHandlerFunction
>
645 Error ELFLinkGraphBuilder
<ELFT
>::forEachRelRelocation(
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();
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
);
655 return FixupSection
.takeError();
657 // Target sections have names in valid ELF object files.
658 Expected
<StringRef
> Name
= Obj
.getSectionName(**FixupSection
);
660 return Name
.takeError();
661 LLVM_DEBUG(dbgs() << " " << *Name
<< ":\n");
663 // Consider skipping these relocations.
664 if (!ProcessDebugSections
&& isDwarfSection(*Name
)) {
665 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
666 return Error::success();
668 if (excludeSection(**FixupSection
)) {
669 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");
670 return Error::success();
673 // Lookup the link-graph node corresponding to the target section name.
674 auto *BlockToFix
= getGraphBlock(RelSect
.sh_info
);
676 return make_error
<StringError
>(
677 "Refencing a section that wasn't added to the graph: " + *Name
,
678 inconvertibleErrorCode());
680 auto RelEntries
= Obj
.rels(RelSect
);
682 return RelEntries
.takeError();
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
))
689 LLVM_DEBUG(dbgs() << "\n");
690 return Error::success();
693 } // end namespace jitlink
694 } // end namespace llvm
698 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H