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