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 /// Ling-graph 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 StringRef FileName, 63 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName); 64 65 /// Attempt to construct and return the LinkGraph. 66 Expected<std::unique_ptr<LinkGraph>> buildGraph(); 67 68 /// Call to derived class to handle relocations. These require 69 /// architecture specific knowledge to map to JITLink edge kinds. 70 virtual Error addRelocations() = 0; 71 72 protected: 73 using ELFSectionIndex = unsigned; 74 using ELFSymbolIndex = unsigned; 75 76 bool isRelocatable() const { 77 return Obj.getHeader().e_type == llvm::ELF::ET_REL; 78 } 79 80 void setGraphBlock(ELFSectionIndex SecIndex, Block *B) { 81 assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index"); 82 GraphBlocks[SecIndex] = B; 83 } 84 85 Block *getGraphBlock(ELFSectionIndex SecIndex) { 86 auto I = GraphBlocks.find(SecIndex); 87 if (I == GraphBlocks.end()) 88 return nullptr; 89 return I->second; 90 } 91 92 void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) { 93 assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index"); 94 GraphSymbols[SymIndex] = &Sym; 95 } 96 97 Symbol *getGraphSymbol(ELFSymbolIndex SymIndex) { 98 auto I = GraphSymbols.find(SymIndex); 99 if (I == GraphSymbols.end()) 100 return nullptr; 101 return I->second; 102 } 103 104 Expected<std::pair<Linkage, Scope>> 105 getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name); 106 107 Error prepare(); 108 Error graphifySections(); 109 Error graphifySymbols(); 110 111 /// Traverse all matching ELFT::Rela relocation records in the given section. 112 /// The handler function Func should be callable with this signature: 113 /// Error(const typename ELFT::Rela &, 114 /// const typename ELFT::Shdr &, Section &) 115 /// 116 template <typename RelocHandlerMethod> 117 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, 118 RelocHandlerMethod &&Func, 119 bool ProcessDebugSections = false); 120 121 /// Traverse all matching ELFT::Rel relocation records in the given section. 122 /// The handler function Func should be callable with this signature: 123 /// Error(const typename ELFT::Rel &, 124 /// const typename ELFT::Shdr &, Section &) 125 /// 126 template <typename RelocHandlerMethod> 127 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, 128 RelocHandlerMethod &&Func, 129 bool ProcessDebugSections = false); 130 131 /// Traverse all matching rela relocation records in the given section. 132 /// Convenience wrapper to allow passing a member function for the handler. 133 /// 134 template <typename ClassT, typename RelocHandlerMethod> 135 Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, 136 ClassT *Instance, RelocHandlerMethod &&Method, 137 bool ProcessDebugSections = false) { 138 return forEachRelaRelocation( 139 RelSect, 140 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 141 return (Instance->*Method)(Rel, Target, GS); 142 }, 143 ProcessDebugSections); 144 } 145 146 /// Traverse all matching rel relocation records in the given section. 147 /// Convenience wrapper to allow passing a member function for the handler. 148 /// 149 template <typename ClassT, typename RelocHandlerMethod> 150 Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, 151 ClassT *Instance, RelocHandlerMethod &&Method, 152 bool ProcessDebugSections = false) { 153 return forEachRelRelocation( 154 RelSect, 155 [Instance, Method](const auto &Rel, const auto &Target, auto &GS) { 156 return (Instance->*Method)(Rel, Target, GS); 157 }, 158 ProcessDebugSections); 159 } 160 161 const ELFFile &Obj; 162 163 typename ELFFile::Elf_Shdr_Range Sections; 164 const typename ELFFile::Elf_Shdr *SymTabSec = nullptr; 165 StringRef SectionStringTab; 166 167 // Maps ELF section indexes to LinkGraph Blocks. 168 // Only SHF_ALLOC sections will have graph blocks. 169 DenseMap<ELFSectionIndex, Block *> GraphBlocks; 170 DenseMap<ELFSymbolIndex, Symbol *> GraphSymbols; 171 DenseMap<const typename ELFFile::Elf_Shdr *, 172 ArrayRef<typename ELFFile::Elf_Word>> 173 ShndxTables; 174 }; 175 176 template <typename ELFT> 177 ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder( 178 const ELFFile &Obj, Triple TT, StringRef FileName, 179 LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) 180 : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>( 181 FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4, 182 support::endianness(ELFT::TargetEndianness), 183 std::move(GetEdgeKindName))), 184 Obj(Obj) { 185 LLVM_DEBUG( 186 { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; }); 187 } 188 189 template <typename ELFT> 190 Expected<std::unique_ptr<LinkGraph>> ELFLinkGraphBuilder<ELFT>::buildGraph() { 191 if (!isRelocatable()) 192 return make_error<JITLinkError>("Object is not a relocatable ELF file"); 193 194 if (auto Err = prepare()) 195 return std::move(Err); 196 197 if (auto Err = graphifySections()) 198 return std::move(Err); 199 200 if (auto Err = graphifySymbols()) 201 return std::move(Err); 202 203 if (auto Err = addRelocations()) 204 return std::move(Err); 205 206 return std::move(G); 207 } 208 209 template <typename ELFT> 210 Expected<std::pair<Linkage, Scope>> 211 ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope( 212 const typename ELFT::Sym &Sym, StringRef Name) { 213 Linkage L = Linkage::Strong; 214 Scope S = Scope::Default; 215 216 switch (Sym.getBinding()) { 217 case ELF::STB_LOCAL: 218 S = Scope::Local; 219 break; 220 case ELF::STB_GLOBAL: 221 // Nothing to do here. 222 break; 223 case ELF::STB_WEAK: 224 case ELF::STB_GNU_UNIQUE: 225 L = Linkage::Weak; 226 break; 227 default: 228 return make_error<StringError>( 229 "Unrecognized symbol binding " + 230 Twine(static_cast<int>(Sym.getBinding())) + " for " + Name, 231 inconvertibleErrorCode()); 232 } 233 234 switch (Sym.getVisibility()) { 235 case ELF::STV_DEFAULT: 236 case ELF::STV_PROTECTED: 237 // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs 238 // Orc support. 239 // Otherwise nothing to do here. 240 break; 241 case ELF::STV_HIDDEN: 242 // Default scope -> Hidden scope. No effect on local scope. 243 if (S == Scope::Default) 244 S = Scope::Hidden; 245 break; 246 case ELF::STV_INTERNAL: 247 return make_error<StringError>( 248 "Unrecognized symbol visibility " + 249 Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name, 250 inconvertibleErrorCode()); 251 } 252 253 return std::make_pair(L, S); 254 } 255 256 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() { 257 LLVM_DEBUG(dbgs() << " Preparing to build...\n"); 258 259 // Get the sections array. 260 if (auto SectionsOrErr = Obj.sections()) 261 Sections = *SectionsOrErr; 262 else 263 return SectionsOrErr.takeError(); 264 265 // Get the section string table. 266 if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections)) 267 SectionStringTab = *SectionStringTabOrErr; 268 else 269 return SectionStringTabOrErr.takeError(); 270 271 // Get the SHT_SYMTAB section. 272 for (auto &Sec : Sections) { 273 if (Sec.sh_type == ELF::SHT_SYMTAB) { 274 if (!SymTabSec) 275 SymTabSec = &Sec; 276 else 277 return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " + 278 G->getName()); 279 } 280 281 // Extended table. 282 if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { 283 uint32_t SymtabNdx = Sec.sh_link; 284 if (SymtabNdx >= Sections.size()) 285 return make_error<JITLinkError>("sh_link is out of bound"); 286 287 auto ShndxTable = Obj.getSHNDXTable(Sec); 288 if (!ShndxTable) 289 return ShndxTable.takeError(); 290 291 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable}); 292 } 293 } 294 295 return Error::success(); 296 } 297 298 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySections() { 299 LLVM_DEBUG(dbgs() << " Creating graph sections...\n"); 300 301 // For each section... 302 for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) { 303 304 auto &Sec = Sections[SecIndex]; 305 306 // Start by getting the section name. 307 auto Name = Obj.getSectionName(Sec, SectionStringTab); 308 if (!Name) 309 return Name.takeError(); 310 311 // If the name indicates that it's a debug section then skip it: We don't 312 // support those yet. 313 if (isDwarfSection(*Name)) { 314 LLVM_DEBUG({ 315 dbgs() << " " << SecIndex << ": \"" << *Name 316 << "\" is a debug section: " 317 "No graph section will be created.\n"; 318 }); 319 continue; 320 } 321 322 // Skip non-SHF_ALLOC sections 323 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) { 324 LLVM_DEBUG({ 325 dbgs() << " " << SecIndex << ": \"" << *Name 326 << "\" is not an SHF_ALLOC section: " 327 "No graph section will be created.\n"; 328 }); 329 continue; 330 } 331 332 LLVM_DEBUG({ 333 dbgs() << " " << SecIndex << ": Creating section for \"" << *Name 334 << "\"\n"; 335 }); 336 337 // Get the section's memory protection flags. 338 orc::MemProt Prot; 339 if (Sec.sh_flags & ELF::SHF_EXECINSTR) 340 Prot = orc::MemProt::Read | orc::MemProt::Exec; 341 else 342 Prot = orc::MemProt::Read | orc::MemProt::Write; 343 344 // Look for existing sections first. 345 auto *GraphSec = G->findSectionByName(*Name); 346 if (!GraphSec) 347 GraphSec = &G->createSection(*Name, Prot); 348 assert(GraphSec->getMemProt() == Prot && "MemProt should match"); 349 350 Block *B = nullptr; 351 if (Sec.sh_type != ELF::SHT_NOBITS) { 352 auto Data = Obj.template getSectionContentsAsArray<char>(Sec); 353 if (!Data) 354 return Data.takeError(); 355 356 B = &G->createContentBlock(*GraphSec, *Data, 357 orc::ExecutorAddr(Sec.sh_addr), 358 Sec.sh_addralign, 0); 359 } else 360 B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size, 361 orc::ExecutorAddr(Sec.sh_addr), 362 Sec.sh_addralign, 0); 363 364 setGraphBlock(SecIndex, B); 365 } 366 367 return Error::success(); 368 } 369 370 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::graphifySymbols() { 371 LLVM_DEBUG(dbgs() << " Creating graph symbols...\n"); 372 373 // No SYMTAB -- Bail out early. 374 if (!SymTabSec) 375 return Error::success(); 376 377 // Get the section content as a Symbols array. 378 auto Symbols = Obj.symbols(SymTabSec); 379 if (!Symbols) 380 return Symbols.takeError(); 381 382 // Get the string table for this section. 383 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections); 384 if (!StringTab) 385 return StringTab.takeError(); 386 387 LLVM_DEBUG({ 388 StringRef SymTabName; 389 390 if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab)) 391 SymTabName = *SymTabNameOrErr; 392 else { 393 dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: " 394 << toString(SymTabNameOrErr.takeError()) << "\n"; 395 SymTabName = "<SHT_SYMTAB section with invalid name>"; 396 } 397 398 dbgs() << " Adding symbols from symtab section \"" << SymTabName 399 << "\"\n"; 400 }); 401 402 for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) { 403 auto &Sym = (*Symbols)[SymIndex]; 404 405 // Check symbol type. 406 switch (Sym.getType()) { 407 case ELF::STT_FILE: 408 LLVM_DEBUG({ 409 if (auto Name = Sym.getName(*StringTab)) 410 dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \"" 411 << *Name << "\"\n"; 412 else { 413 dbgs() << "Could not get STT_FILE symbol name: " 414 << toString(Name.takeError()) << "\n"; 415 dbgs() << " " << SymIndex 416 << ": Skipping STT_FILE symbol with invalid name\n"; 417 } 418 }); 419 continue; 420 break; 421 } 422 423 // Get the symbol name. 424 auto Name = Sym.getName(*StringTab); 425 if (!Name) 426 return Name.takeError(); 427 428 // Handle common symbols specially. 429 if (Sym.isCommon()) { 430 Symbol &GSym = G->addDefinedSymbol( 431 G->createZeroFillBlock(getCommonSection(), Sym.st_size, 432 orc::ExecutorAddr(), Sym.getValue(), 0), 433 0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false); 434 setGraphSymbol(SymIndex, GSym); 435 continue; 436 } 437 438 if (Sym.isDefined() && 439 (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC || 440 Sym.getType() == ELF::STT_OBJECT || 441 Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) { 442 443 // Map Visibility and Binding to Scope and Linkage: 444 Linkage L; 445 Scope S; 446 if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name)) 447 std::tie(L, S) = *LSOrErr; 448 else 449 return LSOrErr.takeError(); 450 451 // Handle extended tables. 452 unsigned Shndx = Sym.st_shndx; 453 if (Shndx == ELF::SHN_XINDEX) { 454 auto ShndxTable = ShndxTables.find(SymTabSec); 455 if (ShndxTable == ShndxTables.end()) 456 continue; 457 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>( 458 Sym, SymIndex, ShndxTable->second); 459 if (!NdxOrErr) 460 return NdxOrErr.takeError(); 461 Shndx = *NdxOrErr; 462 } 463 if (auto *B = getGraphBlock(Shndx)) { 464 LLVM_DEBUG({ 465 dbgs() << " " << SymIndex 466 << ": Creating defined graph symbol for ELF symbol \"" << *Name 467 << "\"\n"; 468 }); 469 470 // In RISCV, temporary symbols (Used to generate dwarf, eh_frame 471 // sections...) will appear in object code's symbol table, and LLVM does 472 // not use names on these temporary symbols (RISCV gnu toolchain uses 473 // names on these temporary symbols). If the symbol is unnamed, add an 474 // anonymous symbol. 475 auto &GSym = 476 Name->empty() 477 ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size, 478 false, false) 479 : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L, 480 S, Sym.getType() == ELF::STT_FUNC, false); 481 setGraphSymbol(SymIndex, GSym); 482 } 483 } else if (Sym.isUndefined() && Sym.isExternal()) { 484 LLVM_DEBUG({ 485 dbgs() << " " << SymIndex 486 << ": Creating external graph symbol for ELF symbol \"" << *Name 487 << "\"\n"; 488 }); 489 490 if (Sym.getBinding() != ELF::STB_GLOBAL && 491 Sym.getBinding() != ELF::STB_WEAK) 492 return make_error<StringError>( 493 "Invalid symbol binding " + 494 Twine(static_cast<int>(Sym.getBinding())) + 495 " for external symbol " + *Name, 496 inconvertibleErrorCode()); 497 498 // If L is Linkage::Weak that means this is a weakly referenced symbol. 499 auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, 500 Sym.getBinding() == ELF::STB_WEAK); 501 setGraphSymbol(SymIndex, GSym); 502 } else { 503 LLVM_DEBUG({ 504 dbgs() << " " << SymIndex 505 << ": Not creating graph symbol for ELF symbol \"" << *Name 506 << "\" with unrecognized type\n"; 507 }); 508 } 509 } 510 511 return Error::success(); 512 } 513 514 template <typename ELFT> 515 template <typename RelocHandlerFunction> 516 Error ELFLinkGraphBuilder<ELFT>::forEachRelaRelocation( 517 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func, 518 bool ProcessDebugSections) { 519 // Only look into sections that store relocation entries. 520 if (RelSect.sh_type != ELF::SHT_RELA) 521 return Error::success(); 522 523 // sh_info contains the section header index of the target (FixupSection), 524 // which is the section to which all relocations in RelSect apply. 525 auto FixupSection = Obj.getSection(RelSect.sh_info); 526 if (!FixupSection) 527 return FixupSection.takeError(); 528 529 // Target sections have names in valid ELF object files. 530 Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 531 if (!Name) 532 return Name.takeError(); 533 LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 534 535 // Consider skipping these relocations. 536 if (!ProcessDebugSections && isDwarfSection(*Name)) { 537 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 538 return Error::success(); 539 } 540 541 // Lookup the link-graph node corresponding to the target section name. 542 auto *BlockToFix = getGraphBlock(RelSect.sh_info); 543 if (!BlockToFix) 544 return make_error<StringError>( 545 "Refencing a section that wasn't added to the graph: " + *Name, 546 inconvertibleErrorCode()); 547 548 auto RelEntries = Obj.relas(RelSect); 549 if (!RelEntries) 550 return RelEntries.takeError(); 551 552 // Let the callee process relocation entries one by one. 553 for (const typename ELFT::Rela &R : *RelEntries) 554 if (Error Err = Func(R, **FixupSection, *BlockToFix)) 555 return Err; 556 557 LLVM_DEBUG(dbgs() << "\n"); 558 return Error::success(); 559 } 560 561 template <typename ELFT> 562 template <typename RelocHandlerFunction> 563 Error ELFLinkGraphBuilder<ELFT>::forEachRelRelocation( 564 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func, 565 bool ProcessDebugSections) { 566 // Only look into sections that store relocation entries. 567 if (RelSect.sh_type != ELF::SHT_REL) 568 return Error::success(); 569 570 // sh_info contains the section header index of the target (FixupSection), 571 // which is the section to which all relocations in RelSect apply. 572 auto FixupSection = Obj.getSection(RelSect.sh_info); 573 if (!FixupSection) 574 return FixupSection.takeError(); 575 576 // Target sections have names in valid ELF object files. 577 Expected<StringRef> Name = Obj.getSectionName(**FixupSection); 578 if (!Name) 579 return Name.takeError(); 580 LLVM_DEBUG(dbgs() << " " << *Name << ":\n"); 581 582 // Consider skipping these relocations. 583 if (!ProcessDebugSections && isDwarfSection(*Name)) { 584 LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n"); 585 return Error::success(); 586 } 587 588 // Lookup the link-graph node corresponding to the target section name. 589 auto *BlockToFix = getGraphBlock(RelSect.sh_info); 590 if (!BlockToFix) 591 return make_error<StringError>( 592 "Refencing a section that wasn't added to the graph: " + *Name, 593 inconvertibleErrorCode()); 594 595 auto RelEntries = Obj.rels(RelSect); 596 if (!RelEntries) 597 return RelEntries.takeError(); 598 599 // Let the callee process relocation entries one by one. 600 for (const typename ELFT::Rel &R : *RelEntries) 601 if (Error Err = Func(R, **FixupSection, *BlockToFix)) 602 return Err; 603 604 LLVM_DEBUG(dbgs() << "\n"); 605 return Error::success(); 606 } 607 608 } // end namespace jitlink 609 } // end namespace llvm 610 611 #undef DEBUG_TYPE 612 613 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H 614