700 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// Generic ELF LinkGraph building code.10//11//===----------------------------------------------------------------------===//12 13#ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H14#define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H15 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"21 22#define DEBUG_TYPE "jitlink"23 24namespace llvm {25namespace jitlink {26 27/// Common link-graph building code shared between all ELFFiles.28class ELFLinkGraphBuilderBase {29public:30 ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}31 virtual ~ELFLinkGraphBuilderBase();32 33protected:34 static bool isDwarfSection(StringRef SectionName) {35 return llvm::is_contained(DwarfSectionNames, SectionName);36 }37 38 Section &getCommonSection() {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 common55/// across all architectures.56template <typename ELFT>57class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {58 using ELFFile = object::ELFFile<ELFT>;59 60public:61 ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj,62 std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,63 SubtargetFeatures Features, StringRef FileName,64 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);65 66 /// Debug sections are included in the graph by default. Use67 /// setProcessDebugSections(false) to ignore them if debug info is not68 /// needed.69 ELFLinkGraphBuilder &setProcessDebugSections(bool ProcessDebugSections) {70 this->ProcessDebugSections = ProcessDebugSections;71 return *this;72 }73 74 /// Attempt to construct and return the LinkGraph.75 Expected<std::unique_ptr<LinkGraph>> buildGraph();76 77 /// Call to derived class to handle relocations. These require78 /// architecture specific knowledge to map to JITLink edge kinds.79 virtual Error addRelocations() = 0;80 81protected:82 using ELFSectionIndex = unsigned;83 using ELFSymbolIndex = unsigned;84 85 bool isRelocatable() const {86 return Obj.getHeader().e_type == llvm::ELF::ET_REL;87 }88 89 void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {90 assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");91 GraphBlocks[SecIndex] = B;92 }93 94 Block *getGraphBlock(ELFSectionIndex SecIndex) {95 return GraphBlocks.lookup(SecIndex);96 }97 98 void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {99 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");100 GraphSymbols[SymIndex] = &Sym;101 }102 103 Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) {104 return GraphSymbols.lookup(SymIndex);105 }106 107 Expected<std::pair<Linkage, Scope>>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 121 Error prepare();122 Error graphifySections();123 Error graphifySymbols();124 125 /// Override in derived classes to suppress certain sections in the link126 /// 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) {155 return forEachRelaRelocation(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) {168 return forEachRelRelocation(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;179 StringRef SectionStringTab;180 bool ProcessDebugSections = true;181 182 // Maps ELF section indexes to LinkGraph Blocks.183 // Only SHF_ALLOC sections will have graph blocks.184 DenseMap<ELFSectionIndex, Block *> GraphBlocks;185 DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols;186 DenseMap<const typename ELFFile::Elf_Shdr *,187 ArrayRef<typename ELFFile::Elf_Word>>188 ShndxTables;189};190 191template <typename ELFT>192ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(193 const ELFFile &Obj, std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,194 SubtargetFeatures Features, StringRef FileName,195 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)196 : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(197 FileName.str(), std::move(SSP), std::move(TT), std::move(Features),198 std::move(GetEdgeKindName))),199 Obj(Obj) {200 LLVM_DEBUG(201 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });202}203 204template <typename ELFT>205Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() {206 if (!isRelocatable())207 return make_error<JITLinkError>("Object is not a relocatable ELF file");208 209 if (auto Err = prepare())210 return std::move(Err);211 212 if (auto Err = graphifySections())213 return std::move(Err);214 215 if (auto Err = graphifySymbols())216 return std::move(Err);217 218 if (auto Err = addRelocations())219 return std::move(Err);220 221 return std::move(G);222}223 224template <typename ELFT>225Expected<std::pair<Linkage, Scope>>226ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(227 const typename ELFT::Sym &Sym, StringRef Name) {228 Linkage L = Linkage::Strong;229 Scope S = Scope::Default;230 231 switch (Sym.getBinding()) {232 case ELF::STB_LOCAL:233 S = Scope::Local;234 break;235 case ELF::STB_GLOBAL:236 // Nothing to do here.237 break;238 case ELF::STB_WEAK:239 case ELF::STB_GNU_UNIQUE:240 L = Linkage::Weak;241 break;242 default:243 return make_error<StringError>(244 "Unrecognized symbol binding " +245 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,246 inconvertibleErrorCode());247 }248 249 switch (Sym.getVisibility()) {250 case ELF::STV_DEFAULT:251 case ELF::STV_PROTECTED:252 // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs253 // Orc support.254 // Otherwise nothing to do here.255 break;256 case ELF::STV_HIDDEN:257 // Default scope -> Hidden scope. No effect on local scope.258 if (S == Scope::Default)259 S = Scope::Hidden;260 break;261 case ELF::STV_INTERNAL:262 return make_error<StringError>(263 "Unrecognized symbol visibility " +264 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,265 inconvertibleErrorCode());266 }267 268 return std::make_pair(L, S);269}270 271template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {272 LLVM_DEBUG(dbgs() << " Preparing to build...\n");273 274 // Get the sections array.275 if (auto SectionsOrErr = Obj.sections())276 Sections = *SectionsOrErr;277 else278 return SectionsOrErr.takeError();279 280 // Get the section string table.281 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))282 SectionStringTab = *SectionStringTabOrErr;283 else284 return SectionStringTabOrErr.takeError();285 286 // Get the SHT_SYMTAB section.287 for (auto &Sec : Sections) {288 if (Sec.sh_type == ELF::SHT_SYMTAB) {289 if (!SymTabSec)290 SymTabSec = &Sec;291 else292 return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +293 G->getName());294 }295 296 // Extended table.297 if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {298 uint32_t SymtabNdx = Sec.sh_link;299 if (SymtabNdx >= Sections.size())300 return make_error<JITLinkError>("sh_link is out of bound");301 302 auto ShndxTable = Obj.getSHNDXTable(Sec);303 if (!ShndxTable)304 return ShndxTable.takeError();305 306 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});307 }308 }309 310 return Error::success();311}312 313template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() {314 LLVM_DEBUG(dbgs() << " Creating graph sections...\n");315 316 // For each section...317 for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {318 319 auto &Sec = Sections[SecIndex];320 321 // Start by getting the section name.322 auto Name = Obj.getSectionName(Sec, SectionStringTab);323 if (!Name)324 return Name.takeError();325 if (excludeSection(Sec)) {326 LLVM_DEBUG({327 dbgs() << " " << SecIndex << ": Skipping section \"" << *Name328 << "\" explicitly\n";329 });330 continue;331 }332 333 // Skip null sections.334 if (Sec.sh_type == ELF::SHT_NULL) {335 LLVM_DEBUG({336 dbgs() << " " << SecIndex << ": has type SHT_NULL. Skipping.\n";337 });338 continue;339 }340 341 // If the name indicates that it's a debug section then skip it: We don't342 // support those yet.343 if (!ProcessDebugSections && isDwarfSection(*Name)) {344 LLVM_DEBUG({345 dbgs() << " " << SecIndex << ": \"" << *Name346 << "\" is a debug section: "347 "No graph section will be created.\n";348 });349 continue;350 }351 352 LLVM_DEBUG({353 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name354 << "\"\n";355 });356 357 // Get the section's memory protection flags.358 orc::MemProt Prot = orc::MemProt::Read;359 if (Sec.sh_flags & ELF::SHF_EXECINSTR)360 Prot |= orc::MemProt::Exec;361 if (Sec.sh_flags & ELF::SHF_WRITE)362 Prot |= orc::MemProt::Write;363 364 // Look for existing sections first.365 auto *GraphSec = G->findSectionByName(*Name);366 if (!GraphSec) {367 GraphSec = &G->createSection(*Name, Prot);368 // Non-SHF_ALLOC sections get NoAlloc memory lifetimes.369 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {370 GraphSec->setMemLifetime(orc::MemLifetime::NoAlloc);371 LLVM_DEBUG({372 dbgs() << " " << SecIndex << ": \"" << *Name373 << "\" is not a SHF_ALLOC section. Using NoAlloc lifetime.\n";374 });375 }376 }377 378 if (GraphSec->getMemProt() != Prot) {379 std::string ErrMsg;380 raw_string_ostream(ErrMsg)381 << "In " << G->getName() << ", section " << *Name382 << " is present more than once with different permissions: "383 << GraphSec->getMemProt() << " vs " << Prot;384 return make_error<JITLinkError>(std::move(ErrMsg));385 }386 387 Block *B = nullptr;388 if (Sec.sh_type != ELF::SHT_NOBITS) {389 auto Data = Obj.template getSectionContentsAsArray<char>(Sec);390 if (!Data)391 return Data.takeError();392 393 B = &G->createContentBlock(*GraphSec, *Data,394 orc::ExecutorAddr(Sec.sh_addr),395 Sec.sh_addralign, 0);396 } else397 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,398 orc::ExecutorAddr(Sec.sh_addr),399 Sec.sh_addralign, 0);400 401 if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {402 // Add live symbol to avoid dead-stripping for .ARM.exidx sections403 G->addAnonymousSymbol(*B, orc::ExecutorAddrDiff(),404 orc::ExecutorAddrDiff(), false, true);405 }406 407 setGraphBlock(SecIndex, B);408 }409 410 return Error::success();411}412 413template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() {414 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");415 416 // No SYMTAB -- Bail out early.417 if (!SymTabSec)418 return Error::success();419 420 // Get the section content as a Symbols array.421 auto Symbols = Obj.symbols(SymTabSec);422 if (!Symbols)423 return Symbols.takeError();424 425 // Get the string table for this section.426 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);427 if (!StringTab)428 return StringTab.takeError();429 430 LLVM_DEBUG({431 StringRef SymTabName;432 433 if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))434 SymTabName = *SymTabNameOrErr;435 else {436 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "437 << toString(SymTabNameOrErr.takeError()) << "\n";438 SymTabName = "<SHT_SYMTAB section with invalid name>";439 }440 441 dbgs() << " Adding symbols from symtab section \"" << SymTabName442 << "\"\n";443 });444 445 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {446 auto &Sym = (*Symbols)[SymIndex];447 448 // Check symbol type.449 switch (Sym.getType()) {450 case ELF::STT_FILE:451 LLVM_DEBUG({452 if (auto Name = Sym.getName(*StringTab))453 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""454 << *Name << "\"\n";455 else {456 dbgs() << "Could not get STT_FILE symbol name: "457 << toString(Name.takeError()) << "\n";458 dbgs() << " " << SymIndex459 << ": Skipping STT_FILE symbol with invalid name\n";460 }461 });462 continue;463 break;464 }465 466 // Get the symbol name.467 auto Name = Sym.getName(*StringTab);468 if (!Name)469 return Name.takeError();470 471 // Handle common symbols specially.472 if (Sym.isCommon()) {473 Symbol &GSym = G->addDefinedSymbol(474 G->createZeroFillBlock(getCommonSection(), Sym.st_size,475 orc::ExecutorAddr(), Sym.getValue(), 0),476 0, *Name, Sym.st_size, Linkage::Weak, Scope::Default, false, false);477 setGraphSymbol(SymIndex, GSym);478 continue;479 }480 481 if (Sym.isDefined() &&482 (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||483 Sym.getType() == ELF::STT_OBJECT ||484 Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {485 486 // Map Visibility and Binding to Scope and Linkage:487 Linkage L;488 Scope S;489 if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))490 std::tie(L, S) = *LSOrErr;491 else492 return LSOrErr.takeError();493 494 // Handle extended tables.495 unsigned Shndx = Sym.st_shndx;496 if (Shndx == ELF::SHN_XINDEX) {497 auto ShndxTable = ShndxTables.find(SymTabSec);498 if (ShndxTable == ShndxTables.end())499 continue;500 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(501 Sym, SymIndex, ShndxTable->second);502 if (!NdxOrErr)503 return NdxOrErr.takeError();504 Shndx = *NdxOrErr;505 }506 if (auto *B = getGraphBlock(Shndx)) {507 LLVM_DEBUG({508 dbgs() << " " << SymIndex509 << ": Creating defined graph symbol for ELF symbol \"" << *Name510 << "\"\n";511 });512 513 TargetFlagsType Flags = makeTargetFlags(Sym);514 orc::ExecutorAddrDiff Offset = getRawOffset(Sym, Flags);515 516 if (Offset + Sym.st_size > B->getSize()) {517 std::string ErrMsg;518 raw_string_ostream ErrStream(ErrMsg);519 ErrStream << "In " << G->getName() << ", symbol ";520 if (!Name->empty())521 ErrStream << *Name;522 else523 ErrStream << "<anon>";524 ErrStream << " (" << (B->getAddress() + Offset) << " -- "525 << (B->getAddress() + Offset + Sym.st_size) << ") extends "526 << formatv("{0:x}", Offset + Sym.st_size - B->getSize())527 << " bytes past the end of its containing block ("528 << B->getRange() << ")";529 return make_error<JITLinkError>(std::move(ErrMsg));530 }531 532 // In RISCV, temporary symbols (Used to generate dwarf, eh_frame533 // sections...) will appear in object code's symbol table, and LLVM does534 // not use names on these temporary symbols (RISCV gnu toolchain uses535 // names on these temporary symbols). If the symbol is unnamed, add an536 // anonymous symbol.537 auto &GSym =538 Name->empty()539 ? G->addAnonymousSymbol(*B, Offset, Sym.st_size,540 false, false)541 : G->addDefinedSymbol(*B, Offset, *Name, Sym.st_size, L,542 S, Sym.getType() == ELF::STT_FUNC,543 false);544 545 GSym.setTargetFlags(Flags);546 setGraphSymbol(SymIndex, GSym);547 }548 } else if (Sym.isUndefined() && Sym.isExternal()) {549 LLVM_DEBUG({550 dbgs() << " " << SymIndex551 << ": Creating external graph symbol for ELF symbol \"" << *Name552 << "\"\n";553 });554 555 if (Sym.getBinding() != ELF::STB_GLOBAL &&556 Sym.getBinding() != ELF::STB_WEAK)557 return make_error<StringError>(558 "Invalid symbol binding " +559 Twine(static_cast<int>(Sym.getBinding())) +560 " for external symbol " + *Name,561 inconvertibleErrorCode());562 563 // If L is Linkage::Weak that means this is a weakly referenced symbol.564 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,565 Sym.getBinding() == ELF::STB_WEAK);566 setGraphSymbol(SymIndex, GSym);567 } else if (Sym.isUndefined() && Sym.st_value == 0 && Sym.st_size == 0 &&568 Sym.getType() == ELF::STT_NOTYPE &&569 Sym.getBinding() == ELF::STB_LOCAL && Name->empty()) {570 // Some relocations (e.g., R_RISCV_ALIGN) don't have a target symbol and571 // use this kind of null symbol as a placeholder.572 LLVM_DEBUG({573 dbgs() << " " << SymIndex << ": Creating null graph symbol\n";574 });575 576 auto SymName =577 G->allocateContent("__jitlink_ELF_SYM_UND_" + Twine(SymIndex));578 auto SymNameRef = StringRef(SymName.data(), SymName.size());579 auto &GSym = G->addAbsoluteSymbol(SymNameRef, orc::ExecutorAddr(0), 0,580 Linkage::Strong, Scope::Local, false);581 setGraphSymbol(SymIndex, GSym);582 } else {583 LLVM_DEBUG({584 dbgs() << " " << SymIndex585 << ": Not creating graph symbol for ELF symbol \"" << *Name586 << "\" with unrecognized type\n";587 });588 }589 }590 591 return Error::success();592}593 594template <typename ELFT>595template <typename RelocHandlerFunction>596Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation(597 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {598 // Only look into sections that store relocation entries.599 if (RelSect.sh_type != ELF::SHT_RELA)600 return Error::success();601 602 // sh_info contains the section header index of the target (FixupSection),603 // which is the section to which all relocations in RelSect apply.604 auto FixupSection = Obj.getSection(RelSect.sh_info);605 if (!FixupSection)606 return FixupSection.takeError();607 608 // Target sections have names in valid ELF object files.609 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);610 if (!Name)611 return Name.takeError();612 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");613 614 // Consider skipping these relocations.615 if (!ProcessDebugSections && isDwarfSection(*Name)) {616 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");617 return Error::success();618 }619 if (excludeSection(**FixupSection)) {620 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");621 return Error::success();622 }623 624 // Lookup the link-graph node corresponding to the target section name.625 auto *BlockToFix = getGraphBlock(RelSect.sh_info);626 if (!BlockToFix)627 return make_error<StringError>(628 "Refencing a section that wasn't added to the graph: " + *Name,629 inconvertibleErrorCode());630 631 auto RelEntries = Obj.relas(RelSect);632 if (!RelEntries)633 return RelEntries.takeError();634 635 // Let the callee process relocation entries one by one.636 for (const typename ELFT::Rela &R : *RelEntries)637 if (Error Err = Func(R, **FixupSection, *BlockToFix))638 return Err;639 640 LLVM_DEBUG(dbgs() << "\n");641 return Error::success();642}643 644template <typename ELFT>645template <typename RelocHandlerFunction>646Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation(647 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func) {648 // Only look into sections that store relocation entries.649 if (RelSect.sh_type != ELF::SHT_REL)650 return Error::success();651 652 // sh_info contains the section header index of the target (FixupSection),653 // which is the section to which all relocations in RelSect apply.654 auto FixupSection = Obj.getSection(RelSect.sh_info);655 if (!FixupSection)656 return FixupSection.takeError();657 658 // Target sections have names in valid ELF object files.659 Expected<StringRef> Name = Obj.getSectionName(**FixupSection);660 if (!Name)661 return Name.takeError();662 LLVM_DEBUG(dbgs() << " " << *Name << ":\n");663 664 // Consider skipping these relocations.665 if (!ProcessDebugSections && isDwarfSection(*Name)) {666 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");667 return Error::success();668 }669 if (excludeSection(**FixupSection)) {670 LLVM_DEBUG(dbgs() << " skipped (fixup section excluded explicitly)\n\n");671 return Error::success();672 }673 674 // Lookup the link-graph node corresponding to the target section name.675 auto *BlockToFix = getGraphBlock(RelSect.sh_info);676 if (!BlockToFix)677 return make_error<StringError>(678 "Refencing a section that wasn't added to the graph: " + *Name,679 inconvertibleErrorCode());680 681 auto RelEntries = Obj.rels(RelSect);682 if (!RelEntries)683 return RelEntries.takeError();684 685 // Let the callee process relocation entries one by one.686 for (const typename ELFT::Rel &R : *RelEntries)687 if (Error Err = Func(R, **FixupSection, *BlockToFix))688 return Err;689 690 LLVM_DEBUG(dbgs() << "\n");691 return Error::success();692}693 694} // end namespace jitlink695} // end namespace llvm696 697#undef DEBUG_TYPE698 699#endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H700