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 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 24 namespace llvm { 25 namespace jitlink { 26 27 /// Common link-graph building code shared between all ELFFiles. 28 class ELFLinkGraphBuilderBase { 29 public: 30 ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {} 31 virtual ~ELFLinkGraphBuilderBase(); 32 33 protected: 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 47 private: 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. 56 template <typename ELFT> 57 class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase { 58 using ELFFile = object::ELFFile<ELFT>; 59 60 public: 61 ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT, 62 SubtargetFeatures Features, StringRef FileName, 63 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName); 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. 68 ELFLinkGraphBuilder &setProcessDebugSections(bool ProcessDebugSections) { 69 this->ProcessDebugSections = ProcessDebugSections; 70 return *this; 71 } 72 73 /// Attempt to construct and return the LinkGraph. 74 Expected<std::unique_ptr<LinkGraph>> buildGraph(); 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 80 protected: 81 using ELFSectionIndex = unsigned; 82 using ELFSymbolIndex = unsigned; 83 84 bool isRelocatable() const { 85 return Obj.getHeader().e_type == llvm::ELF::ET_REL; 86 } 87 88 void setGraphBlock(ELFSectionIndex SecIndex, Block *B) { 89 assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index"); 90 GraphBlocks[SecIndex] = B; 91 } 92 93 Block *getGraphBlock(ELFSectionIndex SecIndex) { 94 return GraphBlocks.lookup(SecIndex); 95 } 96 97 void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) { 98 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index"); 99 GraphSymbols[SymIndex] = &Sym; 100 } 101 102 Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) { 103 return GraphSymbols.lookup(SymIndex); 104 } 105 106 Expected<std::pair<Linkage, Scope>> 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 120 Error prepare(); 121 Error graphifySections(); 122 Error graphifySymbols(); 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) { 154 return forEachRelaRelocation( 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) { 167 return forEachRelRelocation( 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; 178 StringRef SectionStringTab; 179 bool ProcessDebugSections = true; 180 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>> 187 ShndxTables; 188 }; 189 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))), 198 Obj(Obj) { 199 LLVM_DEBUG( 200 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; }); 201 } 202 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"); 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 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; 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: 238 case ELF::STB_GNU_UNIQUE: 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, 245 inconvertibleErrorCode()); 246 } 247 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 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; 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()); 265 } 266 267 return std::make_pair(L, S); 268 } 269 270 template <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 312 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() { 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. 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; 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 412 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() { 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::Strong, 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, 560 inconvertibleErrorCode()); 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, 579 Linkage::Strong, Scope::Local, false); 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 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(); 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, 628 inconvertibleErrorCode()); 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 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(); 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, 678 inconvertibleErrorCode()); 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 699