1221337Sdim//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===// 2221337Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6221337Sdim// 7221337Sdim//===----------------------------------------------------------------------===// 8221337Sdim// 9221337Sdim// This is a testing tool for use with the MC-JIT LLVM components. 10221337Sdim// 11221337Sdim//===----------------------------------------------------------------------===// 12221337Sdim 13221337Sdim#include "llvm/ADT/StringMap.h" 14249423Sdim#include "llvm/DebugInfo/DIContext.h" 15288943Sdim#include "llvm/DebugInfo/DWARF/DWARFContext.h" 16288943Sdim#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 17221337Sdim#include "llvm/ExecutionEngine/RuntimeDyld.h" 18276479Sdim#include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 19276479Sdim#include "llvm/MC/MCAsmInfo.h" 20276479Sdim#include "llvm/MC/MCContext.h" 21309124Sdim#include "llvm/MC/MCDisassembler/MCDisassembler.h" 22280031Sdim#include "llvm/MC/MCInstPrinter.h" 23276479Sdim#include "llvm/MC/MCInstrInfo.h" 24276479Sdim#include "llvm/MC/MCRegisterInfo.h" 25288943Sdim#include "llvm/MC/MCSubtargetInfo.h" 26360784Sdim#include "llvm/MC/MCTargetOptions.h" 27288943Sdim#include "llvm/Object/SymbolSize.h" 28221337Sdim#include "llvm/Support/CommandLine.h" 29276479Sdim#include "llvm/Support/DynamicLibrary.h" 30341825Sdim#include "llvm/Support/InitLLVM.h" 31360784Sdim#include "llvm/Support/MSVCErrorWorkarounds.h" 32221337Sdim#include "llvm/Support/Memory.h" 33221337Sdim#include "llvm/Support/MemoryBuffer.h" 34353358Sdim#include "llvm/Support/Path.h" 35276479Sdim#include "llvm/Support/TargetRegistry.h" 36276479Sdim#include "llvm/Support/TargetSelect.h" 37360784Sdim#include "llvm/Support/Timer.h" 38280031Sdim#include "llvm/Support/raw_ostream.h" 39353358Sdim 40353358Sdim#include <future> 41280031Sdim#include <list> 42276479Sdim 43221337Sdimusing namespace llvm; 44221337Sdimusing namespace llvm::object; 45221337Sdim 46221337Sdimstatic cl::list<std::string> 47221337SdimInputFileList(cl::Positional, cl::ZeroOrMore, 48341825Sdim cl::desc("<input files>")); 49221337Sdim 50221337Sdimenum ActionType { 51249423Sdim AC_Execute, 52288943Sdim AC_PrintObjectLineInfo, 53276479Sdim AC_PrintLineInfo, 54288943Sdim AC_PrintDebugLineInfo, 55276479Sdim AC_Verify 56221337Sdim}; 57221337Sdim 58221337Sdimstatic cl::opt<ActionType> 59221337SdimAction(cl::desc("Action to perform:"), 60221337Sdim cl::init(AC_Execute), 61221337Sdim cl::values(clEnumValN(AC_Execute, "execute", 62221337Sdim "Load, link, and execute the inputs."), 63249423Sdim clEnumValN(AC_PrintLineInfo, "printline", 64249423Sdim "Load, link, and print line information for each function."), 65288943Sdim clEnumValN(AC_PrintDebugLineInfo, "printdebugline", 66288943Sdim "Load, link, and print line information for each function using the debug object"), 67288943Sdim clEnumValN(AC_PrintObjectLineInfo, "printobjline", 68288943Sdim "Like -printlineinfo but does not load the object first"), 69276479Sdim clEnumValN(AC_Verify, "verify", 70314564Sdim "Load, link and verify the resulting memory image."))); 71221337Sdim 72221337Sdimstatic cl::opt<std::string> 73221337SdimEntryPoint("entry", 74221337Sdim cl::desc("Function to call as entry point."), 75221337Sdim cl::init("_main")); 76221337Sdim 77276479Sdimstatic cl::list<std::string> 78276479SdimDylibs("dylib", 79276479Sdim cl::desc("Add library."), 80276479Sdim cl::ZeroOrMore); 81276479Sdim 82353358Sdimstatic cl::list<std::string> InputArgv("args", cl::Positional, 83353358Sdim cl::desc("<program arguments>..."), 84353358Sdim cl::ZeroOrMore, cl::PositionalEatsArgs); 85353358Sdim 86276479Sdimstatic cl::opt<std::string> 87276479SdimTripleName("triple", cl::desc("Target triple for disassembler")); 88276479Sdim 89288943Sdimstatic cl::opt<std::string> 90288943SdimMCPU("mcpu", 91288943Sdim cl::desc("Target a specific cpu type (-mcpu=help for details)"), 92288943Sdim cl::value_desc("cpu-name"), 93288943Sdim cl::init("")); 94288943Sdim 95276479Sdimstatic cl::list<std::string> 96276479SdimCheckFiles("check", 97276479Sdim cl::desc("File containing RuntimeDyld verifier checks."), 98276479Sdim cl::ZeroOrMore); 99276479Sdim 100353358Sdimstatic cl::opt<uint64_t> 101353358Sdim PreallocMemory("preallocate", 102353358Sdim cl::desc("Allocate memory upfront rather than on-demand"), 103353358Sdim cl::init(0)); 104296417Sdim 105353358Sdimstatic cl::opt<uint64_t> TargetAddrStart( 106353358Sdim "target-addr-start", 107353358Sdim cl::desc("For -verify only: start of phony target address " 108353358Sdim "range."), 109353358Sdim cl::init(4096), // Start at "page 1" - no allocating at "null". 110353358Sdim cl::Hidden); 111280031Sdim 112353358Sdimstatic cl::opt<uint64_t> TargetAddrEnd( 113353358Sdim "target-addr-end", 114353358Sdim cl::desc("For -verify only: end of phony target address range."), 115353358Sdim cl::init(~0ULL), cl::Hidden); 116280031Sdim 117353358Sdimstatic cl::opt<uint64_t> TargetSectionSep( 118353358Sdim "target-section-sep", 119353358Sdim cl::desc("For -verify only: Separation between sections in " 120353358Sdim "phony target address space."), 121353358Sdim cl::init(0), cl::Hidden); 122280031Sdim 123280031Sdimstatic cl::list<std::string> 124280031SdimSpecificSectionMappings("map-section", 125288943Sdim cl::desc("For -verify only: Map a section to a " 126288943Sdim "specific address."), 127288943Sdim cl::ZeroOrMore, 128288943Sdim cl::Hidden); 129280031Sdim 130288943Sdimstatic cl::list<std::string> 131288943SdimDummySymbolMappings("dummy-extern", 132288943Sdim cl::desc("For -verify only: Inject a symbol into the extern " 133288943Sdim "symbol table."), 134288943Sdim cl::ZeroOrMore, 135288943Sdim cl::Hidden); 136288943Sdim 137296417Sdimstatic cl::opt<bool> 138296417SdimPrintAllocationRequests("print-alloc-requests", 139296417Sdim cl::desc("Print allocation requests made to the memory " 140296417Sdim "manager by RuntimeDyld"), 141296417Sdim cl::Hidden); 142296417Sdim 143360784Sdimstatic cl::opt<bool> ShowTimes("show-times", 144360784Sdim cl::desc("Show times for llvm-rtdyld phases"), 145360784Sdim cl::init(false)); 146360784Sdim 147353358SdimExitOnError ExitOnErr; 148353358Sdim 149360784Sdimstruct RTDyldTimers { 150360784Sdim TimerGroup RTDyldTG{"llvm-rtdyld timers", "timers for llvm-rtdyld phases"}; 151360784Sdim Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTG}; 152360784Sdim Timer LinkTimer{"link", "time to link object files", RTDyldTG}; 153360784Sdim Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTG}; 154360784Sdim}; 155360784Sdim 156360784Sdimstd::unique_ptr<RTDyldTimers> Timers; 157360784Sdim 158221337Sdim/* *** */ 159221337Sdim 160353358Sdimusing SectionIDMap = StringMap<unsigned>; 161353358Sdimusing FileToSectionIDMap = StringMap<SectionIDMap>; 162353358Sdim 163353358Sdimvoid dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) { 164353358Sdim for (const auto &KV : FileToSecIDMap) { 165353358Sdim llvm::dbgs() << "In " << KV.first() << "\n"; 166353358Sdim for (auto &KV2 : KV.second) 167353358Sdim llvm::dbgs() << " \"" << KV2.first() << "\" -> " << KV2.second << "\n"; 168353358Sdim } 169353358Sdim} 170353358Sdim 171353358SdimExpected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap, 172353358Sdim StringRef FileName, StringRef SectionName) { 173353358Sdim auto I = FileToSecIDMap.find(FileName); 174353358Sdim if (I == FileToSecIDMap.end()) 175353358Sdim return make_error<StringError>("No file named " + FileName, 176353358Sdim inconvertibleErrorCode()); 177353358Sdim auto &SectionIDs = I->second; 178353358Sdim auto J = SectionIDs.find(SectionName); 179353358Sdim if (J == SectionIDs.end()) 180353358Sdim return make_error<StringError>("No section named \"" + SectionName + 181353358Sdim "\" in file " + FileName, 182353358Sdim inconvertibleErrorCode()); 183353358Sdim return J->second; 184353358Sdim} 185353358Sdim 186221337Sdim// A trivial memory manager that doesn't do anything fancy, just uses the 187221337Sdim// support library allocation routines directly. 188221337Sdimclass TrivialMemoryManager : public RTDyldMemoryManager { 189221337Sdimpublic: 190353358Sdim struct SectionInfo { 191353358Sdim SectionInfo(StringRef Name, sys::MemoryBlock MB, unsigned SectionID) 192353358Sdim : Name(Name), MB(std::move(MB)), SectionID(SectionID) {} 193353358Sdim std::string Name; 194353358Sdim sys::MemoryBlock MB; 195353358Sdim unsigned SectionID = ~0U; 196353358Sdim }; 197221337Sdim 198353358Sdim SmallVector<SectionInfo, 16> FunctionMemory; 199353358Sdim SmallVector<SectionInfo, 16> DataMemory; 200353358Sdim 201234353Sdim uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 202276479Sdim unsigned SectionID, 203276479Sdim StringRef SectionName) override; 204234353Sdim uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 205261991Sdim unsigned SectionID, StringRef SectionName, 206276479Sdim bool IsReadOnly) override; 207234353Sdim 208353358Sdim /// If non null, records subsequent Name -> SectionID mappings. 209353358Sdim void setSectionIDsMap(SectionIDMap *SecIDMap) { 210353358Sdim this->SecIDMap = SecIDMap; 211353358Sdim } 212353358Sdim 213276479Sdim void *getPointerToNamedFunction(const std::string &Name, 214276479Sdim bool AbortOnFailure = true) override { 215276479Sdim return nullptr; 216234353Sdim } 217234353Sdim 218276479Sdim bool finalizeMemory(std::string *ErrMsg) override { return false; } 219249423Sdim 220288943Sdim void addDummySymbol(const std::string &Name, uint64_t Addr) { 221288943Sdim DummyExterns[Name] = Addr; 222288943Sdim } 223288943Sdim 224314564Sdim JITSymbol findSymbol(const std::string &Name) override { 225288943Sdim auto I = DummyExterns.find(Name); 226288943Sdim 227288943Sdim if (I != DummyExterns.end()) 228314564Sdim return JITSymbol(I->second, JITSymbolFlags::Exported); 229288943Sdim 230353358Sdim if (auto Sym = RTDyldMemoryManager::findSymbol(Name)) 231353358Sdim return Sym; 232353358Sdim else if (auto Err = Sym.takeError()) 233353358Sdim ExitOnErr(std::move(Err)); 234353358Sdim else 235353358Sdim ExitOnErr(make_error<StringError>("Could not find definition for \"" + 236353358Sdim Name + "\"", 237353358Sdim inconvertibleErrorCode())); 238353358Sdim llvm_unreachable("Should have returned or exited by now"); 239288943Sdim } 240288943Sdim 241288943Sdim void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 242288943Sdim size_t Size) override {} 243321369Sdim void deregisterEHFrames() override {} 244296417Sdim 245296417Sdim void preallocateSlab(uint64_t Size) { 246327952Sdim std::error_code EC; 247327952Sdim sys::MemoryBlock MB = 248327952Sdim sys::Memory::allocateMappedMemory(Size, nullptr, 249327952Sdim sys::Memory::MF_READ | 250327952Sdim sys::Memory::MF_WRITE, 251327952Sdim EC); 252296417Sdim if (!MB.base()) 253327952Sdim report_fatal_error("Can't allocate enough memory: " + EC.message()); 254296417Sdim 255296417Sdim PreallocSlab = MB; 256296417Sdim UsePreallocation = true; 257296417Sdim SlabSize = Size; 258296417Sdim } 259296417Sdim 260353358Sdim uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode, 261353358Sdim StringRef SectionName, unsigned SectionID) { 262309124Sdim Size = alignTo(Size, Alignment); 263296417Sdim if (CurrentSlabOffset + Size > SlabSize) 264296417Sdim report_fatal_error("Can't allocate enough memory. Tune --preallocate"); 265296417Sdim 266296417Sdim uintptr_t OldSlabOffset = CurrentSlabOffset; 267296417Sdim sys::MemoryBlock MB((void *)OldSlabOffset, Size); 268296417Sdim if (isCode) 269353358Sdim FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 270296417Sdim else 271353358Sdim DataMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 272296417Sdim CurrentSlabOffset += Size; 273296417Sdim return (uint8_t*)OldSlabOffset; 274296417Sdim } 275296417Sdim 276288943Sdimprivate: 277288943Sdim std::map<std::string, uint64_t> DummyExterns; 278296417Sdim sys::MemoryBlock PreallocSlab; 279296417Sdim bool UsePreallocation = false; 280296417Sdim uintptr_t SlabSize = 0; 281296417Sdim uintptr_t CurrentSlabOffset = 0; 282353358Sdim SectionIDMap *SecIDMap = nullptr; 283221337Sdim}; 284221337Sdim 285234353Sdimuint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 286234353Sdim unsigned Alignment, 287261991Sdim unsigned SectionID, 288261991Sdim StringRef SectionName) { 289296417Sdim if (PrintAllocationRequests) 290296417Sdim outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " 291296417Sdim << Alignment << ", SectionName = " << SectionName << ")\n"; 292296417Sdim 293353358Sdim if (SecIDMap) 294353358Sdim (*SecIDMap)[SectionName] = SectionID; 295353358Sdim 296296417Sdim if (UsePreallocation) 297353358Sdim return allocateFromSlab(Size, Alignment, true /* isCode */, 298353358Sdim SectionName, SectionID); 299296417Sdim 300327952Sdim std::error_code EC; 301327952Sdim sys::MemoryBlock MB = 302327952Sdim sys::Memory::allocateMappedMemory(Size, nullptr, 303327952Sdim sys::Memory::MF_READ | 304327952Sdim sys::Memory::MF_WRITE, 305327952Sdim EC); 306296417Sdim if (!MB.base()) 307327952Sdim report_fatal_error("MemoryManager allocation failed: " + EC.message()); 308353358Sdim FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 309239462Sdim return (uint8_t*)MB.base(); 310221337Sdim} 311221337Sdim 312234353Sdimuint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 313234353Sdim unsigned Alignment, 314249423Sdim unsigned SectionID, 315261991Sdim StringRef SectionName, 316249423Sdim bool IsReadOnly) { 317296417Sdim if (PrintAllocationRequests) 318296417Sdim outs() << "allocateDataSection(Size = " << Size << ", Alignment = " 319296417Sdim << Alignment << ", SectionName = " << SectionName << ")\n"; 320296417Sdim 321353358Sdim if (SecIDMap) 322353358Sdim (*SecIDMap)[SectionName] = SectionID; 323353358Sdim 324296417Sdim if (UsePreallocation) 325353358Sdim return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName, 326353358Sdim SectionID); 327296417Sdim 328327952Sdim std::error_code EC; 329327952Sdim sys::MemoryBlock MB = 330327952Sdim sys::Memory::allocateMappedMemory(Size, nullptr, 331327952Sdim sys::Memory::MF_READ | 332327952Sdim sys::Memory::MF_WRITE, 333327952Sdim EC); 334296417Sdim if (!MB.base()) 335327952Sdim report_fatal_error("MemoryManager allocation failed: " + EC.message()); 336353358Sdim DataMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 337239462Sdim return (uint8_t*)MB.base(); 338221337Sdim} 339221337Sdim 340221337Sdimstatic const char *ProgramName; 341221337Sdim 342309124Sdimstatic void ErrorAndExit(const Twine &Msg) { 343296417Sdim errs() << ProgramName << ": error: " << Msg << "\n"; 344309124Sdim exit(1); 345221337Sdim} 346221337Sdim 347276479Sdimstatic void loadDylibs() { 348276479Sdim for (const std::string &Dylib : Dylibs) { 349296417Sdim if (!sys::fs::is_regular_file(Dylib)) 350296417Sdim report_fatal_error("Dylib not found: '" + Dylib + "'."); 351296417Sdim std::string ErrMsg; 352296417Sdim if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg)) 353296417Sdim report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg); 354276479Sdim } 355276479Sdim} 356276479Sdim 357221337Sdim/* *** */ 358221337Sdim 359288943Sdimstatic int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { 360288943Sdim assert(LoadObjects || !UseDebugObj); 361288943Sdim 362276479Sdim // Load any dylibs requested on the command line. 363276479Sdim loadDylibs(); 364276479Sdim 365249423Sdim // If we don't have any input files, read from stdin. 366249423Sdim if (!InputFileList.size()) 367249423Sdim InputFileList.push_back("-"); 368296417Sdim for (auto &File : InputFileList) { 369249423Sdim // Instantiate a dynamic linker. 370261991Sdim TrivialMemoryManager MemMgr; 371288943Sdim RuntimeDyld Dyld(MemMgr, MemMgr); 372249423Sdim 373249423Sdim // Load the input memory buffer. 374249423Sdim 375276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 376296417Sdim MemoryBuffer::getFileOrSTDIN(File); 377276479Sdim if (std::error_code EC = InputBuffer.getError()) 378309124Sdim ErrorAndExit("unable to read input: '" + EC.message() + "'"); 379276479Sdim 380309124Sdim Expected<std::unique_ptr<ObjectFile>> MaybeObj( 381280031Sdim ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 382280031Sdim 383309124Sdim if (!MaybeObj) { 384309124Sdim std::string Buf; 385309124Sdim raw_string_ostream OS(Buf); 386344779Sdim logAllUnhandledErrors(MaybeObj.takeError(), OS); 387309124Sdim OS.flush(); 388309124Sdim ErrorAndExit("unable to create object file: '" + Buf + "'"); 389309124Sdim } 390280031Sdim 391280031Sdim ObjectFile &Obj = **MaybeObj; 392280031Sdim 393288943Sdim OwningBinary<ObjectFile> DebugObj; 394288943Sdim std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; 395288943Sdim ObjectFile *SymbolObj = &Obj; 396288943Sdim if (LoadObjects) { 397288943Sdim // Load the object file 398288943Sdim LoadedObjInfo = 399288943Sdim Dyld.loadObject(Obj); 400280031Sdim 401288943Sdim if (Dyld.hasError()) 402309124Sdim ErrorAndExit(Dyld.getErrorString()); 403249423Sdim 404288943Sdim // Resolve all the relocations we can. 405288943Sdim Dyld.resolveRelocations(); 406249423Sdim 407288943Sdim if (UseDebugObj) { 408288943Sdim DebugObj = LoadedObjInfo->getObjectForDebug(Obj); 409288943Sdim SymbolObj = DebugObj.getBinary(); 410296417Sdim LoadedObjInfo.reset(); 411288943Sdim } 412288943Sdim } 413280031Sdim 414327952Sdim std::unique_ptr<DIContext> Context = 415327952Sdim DWARFContext::create(*SymbolObj, LoadedObjInfo.get()); 416249423Sdim 417288943Sdim std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = 418288943Sdim object::computeSymbolSizes(*SymbolObj); 419288943Sdim 420249423Sdim // Use symbol info to iterate functions in the object. 421288943Sdim for (const auto &P : SymAddr) { 422288943Sdim object::SymbolRef Sym = P.first; 423309124Sdim Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); 424309124Sdim if (!TypeOrErr) { 425309124Sdim // TODO: Actually report errors helpfully. 426309124Sdim consumeError(TypeOrErr.takeError()); 427309124Sdim continue; 428309124Sdim } 429309124Sdim SymbolRef::Type Type = *TypeOrErr; 430309124Sdim if (Type == object::SymbolRef::ST_Function) { 431309124Sdim Expected<StringRef> Name = Sym.getName(); 432309124Sdim if (!Name) { 433309124Sdim // TODO: Actually report errors helpfully. 434309124Sdim consumeError(Name.takeError()); 435288943Sdim continue; 436309124Sdim } 437309124Sdim Expected<uint64_t> AddrOrErr = Sym.getAddress(); 438309124Sdim if (!AddrOrErr) { 439309124Sdim // TODO: Actually report errors helpfully. 440309124Sdim consumeError(AddrOrErr.takeError()); 441288943Sdim continue; 442309124Sdim } 443288943Sdim uint64_t Addr = *AddrOrErr; 444249423Sdim 445353358Sdim object::SectionedAddress Address; 446353358Sdim 447288943Sdim uint64_t Size = P.second; 448288943Sdim // If we're not using the debug object, compute the address of the 449288943Sdim // symbol in memory (rather than that in the unrelocated object file) 450288943Sdim // and use that to query the DWARFContext. 451288943Sdim if (!UseDebugObj && LoadObjects) { 452309124Sdim auto SecOrErr = Sym.getSection(); 453309124Sdim if (!SecOrErr) { 454309124Sdim // TODO: Actually report errors helpfully. 455309124Sdim consumeError(SecOrErr.takeError()); 456309124Sdim continue; 457309124Sdim } 458309124Sdim object::section_iterator Sec = *SecOrErr; 459353358Sdim Address.SectionIndex = Sec->getIndex(); 460288943Sdim uint64_t SectionLoadAddress = 461296417Sdim LoadedObjInfo->getSectionLoadAddress(*Sec); 462288943Sdim if (SectionLoadAddress != 0) 463288943Sdim Addr += SectionLoadAddress - Sec->getAddress(); 464353358Sdim } else if (auto SecOrErr = Sym.getSection()) 465353358Sdim Address.SectionIndex = SecOrErr.get()->getIndex(); 466249423Sdim 467288943Sdim outs() << "Function: " << *Name << ", Size = " << Size 468288943Sdim << ", Addr = " << Addr << "\n"; 469288943Sdim 470353358Sdim Address.Address = Addr; 471353358Sdim DILineInfoTable Lines = 472353358Sdim Context->getLineInfoForAddressRange(Address, Size); 473296417Sdim for (auto &D : Lines) { 474296417Sdim outs() << " Line info @ " << D.first - Addr << ": " 475296417Sdim << D.second.FileName << ", line:" << D.second.Line << "\n"; 476249423Sdim } 477249423Sdim } 478249423Sdim } 479249423Sdim } 480249423Sdim 481249423Sdim return 0; 482249423Sdim} 483249423Sdim 484296417Sdimstatic void doPreallocation(TrivialMemoryManager &MemMgr) { 485296417Sdim // Allocate a slab of memory upfront, if required. This is used if 486296417Sdim // we want to test small code models. 487296417Sdim if (static_cast<intptr_t>(PreallocMemory) < 0) 488296417Sdim report_fatal_error("Pre-allocated bytes of memory must be a positive integer."); 489296417Sdim 490296417Sdim // FIXME: Limit the amount of memory that can be preallocated? 491296417Sdim if (PreallocMemory != 0) 492296417Sdim MemMgr.preallocateSlab(PreallocMemory); 493296417Sdim} 494296417Sdim 495221337Sdimstatic int executeInput() { 496276479Sdim // Load any dylibs requested on the command line. 497276479Sdim loadDylibs(); 498276479Sdim 499221337Sdim // Instantiate a dynamic linker. 500261991Sdim TrivialMemoryManager MemMgr; 501296417Sdim doPreallocation(MemMgr); 502288943Sdim RuntimeDyld Dyld(MemMgr, MemMgr); 503221337Sdim 504221337Sdim // If we don't have any input files, read from stdin. 505221337Sdim if (!InputFileList.size()) 506221337Sdim InputFileList.push_back("-"); 507360784Sdim { 508360784Sdim TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr); 509360784Sdim for (auto &File : InputFileList) { 510360784Sdim // Load the input memory buffer. 511360784Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 512360784Sdim MemoryBuffer::getFileOrSTDIN(File); 513360784Sdim if (std::error_code EC = InputBuffer.getError()) 514360784Sdim ErrorAndExit("unable to read input: '" + EC.message() + "'"); 515360784Sdim Expected<std::unique_ptr<ObjectFile>> MaybeObj( 516360784Sdim ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 517280031Sdim 518360784Sdim if (!MaybeObj) { 519360784Sdim std::string Buf; 520360784Sdim raw_string_ostream OS(Buf); 521360784Sdim logAllUnhandledErrors(MaybeObj.takeError(), OS); 522360784Sdim OS.flush(); 523360784Sdim ErrorAndExit("unable to create object file: '" + Buf + "'"); 524360784Sdim } 525280031Sdim 526360784Sdim ObjectFile &Obj = **MaybeObj; 527280031Sdim 528360784Sdim // Load the object file 529360784Sdim Dyld.loadObject(Obj); 530360784Sdim if (Dyld.hasError()) { 531360784Sdim ErrorAndExit(Dyld.getErrorString()); 532360784Sdim } 533221337Sdim } 534221337Sdim } 535221337Sdim 536360784Sdim { 537360784Sdim TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr); 538360784Sdim // Resove all the relocations we can. 539360784Sdim // FIXME: Error out if there are unresolved relocations. 540360784Sdim Dyld.resolveRelocations(); 541360784Sdim } 542221337Sdim 543221337Sdim // Get the address of the entry point (_main by default). 544288943Sdim void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); 545276479Sdim if (!MainAddress) 546309124Sdim ErrorAndExit("no definition for '" + EntryPoint + "'"); 547221337Sdim 548221337Sdim // Invalidate the instruction cache for each loaded function. 549296417Sdim for (auto &FM : MemMgr.FunctionMemory) { 550296417Sdim 551353358Sdim auto &FM_MB = FM.MB; 552353358Sdim 553221337Sdim // Make sure the memory is executable. 554296417Sdim // setExecutable will call InvalidateInstructionCache. 555353358Sdim if (auto EC = sys::Memory::protectMappedMemory(FM_MB, 556327952Sdim sys::Memory::MF_READ | 557327952Sdim sys::Memory::MF_EXEC)) 558327952Sdim ErrorAndExit("unable to mark function executable: '" + EC.message() + 559327952Sdim "'"); 560221337Sdim } 561221337Sdim 562221337Sdim // Dispatch to _main(). 563221337Sdim errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; 564221337Sdim 565221337Sdim int (*Main)(int, const char**) = 566221337Sdim (int(*)(int,const char**)) uintptr_t(MainAddress); 567353358Sdim std::vector<const char *> Argv; 568221337Sdim // Use the name of the first input object module as argv[0] for the target. 569353358Sdim Argv.push_back(InputFileList[0].data()); 570353358Sdim for (auto &Arg : InputArgv) 571353358Sdim Argv.push_back(Arg.data()); 572353358Sdim Argv.push_back(nullptr); 573360784Sdim int Result = 0; 574360784Sdim { 575360784Sdim TimeRegion TR(Timers ? &Timers->RunTimer : nullptr); 576360784Sdim Result = Main(Argv.size() - 1, Argv.data()); 577360784Sdim } 578360784Sdim 579360784Sdim return Result; 580221337Sdim} 581221337Sdim 582276479Sdimstatic int checkAllExpressions(RuntimeDyldChecker &Checker) { 583276479Sdim for (const auto& CheckerFileName : CheckFiles) { 584276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = 585276479Sdim MemoryBuffer::getFileOrSTDIN(CheckerFileName); 586276479Sdim if (std::error_code EC = CheckerFileBuf.getError()) 587309124Sdim ErrorAndExit("unable to read input '" + CheckerFileName + "': " + 588276479Sdim EC.message()); 589276479Sdim 590276479Sdim if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", 591276479Sdim CheckerFileBuf.get().get())) 592309124Sdim ErrorAndExit("some checks in '" + CheckerFileName + "' failed"); 593276479Sdim } 594276479Sdim return 0; 595276479Sdim} 596276479Sdim 597353358Sdimvoid applySpecificSectionMappings(RuntimeDyld &Dyld, 598353358Sdim const FileToSectionIDMap &FileToSecIDMap) { 599280031Sdim 600280031Sdim for (StringRef Mapping : SpecificSectionMappings) { 601280031Sdim size_t EqualsIdx = Mapping.find_first_of("="); 602288943Sdim std::string SectionIDStr = Mapping.substr(0, EqualsIdx); 603280031Sdim size_t ComaIdx = Mapping.find_first_of(","); 604280031Sdim 605296417Sdim if (ComaIdx == StringRef::npos) 606296417Sdim report_fatal_error("Invalid section specification '" + Mapping + 607296417Sdim "'. Should be '<file name>,<section name>=<addr>'"); 608280031Sdim 609288943Sdim std::string FileName = SectionIDStr.substr(0, ComaIdx); 610288943Sdim std::string SectionName = SectionIDStr.substr(ComaIdx + 1); 611353358Sdim unsigned SectionID = 612353358Sdim ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName)); 613280031Sdim 614353358Sdim auto* OldAddr = Dyld.getSectionContent(SectionID).data(); 615288943Sdim std::string NewAddrStr = Mapping.substr(EqualsIdx + 1); 616280031Sdim uint64_t NewAddr; 617280031Sdim 618296417Sdim if (StringRef(NewAddrStr).getAsInteger(0, NewAddr)) 619296417Sdim report_fatal_error("Invalid section address in mapping '" + Mapping + 620296417Sdim "'."); 621280031Sdim 622353358Sdim Dyld.mapSectionAddress(OldAddr, NewAddr); 623280031Sdim } 624280031Sdim} 625280031Sdim 626280031Sdim// Scatter sections in all directions! 627280031Sdim// Remaps section addresses for -verify mode. The following command line options 628280031Sdim// can be used to customize the layout of the memory within the phony target's 629280031Sdim// address space: 630314564Sdim// -target-addr-start <s> -- Specify where the phony target address range starts. 631280031Sdim// -target-addr-end <e> -- Specify where the phony target address range ends. 632280031Sdim// -target-section-sep <d> -- Specify how big a gap should be left between the 633280031Sdim// end of one section and the start of the next. 634280031Sdim// Defaults to zero. Set to something big 635280031Sdim// (e.g. 1 << 32) to stress-test stubs, GOTs, etc. 636280031Sdim// 637288943Sdimstatic void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, 638353358Sdim RuntimeDyld &Dyld, 639353358Sdim TrivialMemoryManager &MemMgr) { 640280031Sdim 641280031Sdim // Set up a work list (section addr/size pairs). 642353358Sdim typedef std::list<const TrivialMemoryManager::SectionInfo*> WorklistT; 643280031Sdim WorklistT Worklist; 644280031Sdim 645280031Sdim for (const auto& CodeSection : MemMgr.FunctionMemory) 646353358Sdim Worklist.push_back(&CodeSection); 647280031Sdim for (const auto& DataSection : MemMgr.DataMemory) 648353358Sdim Worklist.push_back(&DataSection); 649280031Sdim 650280031Sdim // Keep an "already allocated" mapping of section target addresses to sizes. 651280031Sdim // Sections whose address mappings aren't specified on the command line will 652280031Sdim // allocated around the explicitly mapped sections while maintaining the 653280031Sdim // minimum separation. 654280031Sdim std::map<uint64_t, uint64_t> AlreadyAllocated; 655280031Sdim 656321369Sdim // Move the previously applied mappings (whether explicitly specified on the 657321369Sdim // command line, or implicitly set by RuntimeDyld) into the already-allocated 658321369Sdim // map. 659280031Sdim for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); 660280031Sdim I != E;) { 661280031Sdim WorklistT::iterator Tmp = I; 662280031Sdim ++I; 663280031Sdim 664353358Sdim auto LoadAddr = Dyld.getSectionLoadAddress((*Tmp)->SectionID); 665353358Sdim 666353358Sdim if (LoadAddr != static_cast<uint64_t>( 667353358Sdim reinterpret_cast<uintptr_t>((*Tmp)->MB.base()))) { 668344779Sdim // A section will have a LoadAddr of 0 if it wasn't loaded for whatever 669344779Sdim // reason (e.g. zero byte COFF sections). Don't include those sections in 670344779Sdim // the allocation map. 671353358Sdim if (LoadAddr != 0) 672353358Sdim AlreadyAllocated[LoadAddr] = (*Tmp)->MB.allocatedSize(); 673280031Sdim Worklist.erase(Tmp); 674280031Sdim } 675280031Sdim } 676280031Sdim 677280031Sdim // If the -target-addr-end option wasn't explicitly passed, then set it to a 678280031Sdim // sensible default based on the target triple. 679280031Sdim if (TargetAddrEnd.getNumOccurrences() == 0) { 680280031Sdim if (TargetTriple.isArch16Bit()) 681280031Sdim TargetAddrEnd = (1ULL << 16) - 1; 682280031Sdim else if (TargetTriple.isArch32Bit()) 683280031Sdim TargetAddrEnd = (1ULL << 32) - 1; 684280031Sdim // TargetAddrEnd already has a sensible default for 64-bit systems, so 685280031Sdim // there's nothing to do in the 64-bit case. 686280031Sdim } 687280031Sdim 688280031Sdim // Process any elements remaining in the worklist. 689280031Sdim while (!Worklist.empty()) { 690353358Sdim auto *CurEntry = Worklist.front(); 691280031Sdim Worklist.pop_front(); 692280031Sdim 693280031Sdim uint64_t NextSectionAddr = TargetAddrStart; 694280031Sdim 695280031Sdim for (const auto &Alloc : AlreadyAllocated) 696353358Sdim if (NextSectionAddr + CurEntry->MB.allocatedSize() + TargetSectionSep <= 697353358Sdim Alloc.first) 698280031Sdim break; 699280031Sdim else 700280031Sdim NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; 701280031Sdim 702353358Sdim Dyld.mapSectionAddress(CurEntry->MB.base(), NextSectionAddr); 703353358Sdim AlreadyAllocated[NextSectionAddr] = CurEntry->MB.allocatedSize(); 704280031Sdim } 705280031Sdim 706288943Sdim // Add dummy symbols to the memory manager. 707288943Sdim for (const auto &Mapping : DummySymbolMappings) { 708314564Sdim size_t EqualsIdx = Mapping.find_first_of('='); 709288943Sdim 710296417Sdim if (EqualsIdx == StringRef::npos) 711296417Sdim report_fatal_error("Invalid dummy symbol specification '" + Mapping + 712296417Sdim "'. Should be '<symbol name>=<addr>'"); 713288943Sdim 714288943Sdim std::string Symbol = Mapping.substr(0, EqualsIdx); 715288943Sdim std::string AddrStr = Mapping.substr(EqualsIdx + 1); 716288943Sdim 717288943Sdim uint64_t Addr; 718296417Sdim if (StringRef(AddrStr).getAsInteger(0, Addr)) 719296417Sdim report_fatal_error("Invalid symbol mapping '" + Mapping + "'."); 720288943Sdim 721288943Sdim MemMgr.addDummySymbol(Symbol, Addr); 722288943Sdim } 723280031Sdim} 724280031Sdim 725280031Sdim// Load and link the objects specified on the command line, but do not execute 726280031Sdim// anything. Instead, attach a RuntimeDyldChecker instance and call it to 727280031Sdim// verify the correctness of the linked memory. 728276479Sdimstatic int linkAndVerify() { 729276479Sdim 730276479Sdim // Check for missing triple. 731296417Sdim if (TripleName == "") 732309124Sdim ErrorAndExit("-triple required when running in -verify mode."); 733276479Sdim 734276479Sdim // Look up the target and build the disassembler. 735276479Sdim Triple TheTriple(Triple::normalize(TripleName)); 736276479Sdim std::string ErrorStr; 737276479Sdim const Target *TheTarget = 738276479Sdim TargetRegistry::lookupTarget("", TheTriple, ErrorStr); 739296417Sdim if (!TheTarget) 740309124Sdim ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr); 741296417Sdim 742276479Sdim TripleName = TheTriple.getTriple(); 743276479Sdim 744276479Sdim std::unique_ptr<MCSubtargetInfo> STI( 745288943Sdim TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); 746296417Sdim if (!STI) 747309124Sdim ErrorAndExit("Unable to create subtarget info!"); 748276479Sdim 749276479Sdim std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 750296417Sdim if (!MRI) 751309124Sdim ErrorAndExit("Unable to create target register info!"); 752276479Sdim 753360784Sdim MCTargetOptions MCOptions; 754360784Sdim std::unique_ptr<MCAsmInfo> MAI( 755360784Sdim TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 756296417Sdim if (!MAI) 757309124Sdim ErrorAndExit("Unable to create target asm info!"); 758276479Sdim 759276479Sdim MCContext Ctx(MAI.get(), MRI.get(), nullptr); 760276479Sdim 761276479Sdim std::unique_ptr<MCDisassembler> Disassembler( 762276479Sdim TheTarget->createMCDisassembler(*STI, Ctx)); 763296417Sdim if (!Disassembler) 764309124Sdim ErrorAndExit("Unable to create disassembler!"); 765276479Sdim 766276479Sdim std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 767276479Sdim 768276479Sdim std::unique_ptr<MCInstPrinter> InstPrinter( 769288943Sdim TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); 770276479Sdim 771276479Sdim // Load any dylibs requested on the command line. 772276479Sdim loadDylibs(); 773276479Sdim 774276479Sdim // Instantiate a dynamic linker. 775276479Sdim TrivialMemoryManager MemMgr; 776296417Sdim doPreallocation(MemMgr); 777353358Sdim 778353358Sdim struct StubID { 779353358Sdim unsigned SectionID; 780353358Sdim uint32_t Offset; 781353358Sdim }; 782353358Sdim using StubInfos = StringMap<StubID>; 783353358Sdim using StubContainers = StringMap<StubInfos>; 784353358Sdim 785353358Sdim StubContainers StubMap; 786288943Sdim RuntimeDyld Dyld(MemMgr, MemMgr); 787280031Sdim Dyld.setProcessAllSections(true); 788276479Sdim 789353358Sdim Dyld.setNotifyStubEmitted([&StubMap](StringRef FilePath, 790353358Sdim StringRef SectionName, 791353358Sdim StringRef SymbolName, unsigned SectionID, 792353358Sdim uint32_t StubOffset) { 793353358Sdim std::string ContainerName = 794353358Sdim (sys::path::filename(FilePath) + "/" + SectionName).str(); 795353358Sdim StubMap[ContainerName][SymbolName] = {SectionID, StubOffset}; 796353358Sdim }); 797353358Sdim 798353358Sdim auto GetSymbolInfo = 799353358Sdim [&Dyld, &MemMgr]( 800353358Sdim StringRef Symbol) -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 801353358Sdim RuntimeDyldChecker::MemoryRegionInfo SymInfo; 802353358Sdim 803353358Sdim // First get the target address. 804353358Sdim if (auto InternalSymbol = Dyld.getSymbol(Symbol)) 805353358Sdim SymInfo.setTargetAddress(InternalSymbol.getAddress()); 806353358Sdim else { 807353358Sdim // Symbol not found in RuntimeDyld. Fall back to external lookup. 808353358Sdim#ifdef _MSC_VER 809353358Sdim using ExpectedLookupResult = 810353358Sdim MSVCPExpected<JITSymbolResolver::LookupResult>; 811353358Sdim#else 812353358Sdim using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>; 813353358Sdim#endif 814353358Sdim 815353358Sdim auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>(); 816353358Sdim auto ResultF = ResultP->get_future(); 817353358Sdim 818353358Sdim MemMgr.lookup(JITSymbolResolver::LookupSet({Symbol}), 819353358Sdim [=](Expected<JITSymbolResolver::LookupResult> Result) { 820353358Sdim ResultP->set_value(std::move(Result)); 821353358Sdim }); 822353358Sdim 823353358Sdim auto Result = ResultF.get(); 824353358Sdim if (!Result) 825353358Sdim return Result.takeError(); 826353358Sdim 827353358Sdim auto I = Result->find(Symbol); 828353358Sdim assert(I != Result->end() && 829353358Sdim "Expected symbol address if no error occurred"); 830353358Sdim SymInfo.setTargetAddress(I->second.getAddress()); 831353358Sdim } 832353358Sdim 833353358Sdim // Now find the symbol content if possible (otherwise leave content as a 834353358Sdim // default-constructed StringRef). 835353358Sdim if (auto *SymAddr = Dyld.getSymbolLocalAddress(Symbol)) { 836353358Sdim unsigned SectionID = Dyld.getSymbolSectionID(Symbol); 837353358Sdim if (SectionID != ~0U) { 838353358Sdim char *CSymAddr = static_cast<char *>(SymAddr); 839353358Sdim StringRef SecContent = Dyld.getSectionContent(SectionID); 840353358Sdim uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data()); 841353358Sdim SymInfo.setContent(StringRef(CSymAddr, SymSize)); 842353358Sdim } 843353358Sdim } 844353358Sdim return SymInfo; 845353358Sdim }; 846353358Sdim 847353358Sdim auto IsSymbolValid = [&Dyld, GetSymbolInfo](StringRef Symbol) { 848353358Sdim if (Dyld.getSymbol(Symbol)) 849353358Sdim return true; 850353358Sdim auto SymInfo = GetSymbolInfo(Symbol); 851353358Sdim if (!SymInfo) { 852353358Sdim logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 853353358Sdim return false; 854353358Sdim } 855353358Sdim return SymInfo->getTargetAddress() != 0; 856353358Sdim }; 857353358Sdim 858353358Sdim FileToSectionIDMap FileToSecIDMap; 859353358Sdim 860353358Sdim auto GetSectionInfo = [&Dyld, &FileToSecIDMap](StringRef FileName, 861353358Sdim StringRef SectionName) 862353358Sdim -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 863353358Sdim auto SectionID = getSectionId(FileToSecIDMap, FileName, SectionName); 864353358Sdim if (!SectionID) 865353358Sdim return SectionID.takeError(); 866353358Sdim RuntimeDyldChecker::MemoryRegionInfo SecInfo; 867353358Sdim SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID)); 868353358Sdim SecInfo.setContent(Dyld.getSectionContent(*SectionID)); 869353358Sdim return SecInfo; 870353358Sdim }; 871353358Sdim 872353358Sdim auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer, 873353358Sdim StringRef SymbolName) 874353358Sdim -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 875353358Sdim if (!StubMap.count(StubContainer)) 876353358Sdim return make_error<StringError>("Stub container not found: " + 877353358Sdim StubContainer, 878353358Sdim inconvertibleErrorCode()); 879353358Sdim if (!StubMap[StubContainer].count(SymbolName)) 880353358Sdim return make_error<StringError>("Symbol name " + SymbolName + 881353358Sdim " in stub container " + StubContainer, 882353358Sdim inconvertibleErrorCode()); 883353358Sdim auto &SI = StubMap[StubContainer][SymbolName]; 884353358Sdim RuntimeDyldChecker::MemoryRegionInfo StubMemInfo; 885353358Sdim StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) + 886353358Sdim SI.Offset); 887353358Sdim StubMemInfo.setContent( 888353358Sdim Dyld.getSectionContent(SI.SectionID).substr(SI.Offset)); 889353358Sdim return StubMemInfo; 890353358Sdim }; 891353358Sdim 892353358Sdim // We will initialize this below once we have the first object file and can 893353358Sdim // know the endianness. 894353358Sdim std::unique_ptr<RuntimeDyldChecker> Checker; 895353358Sdim 896276479Sdim // If we don't have any input files, read from stdin. 897276479Sdim if (!InputFileList.size()) 898276479Sdim InputFileList.push_back("-"); 899353358Sdim for (auto &InputFile : InputFileList) { 900276479Sdim // Load the input memory buffer. 901276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 902353358Sdim MemoryBuffer::getFileOrSTDIN(InputFile); 903280031Sdim 904276479Sdim if (std::error_code EC = InputBuffer.getError()) 905309124Sdim ErrorAndExit("unable to read input: '" + EC.message() + "'"); 906276479Sdim 907309124Sdim Expected<std::unique_ptr<ObjectFile>> MaybeObj( 908280031Sdim ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 909280031Sdim 910309124Sdim if (!MaybeObj) { 911309124Sdim std::string Buf; 912309124Sdim raw_string_ostream OS(Buf); 913344779Sdim logAllUnhandledErrors(MaybeObj.takeError(), OS); 914309124Sdim OS.flush(); 915309124Sdim ErrorAndExit("unable to create object file: '" + Buf + "'"); 916309124Sdim } 917280031Sdim 918280031Sdim ObjectFile &Obj = **MaybeObj; 919280031Sdim 920353358Sdim if (!Checker) 921360784Sdim Checker = std::make_unique<RuntimeDyldChecker>( 922353358Sdim IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, 923353358Sdim GetStubInfo, Obj.isLittleEndian() ? support::little : support::big, 924353358Sdim Disassembler.get(), InstPrinter.get(), dbgs()); 925353358Sdim 926353358Sdim auto FileName = sys::path::filename(InputFile); 927353358Sdim MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]); 928353358Sdim 929276479Sdim // Load the object file 930280031Sdim Dyld.loadObject(Obj); 931280031Sdim if (Dyld.hasError()) { 932309124Sdim ErrorAndExit(Dyld.getErrorString()); 933276479Sdim } 934276479Sdim } 935276479Sdim 936288943Sdim // Re-map the section addresses into the phony target address space and add 937288943Sdim // dummy symbols. 938353358Sdim applySpecificSectionMappings(Dyld, FileToSecIDMap); 939353358Sdim remapSectionsAndSymbols(TheTriple, Dyld, MemMgr); 940280031Sdim 941276479Sdim // Resolve all the relocations we can. 942276479Sdim Dyld.resolveRelocations(); 943276479Sdim 944280031Sdim // Register EH frames. 945280031Sdim Dyld.registerEHFrames(); 946280031Sdim 947353358Sdim int ErrorCode = checkAllExpressions(*Checker); 948296417Sdim if (Dyld.hasError()) 949309124Sdim ErrorAndExit("RTDyld reported an error applying relocations:\n " + 950296417Sdim Dyld.getErrorString()); 951280031Sdim 952280031Sdim return ErrorCode; 953276479Sdim} 954276479Sdim 955221337Sdimint main(int argc, char **argv) { 956341825Sdim InitLLVM X(argc, argv); 957221337Sdim ProgramName = argv[0]; 958221337Sdim 959276479Sdim llvm::InitializeAllTargetInfos(); 960276479Sdim llvm::InitializeAllTargetMCs(); 961276479Sdim llvm::InitializeAllDisassemblers(); 962276479Sdim 963221337Sdim cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); 964221337Sdim 965353358Sdim ExitOnErr.setBanner(std::string(argv[0]) + ": "); 966353358Sdim 967360784Sdim Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr; 968360784Sdim 969360784Sdim int Result; 970221337Sdim switch (Action) { 971221337Sdim case AC_Execute: 972360784Sdim Result = executeInput(); 973360784Sdim break; 974288943Sdim case AC_PrintDebugLineInfo: 975360784Sdim Result = 976360784Sdim printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ true); 977360784Sdim break; 978249423Sdim case AC_PrintLineInfo: 979360784Sdim Result = 980360784Sdim printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ false); 981360784Sdim break; 982288943Sdim case AC_PrintObjectLineInfo: 983360784Sdim Result = 984360784Sdim printLineInfoForInput(/* LoadObjects */ false, /* UseDebugObj */ false); 985360784Sdim break; 986276479Sdim case AC_Verify: 987360784Sdim Result = linkAndVerify(); 988360784Sdim break; 989221337Sdim } 990360784Sdim return Result; 991221337Sdim} 992