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