1 //===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===// 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 is a testing tool for use with the MC-JIT LLVM components. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ADT/StringMap.h" 14 #include "llvm/DebugInfo/DIContext.h" 15 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 16 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 17 #include "llvm/ExecutionEngine/RuntimeDyld.h" 18 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 19 #include "llvm/MC/MCAsmInfo.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 22 #include "llvm/MC/MCInstPrinter.h" 23 #include "llvm/MC/MCInstrInfo.h" 24 #include "llvm/MC/MCRegisterInfo.h" 25 #include "llvm/MC/MCSubtargetInfo.h" 26 #include "llvm/MC/MCTargetOptions.h" 27 #include "llvm/MC/TargetRegistry.h" 28 #include "llvm/Object/SymbolSize.h" 29 #include "llvm/Support/CommandLine.h" 30 #include "llvm/Support/DynamicLibrary.h" 31 #include "llvm/Support/FileSystem.h" 32 #include "llvm/Support/InitLLVM.h" 33 #include "llvm/Support/MSVCErrorWorkarounds.h" 34 #include "llvm/Support/Memory.h" 35 #include "llvm/Support/MemoryBuffer.h" 36 #include "llvm/Support/Path.h" 37 #include "llvm/Support/TargetSelect.h" 38 #include "llvm/Support/Timer.h" 39 #include "llvm/Support/raw_ostream.h" 40 41 #include <future> 42 #include <list> 43 44 using namespace llvm; 45 using namespace llvm::object; 46 47 static cl::OptionCategory RTDyldCategory("RTDyld Options"); 48 49 static cl::list<std::string> InputFileList(cl::Positional, cl::ZeroOrMore, 50 cl::desc("<input files>"), 51 cl::cat(RTDyldCategory)); 52 53 enum ActionType { 54 AC_Execute, 55 AC_PrintObjectLineInfo, 56 AC_PrintLineInfo, 57 AC_PrintDebugLineInfo, 58 AC_Verify 59 }; 60 61 static cl::opt<ActionType> Action( 62 cl::desc("Action to perform:"), cl::init(AC_Execute), 63 cl::values( 64 clEnumValN(AC_Execute, "execute", 65 "Load, link, and execute the inputs."), 66 clEnumValN(AC_PrintLineInfo, "printline", 67 "Load, link, and print line information for each function."), 68 clEnumValN(AC_PrintDebugLineInfo, "printdebugline", 69 "Load, link, and print line information for each function " 70 "using the debug object"), 71 clEnumValN(AC_PrintObjectLineInfo, "printobjline", 72 "Like -printlineinfo but does not load the object first"), 73 clEnumValN(AC_Verify, "verify", 74 "Load, link and verify the resulting memory image.")), 75 cl::cat(RTDyldCategory)); 76 77 static cl::opt<std::string> 78 EntryPoint("entry", cl::desc("Function to call as entry point."), 79 cl::init("_main"), cl::cat(RTDyldCategory)); 80 81 static cl::list<std::string> Dylibs("dylib", cl::desc("Add library."), 82 cl::ZeroOrMore, cl::cat(RTDyldCategory)); 83 84 static cl::list<std::string> InputArgv("args", cl::Positional, 85 cl::desc("<program arguments>..."), 86 cl::ZeroOrMore, cl::PositionalEatsArgs, 87 cl::cat(RTDyldCategory)); 88 89 static cl::opt<std::string> 90 TripleName("triple", cl::desc("Target triple for disassembler"), 91 cl::cat(RTDyldCategory)); 92 93 static cl::opt<std::string> 94 MCPU("mcpu", 95 cl::desc("Target a specific cpu type (-mcpu=help for details)"), 96 cl::value_desc("cpu-name"), cl::init(""), cl::cat(RTDyldCategory)); 97 98 static cl::list<std::string> 99 CheckFiles("check", 100 cl::desc("File containing RuntimeDyld verifier checks."), 101 cl::ZeroOrMore, cl::cat(RTDyldCategory)); 102 103 static cl::opt<uint64_t> 104 PreallocMemory("preallocate", 105 cl::desc("Allocate memory upfront rather than on-demand"), 106 cl::init(0), cl::cat(RTDyldCategory)); 107 108 static cl::opt<uint64_t> TargetAddrStart( 109 "target-addr-start", 110 cl::desc("For -verify only: start of phony target address " 111 "range."), 112 cl::init(4096), // Start at "page 1" - no allocating at "null". 113 cl::Hidden, cl::cat(RTDyldCategory)); 114 115 static cl::opt<uint64_t> TargetAddrEnd( 116 "target-addr-end", 117 cl::desc("For -verify only: end of phony target address range."), 118 cl::init(~0ULL), cl::Hidden, cl::cat(RTDyldCategory)); 119 120 static cl::opt<uint64_t> TargetSectionSep( 121 "target-section-sep", 122 cl::desc("For -verify only: Separation between sections in " 123 "phony target address space."), 124 cl::init(0), cl::Hidden, cl::cat(RTDyldCategory)); 125 126 static cl::list<std::string> 127 SpecificSectionMappings("map-section", 128 cl::desc("For -verify only: Map a section to a " 129 "specific address."), 130 cl::ZeroOrMore, cl::Hidden, 131 cl::cat(RTDyldCategory)); 132 133 static cl::list<std::string> DummySymbolMappings( 134 "dummy-extern", 135 cl::desc("For -verify only: Inject a symbol into the extern " 136 "symbol table."), 137 cl::ZeroOrMore, cl::Hidden, cl::cat(RTDyldCategory)); 138 139 static cl::opt<bool> PrintAllocationRequests( 140 "print-alloc-requests", 141 cl::desc("Print allocation requests made to the memory " 142 "manager by RuntimeDyld"), 143 cl::Hidden, cl::cat(RTDyldCategory)); 144 145 static cl::opt<bool> ShowTimes("show-times", 146 cl::desc("Show times for llvm-rtdyld phases"), 147 cl::init(false), cl::cat(RTDyldCategory)); 148 149 ExitOnError ExitOnErr; 150 151 struct RTDyldTimers { 152 TimerGroup RTDyldTG{"llvm-rtdyld timers", "timers for llvm-rtdyld phases"}; 153 Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTG}; 154 Timer LinkTimer{"link", "time to link object files", RTDyldTG}; 155 Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTG}; 156 }; 157 158 std::unique_ptr<RTDyldTimers> Timers; 159 160 /* *** */ 161 162 using SectionIDMap = StringMap<unsigned>; 163 using FileToSectionIDMap = StringMap<SectionIDMap>; 164 165 void dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) { 166 for (const auto &KV : FileToSecIDMap) { 167 llvm::dbgs() << "In " << KV.first() << "\n"; 168 for (auto &KV2 : KV.second) 169 llvm::dbgs() << " \"" << KV2.first() << "\" -> " << KV2.second << "\n"; 170 } 171 } 172 173 Expected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap, 174 StringRef FileName, StringRef SectionName) { 175 auto I = FileToSecIDMap.find(FileName); 176 if (I == FileToSecIDMap.end()) 177 return make_error<StringError>("No file named " + FileName, 178 inconvertibleErrorCode()); 179 auto &SectionIDs = I->second; 180 auto J = SectionIDs.find(SectionName); 181 if (J == SectionIDs.end()) 182 return make_error<StringError>("No section named \"" + SectionName + 183 "\" in file " + FileName, 184 inconvertibleErrorCode()); 185 return J->second; 186 } 187 188 // A trivial memory manager that doesn't do anything fancy, just uses the 189 // support library allocation routines directly. 190 class TrivialMemoryManager : public RTDyldMemoryManager { 191 public: 192 struct SectionInfo { 193 SectionInfo(StringRef Name, sys::MemoryBlock MB, unsigned SectionID) 194 : Name(std::string(Name)), MB(std::move(MB)), SectionID(SectionID) {} 195 std::string Name; 196 sys::MemoryBlock MB; 197 unsigned SectionID = ~0U; 198 }; 199 200 SmallVector<SectionInfo, 16> FunctionMemory; 201 SmallVector<SectionInfo, 16> DataMemory; 202 203 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 204 unsigned SectionID, 205 StringRef SectionName) override; 206 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 207 unsigned SectionID, StringRef SectionName, 208 bool IsReadOnly) override; 209 TrivialMemoryManager::TLSSection 210 allocateTLSSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, 211 StringRef SectionName) override; 212 213 /// If non null, records subsequent Name -> SectionID mappings. 214 void setSectionIDsMap(SectionIDMap *SecIDMap) { 215 this->SecIDMap = SecIDMap; 216 } 217 218 void *getPointerToNamedFunction(const std::string &Name, 219 bool AbortOnFailure = true) override { 220 return nullptr; 221 } 222 223 bool finalizeMemory(std::string *ErrMsg) override { return false; } 224 225 void addDummySymbol(const std::string &Name, uint64_t Addr) { 226 DummyExterns[Name] = Addr; 227 } 228 229 JITSymbol findSymbol(const std::string &Name) override { 230 auto I = DummyExterns.find(Name); 231 232 if (I != DummyExterns.end()) 233 return JITSymbol(I->second, JITSymbolFlags::Exported); 234 235 if (auto Sym = RTDyldMemoryManager::findSymbol(Name)) 236 return Sym; 237 else if (auto Err = Sym.takeError()) 238 ExitOnErr(std::move(Err)); 239 else 240 ExitOnErr(make_error<StringError>("Could not find definition for \"" + 241 Name + "\"", 242 inconvertibleErrorCode())); 243 llvm_unreachable("Should have returned or exited by now"); 244 } 245 246 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 247 size_t Size) override {} 248 void deregisterEHFrames() override {} 249 250 void preallocateSlab(uint64_t Size) { 251 std::error_code EC; 252 sys::MemoryBlock MB = 253 sys::Memory::allocateMappedMemory(Size, nullptr, 254 sys::Memory::MF_READ | 255 sys::Memory::MF_WRITE, 256 EC); 257 if (!MB.base()) 258 report_fatal_error(Twine("Can't allocate enough memory: ") + 259 EC.message()); 260 261 PreallocSlab = MB; 262 UsePreallocation = true; 263 SlabSize = Size; 264 } 265 266 uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode, 267 StringRef SectionName, unsigned SectionID) { 268 Size = alignTo(Size, Alignment); 269 if (CurrentSlabOffset + Size > SlabSize) 270 report_fatal_error("Can't allocate enough memory. Tune --preallocate"); 271 272 uintptr_t OldSlabOffset = CurrentSlabOffset; 273 sys::MemoryBlock MB((void *)OldSlabOffset, Size); 274 if (isCode) 275 FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 276 else 277 DataMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 278 CurrentSlabOffset += Size; 279 return (uint8_t*)OldSlabOffset; 280 } 281 282 private: 283 std::map<std::string, uint64_t> DummyExterns; 284 sys::MemoryBlock PreallocSlab; 285 bool UsePreallocation = false; 286 uintptr_t SlabSize = 0; 287 uintptr_t CurrentSlabOffset = 0; 288 SectionIDMap *SecIDMap = nullptr; 289 #if defined(__x86_64__) && defined(__ELF__) && defined(__linux__) 290 unsigned UsedTLSStorage = 0; 291 #endif 292 }; 293 294 uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 295 unsigned Alignment, 296 unsigned SectionID, 297 StringRef SectionName) { 298 if (PrintAllocationRequests) 299 outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " 300 << Alignment << ", SectionName = " << SectionName << ")\n"; 301 302 if (SecIDMap) 303 (*SecIDMap)[SectionName] = SectionID; 304 305 if (UsePreallocation) 306 return allocateFromSlab(Size, Alignment, true /* isCode */, 307 SectionName, SectionID); 308 309 std::error_code EC; 310 sys::MemoryBlock MB = 311 sys::Memory::allocateMappedMemory(Size, nullptr, 312 sys::Memory::MF_READ | 313 sys::Memory::MF_WRITE, 314 EC); 315 if (!MB.base()) 316 report_fatal_error(Twine("MemoryManager allocation failed: ") + 317 EC.message()); 318 FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 319 return (uint8_t*)MB.base(); 320 } 321 322 uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 323 unsigned Alignment, 324 unsigned SectionID, 325 StringRef SectionName, 326 bool IsReadOnly) { 327 if (PrintAllocationRequests) 328 outs() << "allocateDataSection(Size = " << Size << ", Alignment = " 329 << Alignment << ", SectionName = " << SectionName << ")\n"; 330 331 if (SecIDMap) 332 (*SecIDMap)[SectionName] = SectionID; 333 334 if (UsePreallocation) 335 return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName, 336 SectionID); 337 338 std::error_code EC; 339 sys::MemoryBlock MB = 340 sys::Memory::allocateMappedMemory(Size, nullptr, 341 sys::Memory::MF_READ | 342 sys::Memory::MF_WRITE, 343 EC); 344 if (!MB.base()) 345 report_fatal_error(Twine("MemoryManager allocation failed: ") + 346 EC.message()); 347 DataMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 348 return (uint8_t*)MB.base(); 349 } 350 351 // In case the execution needs TLS storage, we define a very small TLS memory 352 // area here that will be used in allocateTLSSection(). 353 #if defined(__x86_64__) && defined(__ELF__) && defined(__linux__) 354 extern "C" { 355 alignas(16) __attribute__((visibility("hidden"), tls_model("initial-exec"), 356 used)) thread_local char LLVMRTDyldTLSSpace[16]; 357 } 358 #endif 359 360 TrivialMemoryManager::TLSSection 361 TrivialMemoryManager::allocateTLSSection(uintptr_t Size, unsigned Alignment, 362 unsigned SectionID, 363 StringRef SectionName) { 364 #if defined(__x86_64__) && defined(__ELF__) && defined(__linux__) 365 if (Size + UsedTLSStorage > sizeof(LLVMRTDyldTLSSpace)) { 366 return {}; 367 } 368 369 // Get the offset of the TLSSpace in the TLS block by using a tpoff 370 // relocation here. 371 int64_t TLSOffset; 372 asm("leaq LLVMRTDyldTLSSpace@tpoff, %0" : "=r"(TLSOffset)); 373 374 TLSSection Section; 375 // We use the storage directly as the initialization image. This means that 376 // when a new thread is spawned after this allocation, it will not be 377 // initialized correctly. This means, llvm-rtdyld will only support TLS in a 378 // single thread. 379 Section.InitializationImage = 380 reinterpret_cast<uint8_t *>(LLVMRTDyldTLSSpace + UsedTLSStorage); 381 Section.Offset = TLSOffset + UsedTLSStorage; 382 383 UsedTLSStorage += Size; 384 385 return Section; 386 #else 387 return {}; 388 #endif 389 } 390 391 static const char *ProgramName; 392 393 static void ErrorAndExit(const Twine &Msg) { 394 errs() << ProgramName << ": error: " << Msg << "\n"; 395 exit(1); 396 } 397 398 static void loadDylibs() { 399 for (const std::string &Dylib : Dylibs) { 400 if (!sys::fs::is_regular_file(Dylib)) 401 report_fatal_error(Twine("Dylib not found: '") + Dylib + "'."); 402 std::string ErrMsg; 403 if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg)) 404 report_fatal_error(Twine("Error loading '") + Dylib + "': " + ErrMsg); 405 } 406 } 407 408 /* *** */ 409 410 static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { 411 assert(LoadObjects || !UseDebugObj); 412 413 // Load any dylibs requested on the command line. 414 loadDylibs(); 415 416 // If we don't have any input files, read from stdin. 417 if (!InputFileList.size()) 418 InputFileList.push_back("-"); 419 for (auto &File : InputFileList) { 420 // Instantiate a dynamic linker. 421 TrivialMemoryManager MemMgr; 422 RuntimeDyld Dyld(MemMgr, MemMgr); 423 424 // Load the input memory buffer. 425 426 ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 427 MemoryBuffer::getFileOrSTDIN(File); 428 if (std::error_code EC = InputBuffer.getError()) 429 ErrorAndExit("unable to read input: '" + EC.message() + "'"); 430 431 Expected<std::unique_ptr<ObjectFile>> MaybeObj( 432 ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 433 434 if (!MaybeObj) { 435 std::string Buf; 436 raw_string_ostream OS(Buf); 437 logAllUnhandledErrors(MaybeObj.takeError(), OS); 438 OS.flush(); 439 ErrorAndExit("unable to create object file: '" + Buf + "'"); 440 } 441 442 ObjectFile &Obj = **MaybeObj; 443 444 OwningBinary<ObjectFile> DebugObj; 445 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; 446 ObjectFile *SymbolObj = &Obj; 447 if (LoadObjects) { 448 // Load the object file 449 LoadedObjInfo = 450 Dyld.loadObject(Obj); 451 452 if (Dyld.hasError()) 453 ErrorAndExit(Dyld.getErrorString()); 454 455 // Resolve all the relocations we can. 456 Dyld.resolveRelocations(); 457 458 if (UseDebugObj) { 459 DebugObj = LoadedObjInfo->getObjectForDebug(Obj); 460 SymbolObj = DebugObj.getBinary(); 461 LoadedObjInfo.reset(); 462 } 463 } 464 465 std::unique_ptr<DIContext> Context = DWARFContext::create( 466 *SymbolObj, DWARFContext::ProcessDebugRelocations::Process, 467 LoadedObjInfo.get()); 468 469 std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = 470 object::computeSymbolSizes(*SymbolObj); 471 472 // Use symbol info to iterate functions in the object. 473 for (const auto &P : SymAddr) { 474 object::SymbolRef Sym = P.first; 475 Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); 476 if (!TypeOrErr) { 477 // TODO: Actually report errors helpfully. 478 consumeError(TypeOrErr.takeError()); 479 continue; 480 } 481 SymbolRef::Type Type = *TypeOrErr; 482 if (Type == object::SymbolRef::ST_Function) { 483 Expected<StringRef> Name = Sym.getName(); 484 if (!Name) { 485 // TODO: Actually report errors helpfully. 486 consumeError(Name.takeError()); 487 continue; 488 } 489 Expected<uint64_t> AddrOrErr = Sym.getAddress(); 490 if (!AddrOrErr) { 491 // TODO: Actually report errors helpfully. 492 consumeError(AddrOrErr.takeError()); 493 continue; 494 } 495 uint64_t Addr = *AddrOrErr; 496 497 object::SectionedAddress Address; 498 499 uint64_t Size = P.second; 500 // If we're not using the debug object, compute the address of the 501 // symbol in memory (rather than that in the unrelocated object file) 502 // and use that to query the DWARFContext. 503 if (!UseDebugObj && LoadObjects) { 504 auto SecOrErr = Sym.getSection(); 505 if (!SecOrErr) { 506 // TODO: Actually report errors helpfully. 507 consumeError(SecOrErr.takeError()); 508 continue; 509 } 510 object::section_iterator Sec = *SecOrErr; 511 Address.SectionIndex = Sec->getIndex(); 512 uint64_t SectionLoadAddress = 513 LoadedObjInfo->getSectionLoadAddress(*Sec); 514 if (SectionLoadAddress != 0) 515 Addr += SectionLoadAddress - Sec->getAddress(); 516 } else if (auto SecOrErr = Sym.getSection()) 517 Address.SectionIndex = SecOrErr.get()->getIndex(); 518 519 outs() << "Function: " << *Name << ", Size = " << Size 520 << ", Addr = " << Addr << "\n"; 521 522 Address.Address = Addr; 523 DILineInfoTable Lines = 524 Context->getLineInfoForAddressRange(Address, Size); 525 for (auto &D : Lines) { 526 outs() << " Line info @ " << D.first - Addr << ": " 527 << D.second.FileName << ", line:" << D.second.Line << "\n"; 528 } 529 } 530 } 531 } 532 533 return 0; 534 } 535 536 static void doPreallocation(TrivialMemoryManager &MemMgr) { 537 // Allocate a slab of memory upfront, if required. This is used if 538 // we want to test small code models. 539 if (static_cast<intptr_t>(PreallocMemory) < 0) 540 report_fatal_error("Pre-allocated bytes of memory must be a positive integer."); 541 542 // FIXME: Limit the amount of memory that can be preallocated? 543 if (PreallocMemory != 0) 544 MemMgr.preallocateSlab(PreallocMemory); 545 } 546 547 static int executeInput() { 548 // Load any dylibs requested on the command line. 549 loadDylibs(); 550 551 // Instantiate a dynamic linker. 552 TrivialMemoryManager MemMgr; 553 doPreallocation(MemMgr); 554 RuntimeDyld Dyld(MemMgr, MemMgr); 555 556 // If we don't have any input files, read from stdin. 557 if (!InputFileList.size()) 558 InputFileList.push_back("-"); 559 { 560 TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr); 561 for (auto &File : InputFileList) { 562 // Load the input memory buffer. 563 ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 564 MemoryBuffer::getFileOrSTDIN(File); 565 if (std::error_code EC = InputBuffer.getError()) 566 ErrorAndExit("unable to read input: '" + EC.message() + "'"); 567 Expected<std::unique_ptr<ObjectFile>> MaybeObj( 568 ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 569 570 if (!MaybeObj) { 571 std::string Buf; 572 raw_string_ostream OS(Buf); 573 logAllUnhandledErrors(MaybeObj.takeError(), OS); 574 OS.flush(); 575 ErrorAndExit("unable to create object file: '" + Buf + "'"); 576 } 577 578 ObjectFile &Obj = **MaybeObj; 579 580 // Load the object file 581 Dyld.loadObject(Obj); 582 if (Dyld.hasError()) { 583 ErrorAndExit(Dyld.getErrorString()); 584 } 585 } 586 } 587 588 { 589 TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr); 590 // Resove all the relocations we can. 591 // FIXME: Error out if there are unresolved relocations. 592 Dyld.resolveRelocations(); 593 } 594 595 // Get the address of the entry point (_main by default). 596 void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); 597 if (!MainAddress) 598 ErrorAndExit("no definition for '" + EntryPoint + "'"); 599 600 // Invalidate the instruction cache for each loaded function. 601 for (auto &FM : MemMgr.FunctionMemory) { 602 603 auto &FM_MB = FM.MB; 604 605 // Make sure the memory is executable. 606 // setExecutable will call InvalidateInstructionCache. 607 if (auto EC = sys::Memory::protectMappedMemory(FM_MB, 608 sys::Memory::MF_READ | 609 sys::Memory::MF_EXEC)) 610 ErrorAndExit("unable to mark function executable: '" + EC.message() + 611 "'"); 612 } 613 614 // Dispatch to _main(). 615 errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; 616 617 int (*Main)(int, const char**) = 618 (int(*)(int,const char**)) uintptr_t(MainAddress); 619 std::vector<const char *> Argv; 620 // Use the name of the first input object module as argv[0] for the target. 621 Argv.push_back(InputFileList[0].data()); 622 for (auto &Arg : InputArgv) 623 Argv.push_back(Arg.data()); 624 Argv.push_back(nullptr); 625 int Result = 0; 626 { 627 TimeRegion TR(Timers ? &Timers->RunTimer : nullptr); 628 Result = Main(Argv.size() - 1, Argv.data()); 629 } 630 631 return Result; 632 } 633 634 static int checkAllExpressions(RuntimeDyldChecker &Checker) { 635 for (const auto& CheckerFileName : CheckFiles) { 636 ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = 637 MemoryBuffer::getFileOrSTDIN(CheckerFileName); 638 if (std::error_code EC = CheckerFileBuf.getError()) 639 ErrorAndExit("unable to read input '" + CheckerFileName + "': " + 640 EC.message()); 641 642 if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", 643 CheckerFileBuf.get().get())) 644 ErrorAndExit("some checks in '" + CheckerFileName + "' failed"); 645 } 646 return 0; 647 } 648 649 void applySpecificSectionMappings(RuntimeDyld &Dyld, 650 const FileToSectionIDMap &FileToSecIDMap) { 651 652 for (StringRef Mapping : SpecificSectionMappings) { 653 size_t EqualsIdx = Mapping.find_first_of("="); 654 std::string SectionIDStr = std::string(Mapping.substr(0, EqualsIdx)); 655 size_t ComaIdx = Mapping.find_first_of(","); 656 657 if (ComaIdx == StringRef::npos) 658 report_fatal_error("Invalid section specification '" + Mapping + 659 "'. Should be '<file name>,<section name>=<addr>'"); 660 661 std::string FileName = SectionIDStr.substr(0, ComaIdx); 662 std::string SectionName = SectionIDStr.substr(ComaIdx + 1); 663 unsigned SectionID = 664 ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName)); 665 666 auto* OldAddr = Dyld.getSectionContent(SectionID).data(); 667 std::string NewAddrStr = std::string(Mapping.substr(EqualsIdx + 1)); 668 uint64_t NewAddr; 669 670 if (StringRef(NewAddrStr).getAsInteger(0, NewAddr)) 671 report_fatal_error("Invalid section address in mapping '" + Mapping + 672 "'."); 673 674 Dyld.mapSectionAddress(OldAddr, NewAddr); 675 } 676 } 677 678 // Scatter sections in all directions! 679 // Remaps section addresses for -verify mode. The following command line options 680 // can be used to customize the layout of the memory within the phony target's 681 // address space: 682 // -target-addr-start <s> -- Specify where the phony target address range starts. 683 // -target-addr-end <e> -- Specify where the phony target address range ends. 684 // -target-section-sep <d> -- Specify how big a gap should be left between the 685 // end of one section and the start of the next. 686 // Defaults to zero. Set to something big 687 // (e.g. 1 << 32) to stress-test stubs, GOTs, etc. 688 // 689 static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, 690 RuntimeDyld &Dyld, 691 TrivialMemoryManager &MemMgr) { 692 693 // Set up a work list (section addr/size pairs). 694 typedef std::list<const TrivialMemoryManager::SectionInfo*> WorklistT; 695 WorklistT Worklist; 696 697 for (const auto& CodeSection : MemMgr.FunctionMemory) 698 Worklist.push_back(&CodeSection); 699 for (const auto& DataSection : MemMgr.DataMemory) 700 Worklist.push_back(&DataSection); 701 702 // Keep an "already allocated" mapping of section target addresses to sizes. 703 // Sections whose address mappings aren't specified on the command line will 704 // allocated around the explicitly mapped sections while maintaining the 705 // minimum separation. 706 std::map<uint64_t, uint64_t> AlreadyAllocated; 707 708 // Move the previously applied mappings (whether explicitly specified on the 709 // command line, or implicitly set by RuntimeDyld) into the already-allocated 710 // map. 711 for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); 712 I != E;) { 713 WorklistT::iterator Tmp = I; 714 ++I; 715 716 auto LoadAddr = Dyld.getSectionLoadAddress((*Tmp)->SectionID); 717 718 if (LoadAddr != static_cast<uint64_t>( 719 reinterpret_cast<uintptr_t>((*Tmp)->MB.base()))) { 720 // A section will have a LoadAddr of 0 if it wasn't loaded for whatever 721 // reason (e.g. zero byte COFF sections). Don't include those sections in 722 // the allocation map. 723 if (LoadAddr != 0) 724 AlreadyAllocated[LoadAddr] = (*Tmp)->MB.allocatedSize(); 725 Worklist.erase(Tmp); 726 } 727 } 728 729 // If the -target-addr-end option wasn't explicitly passed, then set it to a 730 // sensible default based on the target triple. 731 if (TargetAddrEnd.getNumOccurrences() == 0) { 732 if (TargetTriple.isArch16Bit()) 733 TargetAddrEnd = (1ULL << 16) - 1; 734 else if (TargetTriple.isArch32Bit()) 735 TargetAddrEnd = (1ULL << 32) - 1; 736 // TargetAddrEnd already has a sensible default for 64-bit systems, so 737 // there's nothing to do in the 64-bit case. 738 } 739 740 // Process any elements remaining in the worklist. 741 while (!Worklist.empty()) { 742 auto *CurEntry = Worklist.front(); 743 Worklist.pop_front(); 744 745 uint64_t NextSectionAddr = TargetAddrStart; 746 747 for (const auto &Alloc : AlreadyAllocated) 748 if (NextSectionAddr + CurEntry->MB.allocatedSize() + TargetSectionSep <= 749 Alloc.first) 750 break; 751 else 752 NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; 753 754 Dyld.mapSectionAddress(CurEntry->MB.base(), NextSectionAddr); 755 AlreadyAllocated[NextSectionAddr] = CurEntry->MB.allocatedSize(); 756 } 757 758 // Add dummy symbols to the memory manager. 759 for (const auto &Mapping : DummySymbolMappings) { 760 size_t EqualsIdx = Mapping.find_first_of('='); 761 762 if (EqualsIdx == StringRef::npos) 763 report_fatal_error(Twine("Invalid dummy symbol specification '") + 764 Mapping + "'. Should be '<symbol name>=<addr>'"); 765 766 std::string Symbol = Mapping.substr(0, EqualsIdx); 767 std::string AddrStr = Mapping.substr(EqualsIdx + 1); 768 769 uint64_t Addr; 770 if (StringRef(AddrStr).getAsInteger(0, Addr)) 771 report_fatal_error(Twine("Invalid symbol mapping '") + Mapping + "'."); 772 773 MemMgr.addDummySymbol(Symbol, Addr); 774 } 775 } 776 777 // Load and link the objects specified on the command line, but do not execute 778 // anything. Instead, attach a RuntimeDyldChecker instance and call it to 779 // verify the correctness of the linked memory. 780 static int linkAndVerify() { 781 782 // Check for missing triple. 783 if (TripleName == "") 784 ErrorAndExit("-triple required when running in -verify mode."); 785 786 // Look up the target and build the disassembler. 787 Triple TheTriple(Triple::normalize(TripleName)); 788 std::string ErrorStr; 789 const Target *TheTarget = 790 TargetRegistry::lookupTarget("", TheTriple, ErrorStr); 791 if (!TheTarget) 792 ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr); 793 794 TripleName = TheTriple.getTriple(); 795 796 std::unique_ptr<MCSubtargetInfo> STI( 797 TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); 798 if (!STI) 799 ErrorAndExit("Unable to create subtarget info!"); 800 801 std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 802 if (!MRI) 803 ErrorAndExit("Unable to create target register info!"); 804 805 MCTargetOptions MCOptions; 806 std::unique_ptr<MCAsmInfo> MAI( 807 TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 808 if (!MAI) 809 ErrorAndExit("Unable to create target asm info!"); 810 811 MCContext Ctx(Triple(TripleName), MAI.get(), MRI.get(), STI.get()); 812 813 std::unique_ptr<MCDisassembler> Disassembler( 814 TheTarget->createMCDisassembler(*STI, Ctx)); 815 if (!Disassembler) 816 ErrorAndExit("Unable to create disassembler!"); 817 818 std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 819 if (!MII) 820 ErrorAndExit("Unable to create target instruction info!"); 821 822 std::unique_ptr<MCInstPrinter> InstPrinter( 823 TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); 824 825 // Load any dylibs requested on the command line. 826 loadDylibs(); 827 828 // Instantiate a dynamic linker. 829 TrivialMemoryManager MemMgr; 830 doPreallocation(MemMgr); 831 832 struct StubID { 833 unsigned SectionID; 834 uint32_t Offset; 835 }; 836 using StubInfos = StringMap<StubID>; 837 using StubContainers = StringMap<StubInfos>; 838 839 StubContainers StubMap; 840 RuntimeDyld Dyld(MemMgr, MemMgr); 841 Dyld.setProcessAllSections(true); 842 843 Dyld.setNotifyStubEmitted([&StubMap](StringRef FilePath, 844 StringRef SectionName, 845 StringRef SymbolName, unsigned SectionID, 846 uint32_t StubOffset) { 847 std::string ContainerName = 848 (sys::path::filename(FilePath) + "/" + SectionName).str(); 849 StubMap[ContainerName][SymbolName] = {SectionID, StubOffset}; 850 }); 851 852 auto GetSymbolInfo = 853 [&Dyld, &MemMgr]( 854 StringRef Symbol) -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 855 RuntimeDyldChecker::MemoryRegionInfo SymInfo; 856 857 // First get the target address. 858 if (auto InternalSymbol = Dyld.getSymbol(Symbol)) 859 SymInfo.setTargetAddress(InternalSymbol.getAddress()); 860 else { 861 // Symbol not found in RuntimeDyld. Fall back to external lookup. 862 #ifdef _MSC_VER 863 using ExpectedLookupResult = 864 MSVCPExpected<JITSymbolResolver::LookupResult>; 865 #else 866 using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>; 867 #endif 868 869 auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>(); 870 auto ResultF = ResultP->get_future(); 871 872 MemMgr.lookup(JITSymbolResolver::LookupSet({Symbol}), 873 [=](Expected<JITSymbolResolver::LookupResult> Result) { 874 ResultP->set_value(std::move(Result)); 875 }); 876 877 auto Result = ResultF.get(); 878 if (!Result) 879 return Result.takeError(); 880 881 auto I = Result->find(Symbol); 882 assert(I != Result->end() && 883 "Expected symbol address if no error occurred"); 884 SymInfo.setTargetAddress(I->second.getAddress()); 885 } 886 887 // Now find the symbol content if possible (otherwise leave content as a 888 // default-constructed StringRef). 889 if (auto *SymAddr = Dyld.getSymbolLocalAddress(Symbol)) { 890 unsigned SectionID = Dyld.getSymbolSectionID(Symbol); 891 if (SectionID != ~0U) { 892 char *CSymAddr = static_cast<char *>(SymAddr); 893 StringRef SecContent = Dyld.getSectionContent(SectionID); 894 uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data()); 895 SymInfo.setContent(ArrayRef<char>(CSymAddr, SymSize)); 896 } 897 } 898 return SymInfo; 899 }; 900 901 auto IsSymbolValid = [&Dyld, GetSymbolInfo](StringRef Symbol) { 902 if (Dyld.getSymbol(Symbol)) 903 return true; 904 auto SymInfo = GetSymbolInfo(Symbol); 905 if (!SymInfo) { 906 logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 907 return false; 908 } 909 return SymInfo->getTargetAddress() != 0; 910 }; 911 912 FileToSectionIDMap FileToSecIDMap; 913 914 auto GetSectionInfo = [&Dyld, &FileToSecIDMap](StringRef FileName, 915 StringRef SectionName) 916 -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 917 auto SectionID = getSectionId(FileToSecIDMap, FileName, SectionName); 918 if (!SectionID) 919 return SectionID.takeError(); 920 RuntimeDyldChecker::MemoryRegionInfo SecInfo; 921 SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID)); 922 StringRef SecContent = Dyld.getSectionContent(*SectionID); 923 SecInfo.setContent(ArrayRef<char>(SecContent.data(), SecContent.size())); 924 return SecInfo; 925 }; 926 927 auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer, 928 StringRef SymbolName) 929 -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 930 if (!StubMap.count(StubContainer)) 931 return make_error<StringError>("Stub container not found: " + 932 StubContainer, 933 inconvertibleErrorCode()); 934 if (!StubMap[StubContainer].count(SymbolName)) 935 return make_error<StringError>("Symbol name " + SymbolName + 936 " in stub container " + StubContainer, 937 inconvertibleErrorCode()); 938 auto &SI = StubMap[StubContainer][SymbolName]; 939 RuntimeDyldChecker::MemoryRegionInfo StubMemInfo; 940 StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) + 941 SI.Offset); 942 StringRef SecContent = 943 Dyld.getSectionContent(SI.SectionID).substr(SI.Offset); 944 StubMemInfo.setContent( 945 ArrayRef<char>(SecContent.data(), SecContent.size())); 946 return StubMemInfo; 947 }; 948 949 // We will initialize this below once we have the first object file and can 950 // know the endianness. 951 std::unique_ptr<RuntimeDyldChecker> Checker; 952 953 // If we don't have any input files, read from stdin. 954 if (!InputFileList.size()) 955 InputFileList.push_back("-"); 956 for (auto &InputFile : InputFileList) { 957 // Load the input memory buffer. 958 ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 959 MemoryBuffer::getFileOrSTDIN(InputFile); 960 961 if (std::error_code EC = InputBuffer.getError()) 962 ErrorAndExit("unable to read input: '" + EC.message() + "'"); 963 964 Expected<std::unique_ptr<ObjectFile>> MaybeObj( 965 ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 966 967 if (!MaybeObj) { 968 std::string Buf; 969 raw_string_ostream OS(Buf); 970 logAllUnhandledErrors(MaybeObj.takeError(), OS); 971 OS.flush(); 972 ErrorAndExit("unable to create object file: '" + Buf + "'"); 973 } 974 975 ObjectFile &Obj = **MaybeObj; 976 977 if (!Checker) 978 Checker = std::make_unique<RuntimeDyldChecker>( 979 IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, 980 GetStubInfo, Obj.isLittleEndian() ? support::little : support::big, 981 Disassembler.get(), InstPrinter.get(), dbgs()); 982 983 auto FileName = sys::path::filename(InputFile); 984 MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]); 985 986 // Load the object file 987 Dyld.loadObject(Obj); 988 if (Dyld.hasError()) { 989 ErrorAndExit(Dyld.getErrorString()); 990 } 991 } 992 993 // Re-map the section addresses into the phony target address space and add 994 // dummy symbols. 995 applySpecificSectionMappings(Dyld, FileToSecIDMap); 996 remapSectionsAndSymbols(TheTriple, Dyld, MemMgr); 997 998 // Resolve all the relocations we can. 999 Dyld.resolveRelocations(); 1000 1001 // Register EH frames. 1002 Dyld.registerEHFrames(); 1003 1004 int ErrorCode = checkAllExpressions(*Checker); 1005 if (Dyld.hasError()) 1006 ErrorAndExit("RTDyld reported an error applying relocations:\n " + 1007 Dyld.getErrorString()); 1008 1009 return ErrorCode; 1010 } 1011 1012 int main(int argc, char **argv) { 1013 InitLLVM X(argc, argv); 1014 ProgramName = argv[0]; 1015 1016 llvm::InitializeAllTargetInfos(); 1017 llvm::InitializeAllTargetMCs(); 1018 llvm::InitializeAllDisassemblers(); 1019 1020 cl::HideUnrelatedOptions({&RTDyldCategory, &getColorCategory()}); 1021 cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); 1022 1023 ExitOnErr.setBanner(std::string(argv[0]) + ": "); 1024 1025 Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr; 1026 1027 int Result = 0; 1028 switch (Action) { 1029 case AC_Execute: 1030 Result = executeInput(); 1031 break; 1032 case AC_PrintDebugLineInfo: 1033 Result = 1034 printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ true); 1035 break; 1036 case AC_PrintLineInfo: 1037 Result = 1038 printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ false); 1039 break; 1040 case AC_PrintObjectLineInfo: 1041 Result = 1042 printLineInfoForInput(/* LoadObjects */ false, /* UseDebugObj */ false); 1043 break; 1044 case AC_Verify: 1045 Result = linkAndVerify(); 1046 break; 1047 } 1048 return Result; 1049 } 1050