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