llvm-rtdyld.cpp revision 327952
1221337Sdim//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===// 2221337Sdim// 3221337Sdim// The LLVM Compiler Infrastructure 4221337Sdim// 5221337Sdim// This file is distributed under the University of Illinois Open Source 6221337Sdim// License. See LICENSE.TXT for details. 7221337Sdim// 8221337Sdim//===----------------------------------------------------------------------===// 9221337Sdim// 10221337Sdim// This is a testing tool for use with the MC-JIT LLVM components. 11221337Sdim// 12221337Sdim//===----------------------------------------------------------------------===// 13221337Sdim 14221337Sdim#include "llvm/ADT/StringMap.h" 15249423Sdim#include "llvm/DebugInfo/DIContext.h" 16288943Sdim#include "llvm/DebugInfo/DWARF/DWARFContext.h" 17288943Sdim#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 18221337Sdim#include "llvm/ExecutionEngine/RuntimeDyld.h" 19276479Sdim#include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 20276479Sdim#include "llvm/MC/MCAsmInfo.h" 21276479Sdim#include "llvm/MC/MCContext.h" 22309124Sdim#include "llvm/MC/MCDisassembler/MCDisassembler.h" 23280031Sdim#include "llvm/MC/MCInstPrinter.h" 24276479Sdim#include "llvm/MC/MCInstrInfo.h" 25276479Sdim#include "llvm/MC/MCRegisterInfo.h" 26288943Sdim#include "llvm/MC/MCSubtargetInfo.h" 27288943Sdim#include "llvm/Object/SymbolSize.h" 28221337Sdim#include "llvm/Support/CommandLine.h" 29276479Sdim#include "llvm/Support/DynamicLibrary.h" 30221337Sdim#include "llvm/Support/ManagedStatic.h" 31221337Sdim#include "llvm/Support/Memory.h" 32221337Sdim#include "llvm/Support/MemoryBuffer.h" 33261991Sdim#include "llvm/Support/PrettyStackTrace.h" 34261991Sdim#include "llvm/Support/Signals.h" 35276479Sdim#include "llvm/Support/TargetRegistry.h" 36276479Sdim#include "llvm/Support/TargetSelect.h" 37280031Sdim#include "llvm/Support/raw_ostream.h" 38280031Sdim#include <list> 39276479Sdim 40221337Sdimusing namespace llvm; 41221337Sdimusing namespace llvm::object; 42221337Sdim 43221337Sdimstatic cl::list<std::string> 44221337SdimInputFileList(cl::Positional, cl::ZeroOrMore, 45221337Sdim cl::desc("<input file>")); 46221337Sdim 47221337Sdimenum ActionType { 48249423Sdim AC_Execute, 49288943Sdim AC_PrintObjectLineInfo, 50276479Sdim AC_PrintLineInfo, 51288943Sdim AC_PrintDebugLineInfo, 52276479Sdim AC_Verify 53221337Sdim}; 54221337Sdim 55221337Sdimstatic cl::opt<ActionType> 56221337SdimAction(cl::desc("Action to perform:"), 57221337Sdim cl::init(AC_Execute), 58221337Sdim cl::values(clEnumValN(AC_Execute, "execute", 59221337Sdim "Load, link, and execute the inputs."), 60249423Sdim clEnumValN(AC_PrintLineInfo, "printline", 61249423Sdim "Load, link, and print line information for each function."), 62288943Sdim clEnumValN(AC_PrintDebugLineInfo, "printdebugline", 63288943Sdim "Load, link, and print line information for each function using the debug object"), 64288943Sdim clEnumValN(AC_PrintObjectLineInfo, "printobjline", 65288943Sdim "Like -printlineinfo but does not load the object first"), 66276479Sdim clEnumValN(AC_Verify, "verify", 67314564Sdim "Load, link and verify the resulting memory image."))); 68221337Sdim 69221337Sdimstatic cl::opt<std::string> 70221337SdimEntryPoint("entry", 71221337Sdim cl::desc("Function to call as entry point."), 72221337Sdim cl::init("_main")); 73221337Sdim 74276479Sdimstatic cl::list<std::string> 75276479SdimDylibs("dylib", 76276479Sdim cl::desc("Add library."), 77276479Sdim cl::ZeroOrMore); 78276479Sdim 79276479Sdimstatic cl::opt<std::string> 80276479SdimTripleName("triple", cl::desc("Target triple for disassembler")); 81276479Sdim 82288943Sdimstatic cl::opt<std::string> 83288943SdimMCPU("mcpu", 84288943Sdim cl::desc("Target a specific cpu type (-mcpu=help for details)"), 85288943Sdim cl::value_desc("cpu-name"), 86288943Sdim cl::init("")); 87288943Sdim 88276479Sdimstatic cl::list<std::string> 89276479SdimCheckFiles("check", 90276479Sdim cl::desc("File containing RuntimeDyld verifier checks."), 91276479Sdim cl::ZeroOrMore); 92276479Sdim 93280031Sdimstatic cl::opt<uint64_t> 94296417SdimPreallocMemory("preallocate", 95296417Sdim cl::desc("Allocate memory upfront rather than on-demand"), 96296417Sdim cl::init(0)); 97296417Sdim 98296417Sdimstatic cl::opt<uint64_t> 99280031SdimTargetAddrStart("target-addr-start", 100280031Sdim cl::desc("For -verify only: start of phony target address " 101280031Sdim "range."), 102280031Sdim cl::init(4096), // Start at "page 1" - no allocating at "null". 103280031Sdim cl::Hidden); 104280031Sdim 105280031Sdimstatic cl::opt<uint64_t> 106280031SdimTargetAddrEnd("target-addr-end", 107280031Sdim cl::desc("For -verify only: end of phony target address range."), 108280031Sdim cl::init(~0ULL), 109280031Sdim cl::Hidden); 110280031Sdim 111280031Sdimstatic cl::opt<uint64_t> 112280031SdimTargetSectionSep("target-section-sep", 113280031Sdim cl::desc("For -verify only: Separation between sections in " 114280031Sdim "phony target address space."), 115280031Sdim cl::init(0), 116280031Sdim cl::Hidden); 117280031Sdim 118280031Sdimstatic cl::list<std::string> 119280031SdimSpecificSectionMappings("map-section", 120288943Sdim cl::desc("For -verify only: Map a section to a " 121288943Sdim "specific address."), 122288943Sdim cl::ZeroOrMore, 123288943Sdim cl::Hidden); 124280031Sdim 125288943Sdimstatic cl::list<std::string> 126288943SdimDummySymbolMappings("dummy-extern", 127288943Sdim cl::desc("For -verify only: Inject a symbol into the extern " 128288943Sdim "symbol table."), 129288943Sdim cl::ZeroOrMore, 130288943Sdim cl::Hidden); 131288943Sdim 132296417Sdimstatic cl::opt<bool> 133296417SdimPrintAllocationRequests("print-alloc-requests", 134296417Sdim cl::desc("Print allocation requests made to the memory " 135296417Sdim "manager by RuntimeDyld"), 136296417Sdim cl::Hidden); 137296417Sdim 138221337Sdim/* *** */ 139221337Sdim 140221337Sdim// A trivial memory manager that doesn't do anything fancy, just uses the 141221337Sdim// support library allocation routines directly. 142221337Sdimclass TrivialMemoryManager : public RTDyldMemoryManager { 143221337Sdimpublic: 144221337Sdim SmallVector<sys::MemoryBlock, 16> FunctionMemory; 145234353Sdim SmallVector<sys::MemoryBlock, 16> DataMemory; 146221337Sdim 147234353Sdim uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 148276479Sdim unsigned SectionID, 149276479Sdim StringRef SectionName) override; 150234353Sdim uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 151261991Sdim unsigned SectionID, StringRef SectionName, 152276479Sdim bool IsReadOnly) override; 153234353Sdim 154276479Sdim void *getPointerToNamedFunction(const std::string &Name, 155276479Sdim bool AbortOnFailure = true) override { 156276479Sdim return nullptr; 157234353Sdim } 158234353Sdim 159276479Sdim bool finalizeMemory(std::string *ErrMsg) override { return false; } 160249423Sdim 161288943Sdim void addDummySymbol(const std::string &Name, uint64_t Addr) { 162288943Sdim DummyExterns[Name] = Addr; 163288943Sdim } 164288943Sdim 165314564Sdim JITSymbol findSymbol(const std::string &Name) override { 166288943Sdim auto I = DummyExterns.find(Name); 167288943Sdim 168288943Sdim if (I != DummyExterns.end()) 169314564Sdim return JITSymbol(I->second, JITSymbolFlags::Exported); 170288943Sdim 171288943Sdim return RTDyldMemoryManager::findSymbol(Name); 172288943Sdim } 173288943Sdim 174288943Sdim void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 175288943Sdim size_t Size) override {} 176321369Sdim void deregisterEHFrames() override {} 177296417Sdim 178296417Sdim void preallocateSlab(uint64_t Size) { 179327952Sdim std::error_code EC; 180327952Sdim sys::MemoryBlock MB = 181327952Sdim sys::Memory::allocateMappedMemory(Size, nullptr, 182327952Sdim sys::Memory::MF_READ | 183327952Sdim sys::Memory::MF_WRITE, 184327952Sdim EC); 185296417Sdim if (!MB.base()) 186327952Sdim report_fatal_error("Can't allocate enough memory: " + EC.message()); 187296417Sdim 188296417Sdim PreallocSlab = MB; 189296417Sdim UsePreallocation = true; 190296417Sdim SlabSize = Size; 191296417Sdim } 192296417Sdim 193296417Sdim uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode) { 194309124Sdim Size = alignTo(Size, Alignment); 195296417Sdim if (CurrentSlabOffset + Size > SlabSize) 196296417Sdim report_fatal_error("Can't allocate enough memory. Tune --preallocate"); 197296417Sdim 198296417Sdim uintptr_t OldSlabOffset = CurrentSlabOffset; 199296417Sdim sys::MemoryBlock MB((void *)OldSlabOffset, Size); 200296417Sdim if (isCode) 201296417Sdim FunctionMemory.push_back(MB); 202296417Sdim else 203296417Sdim DataMemory.push_back(MB); 204296417Sdim CurrentSlabOffset += Size; 205296417Sdim return (uint8_t*)OldSlabOffset; 206296417Sdim } 207296417Sdim 208288943Sdimprivate: 209288943Sdim std::map<std::string, uint64_t> DummyExterns; 210296417Sdim sys::MemoryBlock PreallocSlab; 211296417Sdim bool UsePreallocation = false; 212296417Sdim uintptr_t SlabSize = 0; 213296417Sdim uintptr_t CurrentSlabOffset = 0; 214221337Sdim}; 215221337Sdim 216234353Sdimuint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 217234353Sdim unsigned Alignment, 218261991Sdim unsigned SectionID, 219261991Sdim StringRef SectionName) { 220296417Sdim if (PrintAllocationRequests) 221296417Sdim outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " 222296417Sdim << Alignment << ", SectionName = " << SectionName << ")\n"; 223296417Sdim 224296417Sdim if (UsePreallocation) 225296417Sdim return allocateFromSlab(Size, Alignment, true /* isCode */); 226296417Sdim 227327952Sdim std::error_code EC; 228327952Sdim sys::MemoryBlock MB = 229327952Sdim sys::Memory::allocateMappedMemory(Size, nullptr, 230327952Sdim sys::Memory::MF_READ | 231327952Sdim sys::Memory::MF_WRITE, 232327952Sdim EC); 233296417Sdim if (!MB.base()) 234327952Sdim report_fatal_error("MemoryManager allocation failed: " + EC.message()); 235239462Sdim FunctionMemory.push_back(MB); 236239462Sdim return (uint8_t*)MB.base(); 237221337Sdim} 238221337Sdim 239234353Sdimuint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 240234353Sdim unsigned Alignment, 241249423Sdim unsigned SectionID, 242261991Sdim StringRef SectionName, 243249423Sdim bool IsReadOnly) { 244296417Sdim if (PrintAllocationRequests) 245296417Sdim outs() << "allocateDataSection(Size = " << Size << ", Alignment = " 246296417Sdim << Alignment << ", SectionName = " << SectionName << ")\n"; 247296417Sdim 248296417Sdim if (UsePreallocation) 249296417Sdim return allocateFromSlab(Size, Alignment, false /* isCode */); 250296417Sdim 251327952Sdim std::error_code EC; 252327952Sdim sys::MemoryBlock MB = 253327952Sdim sys::Memory::allocateMappedMemory(Size, nullptr, 254327952Sdim sys::Memory::MF_READ | 255327952Sdim sys::Memory::MF_WRITE, 256327952Sdim EC); 257296417Sdim if (!MB.base()) 258327952Sdim report_fatal_error("MemoryManager allocation failed: " + EC.message()); 259239462Sdim DataMemory.push_back(MB); 260239462Sdim return (uint8_t*)MB.base(); 261221337Sdim} 262221337Sdim 263221337Sdimstatic const char *ProgramName; 264221337Sdim 265309124Sdimstatic void ErrorAndExit(const Twine &Msg) { 266296417Sdim errs() << ProgramName << ": error: " << Msg << "\n"; 267309124Sdim exit(1); 268221337Sdim} 269221337Sdim 270276479Sdimstatic void loadDylibs() { 271276479Sdim for (const std::string &Dylib : Dylibs) { 272296417Sdim if (!sys::fs::is_regular_file(Dylib)) 273296417Sdim report_fatal_error("Dylib not found: '" + Dylib + "'."); 274296417Sdim std::string ErrMsg; 275296417Sdim if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg)) 276296417Sdim report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg); 277276479Sdim } 278276479Sdim} 279276479Sdim 280221337Sdim/* *** */ 281221337Sdim 282288943Sdimstatic int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { 283288943Sdim assert(LoadObjects || !UseDebugObj); 284288943Sdim 285276479Sdim // Load any dylibs requested on the command line. 286276479Sdim loadDylibs(); 287276479Sdim 288249423Sdim // If we don't have any input files, read from stdin. 289249423Sdim if (!InputFileList.size()) 290249423Sdim InputFileList.push_back("-"); 291296417Sdim for (auto &File : InputFileList) { 292249423Sdim // Instantiate a dynamic linker. 293261991Sdim TrivialMemoryManager MemMgr; 294288943Sdim RuntimeDyld Dyld(MemMgr, MemMgr); 295249423Sdim 296249423Sdim // Load the input memory buffer. 297249423Sdim 298276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 299296417Sdim MemoryBuffer::getFileOrSTDIN(File); 300276479Sdim if (std::error_code EC = InputBuffer.getError()) 301309124Sdim ErrorAndExit("unable to read input: '" + EC.message() + "'"); 302276479Sdim 303309124Sdim Expected<std::unique_ptr<ObjectFile>> MaybeObj( 304280031Sdim ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 305280031Sdim 306309124Sdim if (!MaybeObj) { 307309124Sdim std::string Buf; 308309124Sdim raw_string_ostream OS(Buf); 309309124Sdim logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); 310309124Sdim OS.flush(); 311309124Sdim ErrorAndExit("unable to create object file: '" + Buf + "'"); 312309124Sdim } 313280031Sdim 314280031Sdim ObjectFile &Obj = **MaybeObj; 315280031Sdim 316288943Sdim OwningBinary<ObjectFile> DebugObj; 317288943Sdim std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; 318288943Sdim ObjectFile *SymbolObj = &Obj; 319288943Sdim if (LoadObjects) { 320288943Sdim // Load the object file 321288943Sdim LoadedObjInfo = 322288943Sdim Dyld.loadObject(Obj); 323280031Sdim 324288943Sdim if (Dyld.hasError()) 325309124Sdim ErrorAndExit(Dyld.getErrorString()); 326249423Sdim 327288943Sdim // Resolve all the relocations we can. 328288943Sdim Dyld.resolveRelocations(); 329249423Sdim 330288943Sdim if (UseDebugObj) { 331288943Sdim DebugObj = LoadedObjInfo->getObjectForDebug(Obj); 332288943Sdim SymbolObj = DebugObj.getBinary(); 333296417Sdim LoadedObjInfo.reset(); 334288943Sdim } 335288943Sdim } 336280031Sdim 337327952Sdim std::unique_ptr<DIContext> Context = 338327952Sdim DWARFContext::create(*SymbolObj, LoadedObjInfo.get()); 339249423Sdim 340288943Sdim std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = 341288943Sdim object::computeSymbolSizes(*SymbolObj); 342288943Sdim 343249423Sdim // Use symbol info to iterate functions in the object. 344288943Sdim for (const auto &P : SymAddr) { 345288943Sdim object::SymbolRef Sym = P.first; 346309124Sdim Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); 347309124Sdim if (!TypeOrErr) { 348309124Sdim // TODO: Actually report errors helpfully. 349309124Sdim consumeError(TypeOrErr.takeError()); 350309124Sdim continue; 351309124Sdim } 352309124Sdim SymbolRef::Type Type = *TypeOrErr; 353309124Sdim if (Type == object::SymbolRef::ST_Function) { 354309124Sdim Expected<StringRef> Name = Sym.getName(); 355309124Sdim if (!Name) { 356309124Sdim // TODO: Actually report errors helpfully. 357309124Sdim consumeError(Name.takeError()); 358288943Sdim continue; 359309124Sdim } 360309124Sdim Expected<uint64_t> AddrOrErr = Sym.getAddress(); 361309124Sdim if (!AddrOrErr) { 362309124Sdim // TODO: Actually report errors helpfully. 363309124Sdim consumeError(AddrOrErr.takeError()); 364288943Sdim continue; 365309124Sdim } 366288943Sdim uint64_t Addr = *AddrOrErr; 367249423Sdim 368288943Sdim uint64_t Size = P.second; 369288943Sdim // If we're not using the debug object, compute the address of the 370288943Sdim // symbol in memory (rather than that in the unrelocated object file) 371288943Sdim // and use that to query the DWARFContext. 372288943Sdim if (!UseDebugObj && LoadObjects) { 373309124Sdim auto SecOrErr = Sym.getSection(); 374309124Sdim if (!SecOrErr) { 375309124Sdim // TODO: Actually report errors helpfully. 376309124Sdim consumeError(SecOrErr.takeError()); 377309124Sdim continue; 378309124Sdim } 379309124Sdim object::section_iterator Sec = *SecOrErr; 380288943Sdim StringRef SecName; 381288943Sdim Sec->getName(SecName); 382288943Sdim uint64_t SectionLoadAddress = 383296417Sdim LoadedObjInfo->getSectionLoadAddress(*Sec); 384288943Sdim if (SectionLoadAddress != 0) 385288943Sdim Addr += SectionLoadAddress - Sec->getAddress(); 386288943Sdim } 387249423Sdim 388288943Sdim outs() << "Function: " << *Name << ", Size = " << Size 389288943Sdim << ", Addr = " << Addr << "\n"; 390288943Sdim 391249423Sdim DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); 392296417Sdim for (auto &D : Lines) { 393296417Sdim outs() << " Line info @ " << D.first - Addr << ": " 394296417Sdim << D.second.FileName << ", line:" << D.second.Line << "\n"; 395249423Sdim } 396249423Sdim } 397249423Sdim } 398249423Sdim } 399249423Sdim 400249423Sdim return 0; 401249423Sdim} 402249423Sdim 403296417Sdimstatic void doPreallocation(TrivialMemoryManager &MemMgr) { 404296417Sdim // Allocate a slab of memory upfront, if required. This is used if 405296417Sdim // we want to test small code models. 406296417Sdim if (static_cast<intptr_t>(PreallocMemory) < 0) 407296417Sdim report_fatal_error("Pre-allocated bytes of memory must be a positive integer."); 408296417Sdim 409296417Sdim // FIXME: Limit the amount of memory that can be preallocated? 410296417Sdim if (PreallocMemory != 0) 411296417Sdim MemMgr.preallocateSlab(PreallocMemory); 412296417Sdim} 413296417Sdim 414221337Sdimstatic int executeInput() { 415276479Sdim // Load any dylibs requested on the command line. 416276479Sdim loadDylibs(); 417276479Sdim 418221337Sdim // Instantiate a dynamic linker. 419261991Sdim TrivialMemoryManager MemMgr; 420296417Sdim doPreallocation(MemMgr); 421288943Sdim RuntimeDyld Dyld(MemMgr, MemMgr); 422221337Sdim 423221337Sdim // If we don't have any input files, read from stdin. 424221337Sdim if (!InputFileList.size()) 425221337Sdim InputFileList.push_back("-"); 426296417Sdim for (auto &File : InputFileList) { 427221337Sdim // Load the input memory buffer. 428276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 429296417Sdim MemoryBuffer::getFileOrSTDIN(File); 430276479Sdim if (std::error_code EC = InputBuffer.getError()) 431309124Sdim ErrorAndExit("unable to read input: '" + EC.message() + "'"); 432309124Sdim Expected<std::unique_ptr<ObjectFile>> MaybeObj( 433280031Sdim ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 434280031Sdim 435309124Sdim if (!MaybeObj) { 436309124Sdim std::string Buf; 437309124Sdim raw_string_ostream OS(Buf); 438309124Sdim logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); 439309124Sdim OS.flush(); 440309124Sdim ErrorAndExit("unable to create object file: '" + Buf + "'"); 441309124Sdim } 442280031Sdim 443280031Sdim ObjectFile &Obj = **MaybeObj; 444280031Sdim 445243830Sdim // Load the object file 446280031Sdim Dyld.loadObject(Obj); 447280031Sdim if (Dyld.hasError()) { 448309124Sdim ErrorAndExit(Dyld.getErrorString()); 449221337Sdim } 450221337Sdim } 451221337Sdim 452296417Sdim // Resove all the relocations we can. 453296417Sdim // FIXME: Error out if there are unresolved relocations. 454221337Sdim Dyld.resolveRelocations(); 455221337Sdim 456221337Sdim // Get the address of the entry point (_main by default). 457288943Sdim void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); 458276479Sdim if (!MainAddress) 459309124Sdim ErrorAndExit("no definition for '" + EntryPoint + "'"); 460221337Sdim 461221337Sdim // Invalidate the instruction cache for each loaded function. 462296417Sdim for (auto &FM : MemMgr.FunctionMemory) { 463296417Sdim 464221337Sdim // Make sure the memory is executable. 465296417Sdim // setExecutable will call InvalidateInstructionCache. 466327952Sdim if (auto EC = sys::Memory::protectMappedMemory(FM, 467327952Sdim sys::Memory::MF_READ | 468327952Sdim sys::Memory::MF_EXEC)) 469327952Sdim ErrorAndExit("unable to mark function executable: '" + EC.message() + 470327952Sdim "'"); 471221337Sdim } 472221337Sdim 473221337Sdim // Dispatch to _main(). 474221337Sdim errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; 475221337Sdim 476221337Sdim int (*Main)(int, const char**) = 477221337Sdim (int(*)(int,const char**)) uintptr_t(MainAddress); 478221337Sdim const char **Argv = new const char*[2]; 479221337Sdim // Use the name of the first input object module as argv[0] for the target. 480221337Sdim Argv[0] = InputFileList[0].c_str(); 481276479Sdim Argv[1] = nullptr; 482221337Sdim return Main(1, Argv); 483221337Sdim} 484221337Sdim 485276479Sdimstatic int checkAllExpressions(RuntimeDyldChecker &Checker) { 486276479Sdim for (const auto& CheckerFileName : CheckFiles) { 487276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = 488276479Sdim MemoryBuffer::getFileOrSTDIN(CheckerFileName); 489276479Sdim if (std::error_code EC = CheckerFileBuf.getError()) 490309124Sdim ErrorAndExit("unable to read input '" + CheckerFileName + "': " + 491276479Sdim EC.message()); 492276479Sdim 493276479Sdim if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", 494276479Sdim CheckerFileBuf.get().get())) 495309124Sdim ErrorAndExit("some checks in '" + CheckerFileName + "' failed"); 496276479Sdim } 497276479Sdim return 0; 498276479Sdim} 499276479Sdim 500321369Sdimvoid applySpecificSectionMappings(RuntimeDyldChecker &Checker) { 501280031Sdim 502280031Sdim for (StringRef Mapping : SpecificSectionMappings) { 503280031Sdim 504280031Sdim size_t EqualsIdx = Mapping.find_first_of("="); 505288943Sdim std::string SectionIDStr = Mapping.substr(0, EqualsIdx); 506280031Sdim size_t ComaIdx = Mapping.find_first_of(","); 507280031Sdim 508296417Sdim if (ComaIdx == StringRef::npos) 509296417Sdim report_fatal_error("Invalid section specification '" + Mapping + 510296417Sdim "'. Should be '<file name>,<section name>=<addr>'"); 511280031Sdim 512288943Sdim std::string FileName = SectionIDStr.substr(0, ComaIdx); 513288943Sdim std::string SectionName = SectionIDStr.substr(ComaIdx + 1); 514280031Sdim 515280031Sdim uint64_t OldAddrInt; 516280031Sdim std::string ErrorMsg; 517280031Sdim std::tie(OldAddrInt, ErrorMsg) = 518280031Sdim Checker.getSectionAddr(FileName, SectionName, true); 519280031Sdim 520296417Sdim if (ErrorMsg != "") 521296417Sdim report_fatal_error(ErrorMsg); 522280031Sdim 523280031Sdim void* OldAddr = reinterpret_cast<void*>(static_cast<uintptr_t>(OldAddrInt)); 524280031Sdim 525288943Sdim std::string NewAddrStr = Mapping.substr(EqualsIdx + 1); 526280031Sdim uint64_t NewAddr; 527280031Sdim 528296417Sdim if (StringRef(NewAddrStr).getAsInteger(0, NewAddr)) 529296417Sdim report_fatal_error("Invalid section address in mapping '" + Mapping + 530296417Sdim "'."); 531280031Sdim 532280031Sdim Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr); 533280031Sdim } 534280031Sdim} 535280031Sdim 536280031Sdim// Scatter sections in all directions! 537280031Sdim// Remaps section addresses for -verify mode. The following command line options 538280031Sdim// can be used to customize the layout of the memory within the phony target's 539280031Sdim// address space: 540314564Sdim// -target-addr-start <s> -- Specify where the phony target address range starts. 541280031Sdim// -target-addr-end <e> -- Specify where the phony target address range ends. 542280031Sdim// -target-section-sep <d> -- Specify how big a gap should be left between the 543280031Sdim// end of one section and the start of the next. 544280031Sdim// Defaults to zero. Set to something big 545280031Sdim// (e.g. 1 << 32) to stress-test stubs, GOTs, etc. 546280031Sdim// 547288943Sdimstatic void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, 548288943Sdim TrivialMemoryManager &MemMgr, 549288943Sdim RuntimeDyldChecker &Checker) { 550280031Sdim 551280031Sdim // Set up a work list (section addr/size pairs). 552280031Sdim typedef std::list<std::pair<void*, uint64_t>> WorklistT; 553280031Sdim WorklistT Worklist; 554280031Sdim 555280031Sdim for (const auto& CodeSection : MemMgr.FunctionMemory) 556280031Sdim Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size())); 557280031Sdim for (const auto& DataSection : MemMgr.DataMemory) 558280031Sdim Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size())); 559280031Sdim 560280031Sdim // Apply any section-specific mappings that were requested on the command 561280031Sdim // line. 562321369Sdim applySpecificSectionMappings(Checker); 563280031Sdim 564280031Sdim // Keep an "already allocated" mapping of section target addresses to sizes. 565280031Sdim // Sections whose address mappings aren't specified on the command line will 566280031Sdim // allocated around the explicitly mapped sections while maintaining the 567280031Sdim // minimum separation. 568280031Sdim std::map<uint64_t, uint64_t> AlreadyAllocated; 569280031Sdim 570321369Sdim // Move the previously applied mappings (whether explicitly specified on the 571321369Sdim // command line, or implicitly set by RuntimeDyld) into the already-allocated 572321369Sdim // map. 573280031Sdim for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); 574280031Sdim I != E;) { 575280031Sdim WorklistT::iterator Tmp = I; 576280031Sdim ++I; 577321369Sdim auto LoadAddr = Checker.getSectionLoadAddress(Tmp->first); 578280031Sdim 579321369Sdim if (LoadAddr && 580321369Sdim *LoadAddr != static_cast<uint64_t>( 581321369Sdim reinterpret_cast<uintptr_t>(Tmp->first))) { 582321369Sdim AlreadyAllocated[*LoadAddr] = Tmp->second; 583280031Sdim Worklist.erase(Tmp); 584280031Sdim } 585280031Sdim } 586280031Sdim 587280031Sdim // If the -target-addr-end option wasn't explicitly passed, then set it to a 588280031Sdim // sensible default based on the target triple. 589280031Sdim if (TargetAddrEnd.getNumOccurrences() == 0) { 590280031Sdim if (TargetTriple.isArch16Bit()) 591280031Sdim TargetAddrEnd = (1ULL << 16) - 1; 592280031Sdim else if (TargetTriple.isArch32Bit()) 593280031Sdim TargetAddrEnd = (1ULL << 32) - 1; 594280031Sdim // TargetAddrEnd already has a sensible default for 64-bit systems, so 595280031Sdim // there's nothing to do in the 64-bit case. 596280031Sdim } 597280031Sdim 598280031Sdim // Process any elements remaining in the worklist. 599280031Sdim while (!Worklist.empty()) { 600280031Sdim std::pair<void*, uint64_t> CurEntry = Worklist.front(); 601280031Sdim Worklist.pop_front(); 602280031Sdim 603280031Sdim uint64_t NextSectionAddr = TargetAddrStart; 604280031Sdim 605280031Sdim for (const auto &Alloc : AlreadyAllocated) 606280031Sdim if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first) 607280031Sdim break; 608280031Sdim else 609280031Sdim NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; 610280031Sdim 611280031Sdim AlreadyAllocated[NextSectionAddr] = CurEntry.second; 612280031Sdim Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr); 613280031Sdim } 614280031Sdim 615288943Sdim // Add dummy symbols to the memory manager. 616288943Sdim for (const auto &Mapping : DummySymbolMappings) { 617314564Sdim size_t EqualsIdx = Mapping.find_first_of('='); 618288943Sdim 619296417Sdim if (EqualsIdx == StringRef::npos) 620296417Sdim report_fatal_error("Invalid dummy symbol specification '" + Mapping + 621296417Sdim "'. Should be '<symbol name>=<addr>'"); 622288943Sdim 623288943Sdim std::string Symbol = Mapping.substr(0, EqualsIdx); 624288943Sdim std::string AddrStr = Mapping.substr(EqualsIdx + 1); 625288943Sdim 626288943Sdim uint64_t Addr; 627296417Sdim if (StringRef(AddrStr).getAsInteger(0, Addr)) 628296417Sdim report_fatal_error("Invalid symbol mapping '" + Mapping + "'."); 629288943Sdim 630288943Sdim MemMgr.addDummySymbol(Symbol, Addr); 631288943Sdim } 632280031Sdim} 633280031Sdim 634280031Sdim// Load and link the objects specified on the command line, but do not execute 635280031Sdim// anything. Instead, attach a RuntimeDyldChecker instance and call it to 636280031Sdim// verify the correctness of the linked memory. 637276479Sdimstatic int linkAndVerify() { 638276479Sdim 639276479Sdim // Check for missing triple. 640296417Sdim if (TripleName == "") 641309124Sdim ErrorAndExit("-triple required when running in -verify mode."); 642276479Sdim 643276479Sdim // Look up the target and build the disassembler. 644276479Sdim Triple TheTriple(Triple::normalize(TripleName)); 645276479Sdim std::string ErrorStr; 646276479Sdim const Target *TheTarget = 647276479Sdim TargetRegistry::lookupTarget("", TheTriple, ErrorStr); 648296417Sdim if (!TheTarget) 649309124Sdim ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr); 650296417Sdim 651276479Sdim TripleName = TheTriple.getTriple(); 652276479Sdim 653276479Sdim std::unique_ptr<MCSubtargetInfo> STI( 654288943Sdim TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); 655296417Sdim if (!STI) 656309124Sdim ErrorAndExit("Unable to create subtarget info!"); 657276479Sdim 658276479Sdim std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 659296417Sdim if (!MRI) 660309124Sdim ErrorAndExit("Unable to create target register info!"); 661276479Sdim 662276479Sdim std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); 663296417Sdim if (!MAI) 664309124Sdim ErrorAndExit("Unable to create target asm info!"); 665276479Sdim 666276479Sdim MCContext Ctx(MAI.get(), MRI.get(), nullptr); 667276479Sdim 668276479Sdim std::unique_ptr<MCDisassembler> Disassembler( 669276479Sdim TheTarget->createMCDisassembler(*STI, Ctx)); 670296417Sdim if (!Disassembler) 671309124Sdim ErrorAndExit("Unable to create disassembler!"); 672276479Sdim 673276479Sdim std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 674276479Sdim 675276479Sdim std::unique_ptr<MCInstPrinter> InstPrinter( 676288943Sdim TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); 677276479Sdim 678276479Sdim // Load any dylibs requested on the command line. 679276479Sdim loadDylibs(); 680276479Sdim 681276479Sdim // Instantiate a dynamic linker. 682276479Sdim TrivialMemoryManager MemMgr; 683296417Sdim doPreallocation(MemMgr); 684288943Sdim RuntimeDyld Dyld(MemMgr, MemMgr); 685280031Sdim Dyld.setProcessAllSections(true); 686280031Sdim RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(), 687280031Sdim llvm::dbgs()); 688276479Sdim 689276479Sdim // If we don't have any input files, read from stdin. 690276479Sdim if (!InputFileList.size()) 691276479Sdim InputFileList.push_back("-"); 692296417Sdim for (auto &Filename : InputFileList) { 693276479Sdim // Load the input memory buffer. 694276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 695296417Sdim MemoryBuffer::getFileOrSTDIN(Filename); 696280031Sdim 697276479Sdim if (std::error_code EC = InputBuffer.getError()) 698309124Sdim ErrorAndExit("unable to read input: '" + EC.message() + "'"); 699276479Sdim 700309124Sdim Expected<std::unique_ptr<ObjectFile>> MaybeObj( 701280031Sdim ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 702280031Sdim 703309124Sdim if (!MaybeObj) { 704309124Sdim std::string Buf; 705309124Sdim raw_string_ostream OS(Buf); 706309124Sdim logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); 707309124Sdim OS.flush(); 708309124Sdim ErrorAndExit("unable to create object file: '" + Buf + "'"); 709309124Sdim } 710280031Sdim 711280031Sdim ObjectFile &Obj = **MaybeObj; 712280031Sdim 713276479Sdim // Load the object file 714280031Sdim Dyld.loadObject(Obj); 715280031Sdim if (Dyld.hasError()) { 716309124Sdim ErrorAndExit(Dyld.getErrorString()); 717276479Sdim } 718276479Sdim } 719276479Sdim 720288943Sdim // Re-map the section addresses into the phony target address space and add 721288943Sdim // dummy symbols. 722288943Sdim remapSectionsAndSymbols(TheTriple, MemMgr, Checker); 723280031Sdim 724276479Sdim // Resolve all the relocations we can. 725276479Sdim Dyld.resolveRelocations(); 726276479Sdim 727280031Sdim // Register EH frames. 728280031Sdim Dyld.registerEHFrames(); 729280031Sdim 730280031Sdim int ErrorCode = checkAllExpressions(Checker); 731296417Sdim if (Dyld.hasError()) 732309124Sdim ErrorAndExit("RTDyld reported an error applying relocations:\n " + 733296417Sdim Dyld.getErrorString()); 734280031Sdim 735280031Sdim return ErrorCode; 736276479Sdim} 737276479Sdim 738221337Sdimint main(int argc, char **argv) { 739309124Sdim sys::PrintStackTraceOnErrorSignal(argv[0]); 740261991Sdim PrettyStackTraceProgram X(argc, argv); 741261991Sdim 742221337Sdim ProgramName = argv[0]; 743221337Sdim llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 744221337Sdim 745276479Sdim llvm::InitializeAllTargetInfos(); 746276479Sdim llvm::InitializeAllTargetMCs(); 747276479Sdim llvm::InitializeAllDisassemblers(); 748276479Sdim 749221337Sdim cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); 750221337Sdim 751221337Sdim switch (Action) { 752221337Sdim case AC_Execute: 753221337Sdim return executeInput(); 754288943Sdim case AC_PrintDebugLineInfo: 755288943Sdim return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */ true); 756249423Sdim case AC_PrintLineInfo: 757288943Sdim return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */false); 758288943Sdim case AC_PrintObjectLineInfo: 759288943Sdim return printLineInfoForInput(/* LoadObjects */false,/* UseDebugObj */false); 760276479Sdim case AC_Verify: 761276479Sdim return linkAndVerify(); 762221337Sdim } 763221337Sdim} 764