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