1 //===- llvm-jitlink.cpp -- Command line interface/tester for llvm-jitlink -===// 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 // This utility provides a simple command line interface to the llvm jitlink 10 // library, which makes relocatable object files executable in memory. Its 11 // primary function is as a testing utility for the jitlink library. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm-jitlink.h" 16 17 #include "llvm/BinaryFormat/Magic.h" 18 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 19 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 20 #include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 24 #include "llvm/MC/MCInstPrinter.h" 25 #include "llvm/MC/MCInstrInfo.h" 26 #include "llvm/MC/MCRegisterInfo.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/MC/MCTargetOptions.h" 29 #include "llvm/Object/COFF.h" 30 #include "llvm/Object/MachO.h" 31 #include "llvm/Object/ObjectFile.h" 32 #include "llvm/Support/CommandLine.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/InitLLVM.h" 35 #include "llvm/Support/MemoryBuffer.h" 36 #include "llvm/Support/Process.h" 37 #include "llvm/Support/TargetRegistry.h" 38 #include "llvm/Support/TargetSelect.h" 39 #include "llvm/Support/Timer.h" 40 41 #include <list> 42 #include <string> 43 44 #define DEBUG_TYPE "llvm_jitlink" 45 46 using namespace llvm; 47 using namespace llvm::jitlink; 48 using namespace llvm::orc; 49 50 static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore, 51 cl::desc("input files")); 52 53 static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"), 54 cl::init(false)); 55 56 static cl::list<std::string> 57 CheckFiles("check", cl::desc("File containing verifier checks"), 58 cl::ZeroOrMore); 59 60 static cl::opt<std::string> 61 CheckName("check-name", cl::desc("Name of checks to match against"), 62 cl::init("jitlink-check")); 63 64 static cl::opt<std::string> 65 EntryPointName("entry", cl::desc("Symbol to call as main entry point"), 66 cl::init("")); 67 68 static cl::list<std::string> JITLinkDylibs( 69 "jld", cl::desc("Specifies the JITDylib to be used for any subsequent " 70 "input file arguments")); 71 72 static cl::list<std::string> 73 Dylibs("dlopen", cl::desc("Dynamic libraries to load before linking"), 74 cl::ZeroOrMore); 75 76 static cl::list<std::string> InputArgv("args", cl::Positional, 77 cl::desc("<program arguments>..."), 78 cl::ZeroOrMore, cl::PositionalEatsArgs); 79 80 static cl::opt<bool> 81 NoProcessSymbols("no-process-syms", 82 cl::desc("Do not resolve to llvm-jitlink process symbols"), 83 cl::init(false)); 84 85 static cl::list<std::string> AbsoluteDefs( 86 "define-abs", 87 cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"), 88 cl::ZeroOrMore); 89 90 static cl::list<std::string> TestHarnesses("harness", cl::Positional, 91 cl::desc("Test harness files"), 92 cl::ZeroOrMore, 93 cl::PositionalEatsArgs); 94 95 static cl::opt<bool> ShowInitialExecutionSessionState( 96 "show-init-es", 97 cl::desc("Print ExecutionSession state before resolving entry point"), 98 cl::init(false)); 99 100 static cl::opt<bool> ShowAddrs( 101 "show-addrs", 102 cl::desc("Print registered symbol, section, got and stub addresses"), 103 cl::init(false)); 104 105 static cl::opt<bool> ShowLinkGraph( 106 "show-graph", 107 cl::desc("Print the link graph after fixups have been applied"), 108 cl::init(false)); 109 110 static cl::opt<bool> ShowSizes( 111 "show-sizes", 112 cl::desc("Show sizes pre- and post-dead stripping, and allocations"), 113 cl::init(false)); 114 115 static cl::opt<bool> ShowTimes("show-times", 116 cl::desc("Show times for llvm-jitlink phases"), 117 cl::init(false)); 118 119 static cl::opt<std::string> SlabAllocateSizeString( 120 "slab-allocate", 121 cl::desc("Allocate from a slab of the given size " 122 "(allowable suffixes: Kb, Mb, Gb. default = " 123 "Kb)"), 124 cl::init("")); 125 126 static cl::opt<uint64_t> SlabAddress( 127 "slab-address", 128 cl::desc("Set slab target address (requires -slab-allocate and -noexec)"), 129 cl::init(~0ULL)); 130 131 static cl::opt<bool> ShowRelocatedSectionContents( 132 "show-relocated-section-contents", 133 cl::desc("show section contents after fixups have been applied"), 134 cl::init(false)); 135 136 static cl::opt<bool> PhonyExternals( 137 "phony-externals", 138 cl::desc("resolve all otherwise unresolved externals to null"), 139 cl::init(false)); 140 141 ExitOnError ExitOnErr; 142 143 namespace llvm { 144 145 static raw_ostream & 146 operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) { 147 return OS << "target addr = " 148 << format("0x%016" PRIx64, MRI.getTargetAddress()) 149 << ", content: " << (const void *)MRI.getContent().data() << " -- " 150 << (const void *)(MRI.getContent().data() + MRI.getContent().size()) 151 << " (" << MRI.getContent().size() << " bytes)"; 152 } 153 154 static raw_ostream & 155 operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) { 156 OS << "Symbols:\n"; 157 for (auto &SKV : SIM) 158 OS << " \"" << SKV.first() << "\" " << SKV.second << "\n"; 159 return OS; 160 } 161 162 static raw_ostream & 163 operator<<(raw_ostream &OS, const Session::FileInfo &FI) { 164 for (auto &SIKV : FI.SectionInfos) 165 OS << " Section \"" << SIKV.first() << "\": " << SIKV.second << "\n"; 166 for (auto &GOTKV : FI.GOTEntryInfos) 167 OS << " GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n"; 168 for (auto &StubKV : FI.StubInfos) 169 OS << " Stub \"" << StubKV.first() << "\": " << StubKV.second << "\n"; 170 return OS; 171 } 172 173 static raw_ostream & 174 operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) { 175 for (auto &FIKV : FIM) 176 OS << "File \"" << FIKV.first() << "\":\n" << FIKV.second; 177 return OS; 178 } 179 180 static Error applyHarnessPromotions(Session &S, LinkGraph &G) { 181 182 // If this graph is part of the test harness there's nothing to do. 183 if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName())) 184 return Error::success(); 185 186 LLVM_DEBUG(dbgs() << "Appling promotions to graph " << G.getName() << "\n"); 187 188 // If this graph is part of the test then promote any symbols referenced by 189 // the harness to default scope, remove all symbols that clash with harness 190 // definitions. 191 std::vector<Symbol *> DefinitionsToRemove; 192 for (auto *Sym : G.defined_symbols()) { 193 194 if (!Sym->hasName()) 195 continue; 196 197 if (Sym->getLinkage() == Linkage::Weak) { 198 if (!S.CanonicalWeakDefs.count(Sym->getName()) || 199 S.CanonicalWeakDefs[Sym->getName()] != G.getName()) { 200 LLVM_DEBUG({ 201 dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n"; 202 }); 203 DefinitionsToRemove.push_back(Sym); 204 } else { 205 LLVM_DEBUG({ 206 dbgs() << " Making weak symbol " << Sym->getName() << " strong\n"; 207 }); 208 if (S.HarnessExternals.count(Sym->getName())) 209 Sym->setScope(Scope::Default); 210 else 211 Sym->setScope(Scope::Hidden); 212 Sym->setLinkage(Linkage::Strong); 213 } 214 } else if (S.HarnessExternals.count(Sym->getName())) { 215 LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n"); 216 Sym->setScope(Scope::Default); 217 Sym->setLive(true); 218 continue; 219 } else if (S.HarnessDefinitions.count(Sym->getName())) { 220 LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n"); 221 DefinitionsToRemove.push_back(Sym); 222 } 223 } 224 225 for (auto *Sym : DefinitionsToRemove) 226 G.makeExternal(*Sym); 227 228 return Error::success(); 229 } 230 231 static uint64_t computeTotalBlockSizes(LinkGraph &G) { 232 uint64_t TotalSize = 0; 233 for (auto *B : G.blocks()) 234 TotalSize += B->getSize(); 235 return TotalSize; 236 } 237 238 static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) { 239 constexpr JITTargetAddress DumpWidth = 16; 240 static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two"); 241 242 // Put sections in address order. 243 std::vector<Section *> Sections; 244 for (auto &S : G.sections()) 245 Sections.push_back(&S); 246 247 std::sort(Sections.begin(), Sections.end(), 248 [](const Section *LHS, const Section *RHS) { 249 if (llvm::empty(LHS->symbols()) && llvm::empty(RHS->symbols())) 250 return false; 251 if (llvm::empty(LHS->symbols())) 252 return false; 253 if (llvm::empty(RHS->symbols())) 254 return true; 255 SectionRange LHSRange(*LHS); 256 SectionRange RHSRange(*RHS); 257 return LHSRange.getStart() < RHSRange.getStart(); 258 }); 259 260 for (auto *S : Sections) { 261 OS << S->getName() << " content:"; 262 if (llvm::empty(S->symbols())) { 263 OS << "\n section empty\n"; 264 continue; 265 } 266 267 // Sort symbols into order, then render. 268 std::vector<Symbol *> Syms(S->symbols().begin(), S->symbols().end()); 269 llvm::sort(Syms, [](const Symbol *LHS, const Symbol *RHS) { 270 return LHS->getAddress() < RHS->getAddress(); 271 }); 272 273 JITTargetAddress NextAddr = Syms.front()->getAddress() & ~(DumpWidth - 1); 274 for (auto *Sym : Syms) { 275 bool IsZeroFill = Sym->getBlock().isZeroFill(); 276 JITTargetAddress SymStart = Sym->getAddress(); 277 JITTargetAddress SymSize = Sym->getSize(); 278 JITTargetAddress SymEnd = SymStart + SymSize; 279 const uint8_t *SymData = 280 IsZeroFill ? nullptr : Sym->getSymbolContent().bytes_begin(); 281 282 // Pad any space before the symbol starts. 283 while (NextAddr != SymStart) { 284 if (NextAddr % DumpWidth == 0) 285 OS << formatv("\n{0:x16}:", NextAddr); 286 OS << " "; 287 ++NextAddr; 288 } 289 290 // Render the symbol content. 291 while (NextAddr != SymEnd) { 292 if (NextAddr % DumpWidth == 0) 293 OS << formatv("\n{0:x16}:", NextAddr); 294 if (IsZeroFill) 295 OS << " 00"; 296 else 297 OS << formatv(" {0:x-2}", SymData[NextAddr - SymStart]); 298 ++NextAddr; 299 } 300 } 301 OS << "\n"; 302 } 303 } 304 305 class JITLinkSlabAllocator final : public JITLinkMemoryManager { 306 public: 307 static Expected<std::unique_ptr<JITLinkSlabAllocator>> 308 Create(uint64_t SlabSize) { 309 Error Err = Error::success(); 310 std::unique_ptr<JITLinkSlabAllocator> Allocator( 311 new JITLinkSlabAllocator(SlabSize, Err)); 312 if (Err) 313 return std::move(Err); 314 return std::move(Allocator); 315 } 316 317 Expected<std::unique_ptr<JITLinkMemoryManager::Allocation>> 318 allocate(const SegmentsRequestMap &Request) override { 319 320 using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>; 321 322 // Local class for allocation. 323 class IPMMAlloc : public Allocation { 324 public: 325 IPMMAlloc(JITLinkSlabAllocator &Parent, AllocationMap SegBlocks) 326 : Parent(Parent), SegBlocks(std::move(SegBlocks)) {} 327 MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override { 328 assert(SegBlocks.count(Seg) && "No allocation for segment"); 329 return {static_cast<char *>(SegBlocks[Seg].base()), 330 SegBlocks[Seg].allocatedSize()}; 331 } 332 JITTargetAddress getTargetMemory(ProtectionFlags Seg) override { 333 assert(SegBlocks.count(Seg) && "No allocation for segment"); 334 return pointerToJITTargetAddress(SegBlocks[Seg].base()) + 335 Parent.TargetDelta; 336 } 337 void finalizeAsync(FinalizeContinuation OnFinalize) override { 338 OnFinalize(applyProtections()); 339 } 340 Error deallocate() override { 341 for (auto &KV : SegBlocks) 342 if (auto EC = sys::Memory::releaseMappedMemory(KV.second)) 343 return errorCodeToError(EC); 344 return Error::success(); 345 } 346 347 private: 348 Error applyProtections() { 349 for (auto &KV : SegBlocks) { 350 auto &Prot = KV.first; 351 auto &Block = KV.second; 352 if (auto EC = sys::Memory::protectMappedMemory(Block, Prot)) 353 return errorCodeToError(EC); 354 if (Prot & sys::Memory::MF_EXEC) 355 sys::Memory::InvalidateInstructionCache(Block.base(), 356 Block.allocatedSize()); 357 } 358 return Error::success(); 359 } 360 361 JITLinkSlabAllocator &Parent; 362 AllocationMap SegBlocks; 363 }; 364 365 AllocationMap Blocks; 366 367 for (auto &KV : Request) { 368 auto &Seg = KV.second; 369 370 if (Seg.getAlignment() > PageSize) 371 return make_error<StringError>("Cannot request higher than page " 372 "alignment", 373 inconvertibleErrorCode()); 374 375 if (PageSize % Seg.getAlignment() != 0) 376 return make_error<StringError>("Page size is not a multiple of " 377 "alignment", 378 inconvertibleErrorCode()); 379 380 uint64_t ZeroFillStart = Seg.getContentSize(); 381 uint64_t SegmentSize = ZeroFillStart + Seg.getZeroFillSize(); 382 383 // Round segment size up to page boundary. 384 SegmentSize = (SegmentSize + PageSize - 1) & ~(PageSize - 1); 385 386 // Take segment bytes from the front of the slab. 387 void *SlabBase = SlabRemaining.base(); 388 uint64_t SlabRemainingSize = SlabRemaining.allocatedSize(); 389 390 if (SegmentSize > SlabRemainingSize) 391 return make_error<StringError>("Slab allocator out of memory", 392 inconvertibleErrorCode()); 393 394 sys::MemoryBlock SegMem(SlabBase, SegmentSize); 395 SlabRemaining = 396 sys::MemoryBlock(reinterpret_cast<char *>(SlabBase) + SegmentSize, 397 SlabRemainingSize - SegmentSize); 398 399 // Zero out the zero-fill memory. 400 memset(static_cast<char *>(SegMem.base()) + ZeroFillStart, 0, 401 Seg.getZeroFillSize()); 402 403 // Record the block for this segment. 404 Blocks[KV.first] = std::move(SegMem); 405 } 406 return std::unique_ptr<InProcessMemoryManager::Allocation>( 407 new IPMMAlloc(*this, std::move(Blocks))); 408 } 409 410 private: 411 JITLinkSlabAllocator(uint64_t SlabSize, Error &Err) { 412 ErrorAsOutParameter _(&Err); 413 414 PageSize = sys::Process::getPageSizeEstimate(); 415 416 if (!isPowerOf2_64(PageSize)) { 417 Err = make_error<StringError>("Page size is not a power of 2", 418 inconvertibleErrorCode()); 419 return; 420 } 421 422 // Round slab request up to page size. 423 SlabSize = (SlabSize + PageSize - 1) & ~(PageSize - 1); 424 425 const sys::Memory::ProtectionFlags ReadWrite = 426 static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ | 427 sys::Memory::MF_WRITE); 428 429 std::error_code EC; 430 SlabRemaining = 431 sys::Memory::allocateMappedMemory(SlabSize, nullptr, ReadWrite, EC); 432 433 if (EC) { 434 Err = errorCodeToError(EC); 435 return; 436 } 437 438 // Calculate the target address delta to link as-if slab were at 439 // SlabAddress. 440 if (SlabAddress != ~0ULL) 441 TargetDelta = 442 SlabAddress - pointerToJITTargetAddress(SlabRemaining.base()); 443 } 444 445 sys::MemoryBlock SlabRemaining; 446 uint64_t PageSize = 0; 447 int64_t TargetDelta = 0; 448 }; 449 450 Expected<uint64_t> getSlabAllocSize(StringRef SizeString) { 451 SizeString = SizeString.trim(); 452 453 uint64_t Units = 1024; 454 455 if (SizeString.endswith_lower("kb")) 456 SizeString = SizeString.drop_back(2).rtrim(); 457 else if (SizeString.endswith_lower("mb")) { 458 Units = 1024 * 1024; 459 SizeString = SizeString.drop_back(2).rtrim(); 460 } else if (SizeString.endswith_lower("gb")) { 461 Units = 1024 * 1024 * 1024; 462 SizeString = SizeString.drop_back(2).rtrim(); 463 } 464 465 uint64_t SlabSize = 0; 466 if (SizeString.getAsInteger(10, SlabSize)) 467 return make_error<StringError>("Invalid numeric format for slab size", 468 inconvertibleErrorCode()); 469 470 return SlabSize * Units; 471 } 472 473 static std::unique_ptr<JITLinkMemoryManager> createMemoryManager() { 474 if (!SlabAllocateSizeString.empty()) { 475 auto SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString)); 476 return ExitOnErr(JITLinkSlabAllocator::Create(SlabSize)); 477 } 478 return std::make_unique<InProcessMemoryManager>(); 479 } 480 481 LLVMJITLinkObjectLinkingLayer::LLVMJITLinkObjectLinkingLayer( 482 Session &S, JITLinkMemoryManager &MemMgr) 483 : ObjectLinkingLayer(S.ES, MemMgr), S(S) {} 484 485 Error LLVMJITLinkObjectLinkingLayer::add(ResourceTrackerSP RT, 486 std::unique_ptr<MemoryBuffer> O) { 487 488 if (S.HarnessFiles.empty() || S.HarnessFiles.count(O->getBufferIdentifier())) 489 return ObjectLinkingLayer::add(std::move(RT), std::move(O)); 490 491 // Use getObjectSymbolInfo to compute the init symbol, but ignore 492 // the symbols field. We'll handle that manually to include promotion. 493 auto ObjSymInfo = 494 getObjectSymbolInfo(getExecutionSession(), O->getMemBufferRef()); 495 496 if (!ObjSymInfo) 497 return ObjSymInfo.takeError(); 498 499 auto &InitSymbol = ObjSymInfo->second; 500 501 // If creating an object file was going to fail it would have happened above, 502 // so we can 'cantFail' this. 503 auto Obj = 504 cantFail(object::ObjectFile::createObjectFile(O->getMemBufferRef())); 505 506 SymbolFlagsMap SymbolFlags; 507 508 // The init symbol must be included in the SymbolFlags map if present. 509 if (InitSymbol) 510 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; 511 512 for (auto &Sym : Obj->symbols()) { 513 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 514 if (!SymFlagsOrErr) 515 // TODO: Test this error. 516 return SymFlagsOrErr.takeError(); 517 518 // Skip symbols not defined in this object file. 519 if ((*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)) 520 continue; 521 522 auto Name = Sym.getName(); 523 if (!Name) 524 return Name.takeError(); 525 526 // Skip symbols that have type SF_File. 527 if (auto SymType = Sym.getType()) { 528 if (*SymType == object::SymbolRef::ST_File) 529 continue; 530 } else 531 return SymType.takeError(); 532 533 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 534 if (!SymFlags) 535 return SymFlags.takeError(); 536 537 if (SymFlags->isWeak()) { 538 // If this is a weak symbol that's not defined in the harness then we 539 // need to either mark it as strong (if this is the first definition 540 // that we've seen) or discard it. 541 if (S.HarnessDefinitions.count(*Name) || S.CanonicalWeakDefs.count(*Name)) 542 continue; 543 S.CanonicalWeakDefs[*Name] = O->getBufferIdentifier(); 544 *SymFlags &= ~JITSymbolFlags::Weak; 545 if (!S.HarnessExternals.count(*Name)) 546 *SymFlags &= ~JITSymbolFlags::Exported; 547 } else if (S.HarnessExternals.count(*Name)) { 548 *SymFlags |= JITSymbolFlags::Exported; 549 } else if (S.HarnessDefinitions.count(*Name) || 550 !(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 551 continue; 552 553 auto InternedName = S.ES.intern(*Name); 554 SymbolFlags[InternedName] = std::move(*SymFlags); 555 } 556 557 auto MU = std::make_unique<BasicObjectLayerMaterializationUnit>( 558 *this, std::move(O), std::move(SymbolFlags), std::move(InitSymbol)); 559 560 auto &JD = RT->getJITDylib(); 561 return JD.define(std::move(MU), std::move(RT)); 562 } 563 564 class PhonyExternalsGenerator : public DefinitionGenerator { 565 public: 566 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, 567 JITDylibLookupFlags JDLookupFlags, 568 const SymbolLookupSet &LookupSet) override { 569 SymbolMap PhonySymbols; 570 for (auto &KV : LookupSet) 571 PhonySymbols[KV.first] = JITEvaluatedSymbol(0, JITSymbolFlags::Exported); 572 return JD.define(absoluteSymbols(std::move(PhonySymbols))); 573 } 574 }; 575 576 Expected<std::unique_ptr<Session>> Session::Create(Triple TT) { 577 Error Err = Error::success(); 578 579 auto PageSize = sys::Process::getPageSize(); 580 if (!PageSize) 581 return PageSize.takeError(); 582 583 std::unique_ptr<Session> S(new Session(std::move(TT), *PageSize, Err)); 584 if (Err) 585 return std::move(Err); 586 return std::move(S); 587 } 588 589 Session::~Session() { 590 if (auto Err = ES.endSession()) 591 ES.reportError(std::move(Err)); 592 } 593 594 // FIXME: Move to createJITDylib if/when we start using Platform support in 595 // llvm-jitlink. 596 Session::Session(Triple TT, uint64_t PageSize, Error &Err) 597 : TPC(std::make_unique<SelfTargetProcessControl>(std::move(TT), PageSize, 598 createMemoryManager())), 599 ObjLayer(*this, TPC->getMemMgr()) { 600 601 /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the 602 /// Session. 603 class JITLinkSessionPlugin : public ObjectLinkingLayer::Plugin { 604 public: 605 JITLinkSessionPlugin(Session &S) : S(S) {} 606 void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, 607 PassConfiguration &PassConfig) override { 608 S.modifyPassConfig(TT, PassConfig); 609 } 610 611 Error notifyFailed(MaterializationResponsibility &MR) override { 612 return Error::success(); 613 } 614 Error notifyRemovingResources(ResourceKey K) override { 615 return Error::success(); 616 } 617 void notifyTransferringResources(ResourceKey DstKey, 618 ResourceKey SrcKey) override {} 619 620 private: 621 Session &S; 622 }; 623 624 ErrorAsOutParameter _(&Err); 625 626 if (auto MainJDOrErr = ES.createJITDylib("main")) 627 MainJD = &*MainJDOrErr; 628 else { 629 Err = MainJDOrErr.takeError(); 630 return; 631 } 632 633 if (!NoExec && !TT.isOSWindows()) 634 ObjLayer.addPlugin(std::make_unique<EHFrameRegistrationPlugin>( 635 ES, std::make_unique<InProcessEHFrameRegistrar>())); 636 637 ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this)); 638 639 // Process any harness files. 640 for (auto &HarnessFile : TestHarnesses) { 641 HarnessFiles.insert(HarnessFile); 642 643 auto ObjBuffer = 644 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile))); 645 646 auto ObjSymbolInfo = 647 ExitOnErr(getObjectSymbolInfo(ES, ObjBuffer->getMemBufferRef())); 648 649 for (auto &KV : ObjSymbolInfo.first) 650 HarnessDefinitions.insert(*KV.first); 651 652 auto Obj = ExitOnErr( 653 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())); 654 655 for (auto &Sym : Obj->symbols()) { 656 uint32_t SymFlags = ExitOnErr(Sym.getFlags()); 657 auto Name = ExitOnErr(Sym.getName()); 658 659 if (Name.empty()) 660 continue; 661 662 if (SymFlags & object::BasicSymbolRef::SF_Undefined) 663 HarnessExternals.insert(Name); 664 } 665 } 666 667 // If a name is defined by some harness file then it's a definition, not an 668 // external. 669 for (auto &DefName : HarnessDefinitions) 670 HarnessExternals.erase(DefName.getKey()); 671 } 672 673 void Session::dumpSessionInfo(raw_ostream &OS) { 674 OS << "Registered addresses:\n" << SymbolInfos << FileInfos; 675 } 676 677 void Session::modifyPassConfig(const Triple &TT, 678 PassConfiguration &PassConfig) { 679 if (!CheckFiles.empty()) 680 PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) { 681 if (TPC->getTargetTriple().getObjectFormat() == Triple::ELF) 682 return registerELFGraphInfo(*this, G); 683 684 if (TPC->getTargetTriple().getObjectFormat() == Triple::MachO) 685 return registerMachOGraphInfo(*this, G); 686 687 return make_error<StringError>("Unsupported object format for GOT/stub " 688 "registration", 689 inconvertibleErrorCode()); 690 }); 691 692 if (ShowLinkGraph) 693 PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error { 694 outs() << "Link graph \"" << G.getName() << "\" post-fixup:\n"; 695 G.dump(outs()); 696 return Error::success(); 697 }); 698 699 PassConfig.PrePrunePasses.push_back( 700 [this](LinkGraph &G) { return applyHarnessPromotions(*this, G); }); 701 702 if (ShowSizes) { 703 PassConfig.PrePrunePasses.push_back([this](LinkGraph &G) -> Error { 704 SizeBeforePruning += computeTotalBlockSizes(G); 705 return Error::success(); 706 }); 707 PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error { 708 SizeAfterFixups += computeTotalBlockSizes(G); 709 return Error::success(); 710 }); 711 } 712 713 if (ShowRelocatedSectionContents) 714 PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error { 715 outs() << "Relocated section contents for " << G.getName() << ":\n"; 716 dumpSectionContents(outs(), G); 717 return Error::success(); 718 }); 719 } 720 721 Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) { 722 auto FileInfoItr = FileInfos.find(FileName); 723 if (FileInfoItr == FileInfos.end()) 724 return make_error<StringError>("file \"" + FileName + "\" not recognized", 725 inconvertibleErrorCode()); 726 return FileInfoItr->second; 727 } 728 729 Expected<Session::MemoryRegionInfo &> 730 Session::findSectionInfo(StringRef FileName, StringRef SectionName) { 731 auto FI = findFileInfo(FileName); 732 if (!FI) 733 return FI.takeError(); 734 auto SecInfoItr = FI->SectionInfos.find(SectionName); 735 if (SecInfoItr == FI->SectionInfos.end()) 736 return make_error<StringError>("no section \"" + SectionName + 737 "\" registered for file \"" + FileName + 738 "\"", 739 inconvertibleErrorCode()); 740 return SecInfoItr->second; 741 } 742 743 Expected<Session::MemoryRegionInfo &> 744 Session::findStubInfo(StringRef FileName, StringRef TargetName) { 745 auto FI = findFileInfo(FileName); 746 if (!FI) 747 return FI.takeError(); 748 auto StubInfoItr = FI->StubInfos.find(TargetName); 749 if (StubInfoItr == FI->StubInfos.end()) 750 return make_error<StringError>("no stub for \"" + TargetName + 751 "\" registered for file \"" + FileName + 752 "\"", 753 inconvertibleErrorCode()); 754 return StubInfoItr->second; 755 } 756 757 Expected<Session::MemoryRegionInfo &> 758 Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) { 759 auto FI = findFileInfo(FileName); 760 if (!FI) 761 return FI.takeError(); 762 auto GOTInfoItr = FI->GOTEntryInfos.find(TargetName); 763 if (GOTInfoItr == FI->GOTEntryInfos.end()) 764 return make_error<StringError>("no GOT entry for \"" + TargetName + 765 "\" registered for file \"" + FileName + 766 "\"", 767 inconvertibleErrorCode()); 768 return GOTInfoItr->second; 769 } 770 771 bool Session::isSymbolRegistered(StringRef SymbolName) { 772 return SymbolInfos.count(SymbolName); 773 } 774 775 Expected<Session::MemoryRegionInfo &> 776 Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) { 777 auto SymInfoItr = SymbolInfos.find(SymbolName); 778 if (SymInfoItr == SymbolInfos.end()) 779 return make_error<StringError>(ErrorMsgStem + ": symbol " + SymbolName + 780 " not found", 781 inconvertibleErrorCode()); 782 return SymInfoItr->second; 783 } 784 785 } // end namespace llvm 786 787 static Triple getFirstFileTriple() { 788 assert(!InputFiles.empty() && "InputFiles can not be empty"); 789 auto ObjBuffer = 790 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFiles.front()))); 791 auto Obj = ExitOnErr( 792 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())); 793 return Obj->makeTriple(); 794 } 795 796 static Error sanitizeArguments(const Session &S) { 797 if (EntryPointName.empty()) { 798 if (S.TPC->getTargetTriple().getObjectFormat() == Triple::MachO) 799 EntryPointName = "_main"; 800 else 801 EntryPointName = "main"; 802 } 803 804 if (NoExec && !InputArgv.empty()) 805 outs() << "Warning: --args passed to -noexec run will be ignored.\n"; 806 807 // If -slab-address is passed, require -slab-allocate and -noexec 808 if (SlabAddress != ~0ULL) { 809 if (SlabAllocateSizeString == "" || !NoExec) 810 return make_error<StringError>( 811 "-slab-address requires -slab-allocate and -noexec", 812 inconvertibleErrorCode()); 813 } 814 815 return Error::success(); 816 } 817 818 static Error loadProcessSymbols(Session &S) { 819 auto InternedEntryPointName = S.ES.intern(EntryPointName); 820 auto FilterMainEntryPoint = [InternedEntryPointName](SymbolStringPtr Name) { 821 return Name != InternedEntryPointName; 822 }; 823 S.MainJD->addGenerator( 824 ExitOnErr(orc::TPCDynamicLibrarySearchGenerator::GetForTargetProcess( 825 *S.TPC, std::move(FilterMainEntryPoint)))); 826 827 return Error::success(); 828 } 829 830 static Error loadDylibs() { 831 // FIXME: This should all be handled inside DynamicLibrary. 832 for (const auto &Dylib : Dylibs) { 833 if (!sys::fs::is_regular_file(Dylib)) 834 return make_error<StringError>("\"" + Dylib + "\" is not a regular file", 835 inconvertibleErrorCode()); 836 std::string ErrMsg; 837 if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg)) 838 return make_error<StringError>(ErrMsg, inconvertibleErrorCode()); 839 } 840 841 return Error::success(); 842 } 843 844 static void addPhonyExternalsGenerator(Session &S) { 845 S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>()); 846 } 847 848 static Error loadObjects(Session &S) { 849 std::map<unsigned, JITDylib *> IdxToJLD; 850 851 // First, set up JITDylibs. 852 LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n"); 853 { 854 // Create a "main" JITLinkDylib. 855 IdxToJLD[0] = S.MainJD; 856 S.JDSearchOrder.push_back(S.MainJD); 857 LLVM_DEBUG(dbgs() << " 0: " << S.MainJD->getName() << "\n"); 858 859 // Add any extra JITLinkDylibs from the command line. 860 std::string JDNamePrefix("lib"); 861 for (auto JLDItr = JITLinkDylibs.begin(), JLDEnd = JITLinkDylibs.end(); 862 JLDItr != JLDEnd; ++JLDItr) { 863 auto JD = S.ES.createJITDylib(JDNamePrefix + *JLDItr); 864 if (!JD) 865 return JD.takeError(); 866 unsigned JDIdx = 867 JITLinkDylibs.getPosition(JLDItr - JITLinkDylibs.begin()); 868 IdxToJLD[JDIdx] = &*JD; 869 S.JDSearchOrder.push_back(&*JD); 870 LLVM_DEBUG(dbgs() << " " << JDIdx << ": " << JD->getName() << "\n"); 871 } 872 873 // Set every dylib to link against every other, in command line order. 874 for (auto *JD : S.JDSearchOrder) { 875 auto LookupFlags = JITDylibLookupFlags::MatchExportedSymbolsOnly; 876 JITDylibSearchOrder LinkOrder; 877 for (auto *JD2 : S.JDSearchOrder) { 878 if (JD2 == JD) 879 continue; 880 LinkOrder.push_back(std::make_pair(JD2, LookupFlags)); 881 } 882 JD->setLinkOrder(std::move(LinkOrder)); 883 } 884 } 885 886 LLVM_DEBUG(dbgs() << "Adding test harness objects...\n"); 887 for (auto HarnessFile : TestHarnesses) { 888 LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n"); 889 auto ObjBuffer = 890 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile))); 891 ExitOnErr(S.ObjLayer.add(*S.MainJD, std::move(ObjBuffer))); 892 } 893 894 // Load each object into the corresponding JITDylib.. 895 LLVM_DEBUG(dbgs() << "Adding objects...\n"); 896 for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end(); 897 InputFileItr != InputFileEnd; ++InputFileItr) { 898 unsigned InputFileArgIdx = 899 InputFiles.getPosition(InputFileItr - InputFiles.begin()); 900 const std::string &InputFile = *InputFileItr; 901 auto &JD = *std::prev(IdxToJLD.lower_bound(InputFileArgIdx))->second; 902 LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile 903 << "\" to " << JD.getName() << "\n";); 904 auto ObjBuffer = 905 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFile))); 906 907 auto Magic = identify_magic(ObjBuffer->getBuffer()); 908 if (Magic == file_magic::archive || 909 Magic == file_magic::macho_universal_binary) 910 JD.addGenerator(ExitOnErr(StaticLibraryDefinitionGenerator::Load( 911 S.ObjLayer, InputFile.c_str(), S.TPC->getTargetTriple()))); 912 else 913 ExitOnErr(S.ObjLayer.add(JD, std::move(ObjBuffer))); 914 } 915 916 // Define absolute symbols. 917 LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n"); 918 for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end(); 919 AbsDefItr != AbsDefEnd; ++AbsDefItr) { 920 unsigned AbsDefArgIdx = 921 AbsoluteDefs.getPosition(AbsDefItr - AbsoluteDefs.begin()); 922 auto &JD = *std::prev(IdxToJLD.lower_bound(AbsDefArgIdx))->second; 923 924 StringRef AbsDefStmt = *AbsDefItr; 925 size_t EqIdx = AbsDefStmt.find_first_of('='); 926 if (EqIdx == StringRef::npos) 927 return make_error<StringError>("Invalid absolute define \"" + AbsDefStmt + 928 "\". Syntax: <name>=<addr>", 929 inconvertibleErrorCode()); 930 StringRef Name = AbsDefStmt.substr(0, EqIdx).trim(); 931 StringRef AddrStr = AbsDefStmt.substr(EqIdx + 1).trim(); 932 933 uint64_t Addr; 934 if (AddrStr.getAsInteger(0, Addr)) 935 return make_error<StringError>("Invalid address expression \"" + AddrStr + 936 "\" in absolute define \"" + AbsDefStmt + 937 "\"", 938 inconvertibleErrorCode()); 939 JITEvaluatedSymbol AbsDef(Addr, JITSymbolFlags::Exported); 940 if (auto Err = JD.define(absoluteSymbols({{S.ES.intern(Name), AbsDef}}))) 941 return Err; 942 943 // Register the absolute symbol with the session symbol infos. 944 S.SymbolInfos[Name] = { StringRef(), Addr }; 945 } 946 947 LLVM_DEBUG({ 948 dbgs() << "Dylib search order is [ "; 949 for (auto *JD : S.JDSearchOrder) 950 dbgs() << JD->getName() << " "; 951 dbgs() << "]\n"; 952 }); 953 954 return Error::success(); 955 } 956 957 static Error runChecks(Session &S) { 958 959 auto TripleName = S.TPC->getTargetTriple().str(); 960 std::string ErrorStr; 961 const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, ErrorStr); 962 if (!TheTarget) 963 ExitOnErr(make_error<StringError>("Error accessing target '" + TripleName + 964 "': " + ErrorStr, 965 inconvertibleErrorCode())); 966 967 std::unique_ptr<MCSubtargetInfo> STI( 968 TheTarget->createMCSubtargetInfo(TripleName, "", "")); 969 if (!STI) 970 ExitOnErr( 971 make_error<StringError>("Unable to create subtarget for " + TripleName, 972 inconvertibleErrorCode())); 973 974 std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 975 if (!MRI) 976 ExitOnErr(make_error<StringError>("Unable to create target register info " 977 "for " + 978 TripleName, 979 inconvertibleErrorCode())); 980 981 MCTargetOptions MCOptions; 982 std::unique_ptr<MCAsmInfo> MAI( 983 TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 984 if (!MAI) 985 ExitOnErr(make_error<StringError>("Unable to create target asm info " + 986 TripleName, 987 inconvertibleErrorCode())); 988 989 MCContext Ctx(MAI.get(), MRI.get(), nullptr); 990 991 std::unique_ptr<MCDisassembler> Disassembler( 992 TheTarget->createMCDisassembler(*STI, Ctx)); 993 if (!Disassembler) 994 ExitOnErr(make_error<StringError>("Unable to create disassembler for " + 995 TripleName, 996 inconvertibleErrorCode())); 997 998 std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 999 1000 std::unique_ptr<MCInstPrinter> InstPrinter( 1001 TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); 1002 1003 auto IsSymbolValid = [&S](StringRef Symbol) { 1004 return S.isSymbolRegistered(Symbol); 1005 }; 1006 1007 auto GetSymbolInfo = [&S](StringRef Symbol) { 1008 return S.findSymbolInfo(Symbol, "Can not get symbol info"); 1009 }; 1010 1011 auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) { 1012 return S.findSectionInfo(FileName, SectionName); 1013 }; 1014 1015 auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName) { 1016 return S.findStubInfo(FileName, SectionName); 1017 }; 1018 1019 auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) { 1020 return S.findGOTEntryInfo(FileName, SectionName); 1021 }; 1022 1023 RuntimeDyldChecker Checker( 1024 IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo, 1025 S.TPC->getTargetTriple().isLittleEndian() ? support::little 1026 : support::big, 1027 Disassembler.get(), InstPrinter.get(), dbgs()); 1028 1029 std::string CheckLineStart = "# " + CheckName + ":"; 1030 for (auto &CheckFile : CheckFiles) { 1031 auto CheckerFileBuf = 1032 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(CheckFile))); 1033 if (!Checker.checkAllRulesInBuffer(CheckLineStart, &*CheckerFileBuf)) 1034 ExitOnErr(make_error<StringError>( 1035 "Some checks in " + CheckFile + " failed", inconvertibleErrorCode())); 1036 } 1037 1038 return Error::success(); 1039 } 1040 1041 static void dumpSessionStats(Session &S) { 1042 if (ShowSizes) 1043 outs() << "Total size of all blocks before pruning: " << S.SizeBeforePruning 1044 << "\nTotal size of all blocks after fixups: " << S.SizeAfterFixups 1045 << "\n"; 1046 } 1047 1048 static Expected<JITEvaluatedSymbol> getMainEntryPoint(Session &S) { 1049 return S.ES.lookup(S.JDSearchOrder, EntryPointName); 1050 } 1051 1052 namespace { 1053 struct JITLinkTimers { 1054 TimerGroup JITLinkTG{"llvm-jitlink timers", "timers for llvm-jitlink phases"}; 1055 Timer LoadObjectsTimer{"load", "time to load/add object files", JITLinkTG}; 1056 Timer LinkTimer{"link", "time to link object files", JITLinkTG}; 1057 Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTG}; 1058 }; 1059 } // namespace 1060 1061 int main(int argc, char *argv[]) { 1062 InitLLVM X(argc, argv); 1063 1064 InitializeAllTargetInfos(); 1065 InitializeAllTargetMCs(); 1066 InitializeAllDisassemblers(); 1067 1068 cl::ParseCommandLineOptions(argc, argv, "llvm jitlink tool"); 1069 ExitOnErr.setBanner(std::string(argv[0]) + ": "); 1070 1071 /// If timers are enabled, create a JITLinkTimers instance. 1072 std::unique_ptr<JITLinkTimers> Timers = 1073 ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr; 1074 1075 auto S = ExitOnErr(Session::Create(getFirstFileTriple())); 1076 1077 ExitOnErr(sanitizeArguments(*S)); 1078 1079 { 1080 TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr); 1081 ExitOnErr(loadObjects(*S)); 1082 } 1083 1084 if (!NoProcessSymbols) 1085 ExitOnErr(loadProcessSymbols(*S)); 1086 ExitOnErr(loadDylibs()); 1087 1088 if (PhonyExternals) 1089 addPhonyExternalsGenerator(*S); 1090 1091 1092 if (ShowInitialExecutionSessionState) 1093 S->ES.dump(outs()); 1094 1095 JITEvaluatedSymbol EntryPoint = 0; 1096 { 1097 TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr); 1098 EntryPoint = ExitOnErr(getMainEntryPoint(*S)); 1099 } 1100 1101 if (ShowAddrs) 1102 S->dumpSessionInfo(outs()); 1103 1104 ExitOnErr(runChecks(*S)); 1105 1106 dumpSessionStats(*S); 1107 1108 if (NoExec) 1109 return 0; 1110 1111 int Result = 0; 1112 { 1113 using MainTy = int (*)(int, char *[]); 1114 auto EntryFn = jitTargetAddressToFunction<MainTy>(EntryPoint.getAddress()); 1115 TimeRegion TR(Timers ? &Timers->RunTimer : nullptr); 1116 Result = runAsMain(EntryFn, InputArgv, StringRef(InputFiles.front())); 1117 } 1118 1119 return Result; 1120 } 1121