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