10b57cec5SDimitry Andric //===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This is a testing tool for use with the MC-JIT LLVM components. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 140b57cec5SDimitry Andric #include "llvm/DebugInfo/DIContext.h" 150b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFContext.h" 160b57cec5SDimitry Andric #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 170b57cec5SDimitry Andric #include "llvm/ExecutionEngine/RuntimeDyld.h" 180b57cec5SDimitry Andric #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCInstPrinter.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 26480093f4SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 27349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 280b57cec5SDimitry Andric #include "llvm/Object/SymbolSize.h" 290b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 300b57cec5SDimitry Andric #include "llvm/Support/DynamicLibrary.h" 31fe6060f1SDimitry Andric #include "llvm/Support/FileSystem.h" 320b57cec5SDimitry Andric #include "llvm/Support/InitLLVM.h" 338bcb0991SDimitry Andric #include "llvm/Support/MSVCErrorWorkarounds.h" 340b57cec5SDimitry Andric #include "llvm/Support/Memory.h" 350b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 360b57cec5SDimitry Andric #include "llvm/Support/Path.h" 370b57cec5SDimitry Andric #include "llvm/Support/TargetSelect.h" 388bcb0991SDimitry Andric #include "llvm/Support/Timer.h" 390b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric #include <future> 420b57cec5SDimitry Andric #include <list> 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric using namespace llvm; 450b57cec5SDimitry Andric using namespace llvm::object; 460b57cec5SDimitry Andric 47fe6060f1SDimitry Andric static cl::OptionCategory RTDyldCategory("RTDyld Options"); 48fe6060f1SDimitry Andric 4981ad6265SDimitry Andric static cl::list<std::string> InputFileList(cl::Positional, 50fe6060f1SDimitry Andric cl::desc("<input files>"), 51fe6060f1SDimitry Andric cl::cat(RTDyldCategory)); 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric enum ActionType { 540b57cec5SDimitry Andric AC_Execute, 550b57cec5SDimitry Andric AC_PrintObjectLineInfo, 560b57cec5SDimitry Andric AC_PrintLineInfo, 570b57cec5SDimitry Andric AC_PrintDebugLineInfo, 580b57cec5SDimitry Andric AC_Verify 590b57cec5SDimitry Andric }; 600b57cec5SDimitry Andric 61fe6060f1SDimitry Andric static cl::opt<ActionType> Action( 62fe6060f1SDimitry Andric cl::desc("Action to perform:"), cl::init(AC_Execute), 63fe6060f1SDimitry Andric cl::values( 64fe6060f1SDimitry Andric clEnumValN(AC_Execute, "execute", 650b57cec5SDimitry Andric "Load, link, and execute the inputs."), 660b57cec5SDimitry Andric clEnumValN(AC_PrintLineInfo, "printline", 670b57cec5SDimitry Andric "Load, link, and print line information for each function."), 680b57cec5SDimitry Andric clEnumValN(AC_PrintDebugLineInfo, "printdebugline", 69fe6060f1SDimitry Andric "Load, link, and print line information for each function " 70fe6060f1SDimitry Andric "using the debug object"), 710b57cec5SDimitry Andric clEnumValN(AC_PrintObjectLineInfo, "printobjline", 720b57cec5SDimitry Andric "Like -printlineinfo but does not load the object first"), 730b57cec5SDimitry Andric clEnumValN(AC_Verify, "verify", 74fe6060f1SDimitry Andric "Load, link and verify the resulting memory image.")), 75fe6060f1SDimitry Andric cl::cat(RTDyldCategory)); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric static cl::opt<std::string> 78fe6060f1SDimitry Andric EntryPoint("entry", cl::desc("Function to call as entry point."), 79fe6060f1SDimitry Andric cl::init("_main"), cl::cat(RTDyldCategory)); 800b57cec5SDimitry Andric 81fe6060f1SDimitry Andric static cl::list<std::string> Dylibs("dylib", cl::desc("Add library."), 8281ad6265SDimitry Andric cl::cat(RTDyldCategory)); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric static cl::list<std::string> InputArgv("args", cl::Positional, 850b57cec5SDimitry Andric cl::desc("<program arguments>..."), 8681ad6265SDimitry Andric cl::PositionalEatsArgs, 87fe6060f1SDimitry Andric cl::cat(RTDyldCategory)); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric static cl::opt<std::string> 90fe6060f1SDimitry Andric TripleName("triple", cl::desc("Target triple for disassembler"), 91fe6060f1SDimitry Andric cl::cat(RTDyldCategory)); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric static cl::opt<std::string> 940b57cec5SDimitry Andric MCPU("mcpu", 950b57cec5SDimitry Andric cl::desc("Target a specific cpu type (-mcpu=help for details)"), 96fe6060f1SDimitry Andric cl::value_desc("cpu-name"), cl::init(""), cl::cat(RTDyldCategory)); 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric static cl::list<std::string> 990b57cec5SDimitry Andric CheckFiles("check", 1000b57cec5SDimitry Andric cl::desc("File containing RuntimeDyld verifier checks."), 10181ad6265SDimitry Andric cl::cat(RTDyldCategory)); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric static cl::opt<uint64_t> 1040b57cec5SDimitry Andric PreallocMemory("preallocate", 1050b57cec5SDimitry Andric cl::desc("Allocate memory upfront rather than on-demand"), 106fe6060f1SDimitry Andric cl::init(0), cl::cat(RTDyldCategory)); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric static cl::opt<uint64_t> TargetAddrStart( 1090b57cec5SDimitry Andric "target-addr-start", 1100b57cec5SDimitry Andric cl::desc("For -verify only: start of phony target address " 1110b57cec5SDimitry Andric "range."), 1120b57cec5SDimitry Andric cl::init(4096), // Start at "page 1" - no allocating at "null". 113fe6060f1SDimitry Andric cl::Hidden, cl::cat(RTDyldCategory)); 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric static cl::opt<uint64_t> TargetAddrEnd( 1160b57cec5SDimitry Andric "target-addr-end", 1170b57cec5SDimitry Andric cl::desc("For -verify only: end of phony target address range."), 118fe6060f1SDimitry Andric cl::init(~0ULL), cl::Hidden, cl::cat(RTDyldCategory)); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric static cl::opt<uint64_t> TargetSectionSep( 1210b57cec5SDimitry Andric "target-section-sep", 1220b57cec5SDimitry Andric cl::desc("For -verify only: Separation between sections in " 1230b57cec5SDimitry Andric "phony target address space."), 124fe6060f1SDimitry Andric cl::init(0), cl::Hidden, cl::cat(RTDyldCategory)); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric static cl::list<std::string> 1270b57cec5SDimitry Andric SpecificSectionMappings("map-section", 1280b57cec5SDimitry Andric cl::desc("For -verify only: Map a section to a " 1290b57cec5SDimitry Andric "specific address."), 13081ad6265SDimitry Andric cl::Hidden, cl::cat(RTDyldCategory)); 1310b57cec5SDimitry Andric 132fe6060f1SDimitry Andric static cl::list<std::string> DummySymbolMappings( 133fe6060f1SDimitry Andric "dummy-extern", 1340b57cec5SDimitry Andric cl::desc("For -verify only: Inject a symbol into the extern " 1350b57cec5SDimitry Andric "symbol table."), 13681ad6265SDimitry Andric cl::Hidden, cl::cat(RTDyldCategory)); 1370b57cec5SDimitry Andric 138fe6060f1SDimitry Andric static cl::opt<bool> PrintAllocationRequests( 139fe6060f1SDimitry Andric "print-alloc-requests", 1400b57cec5SDimitry Andric cl::desc("Print allocation requests made to the memory " 1410b57cec5SDimitry Andric "manager by RuntimeDyld"), 142fe6060f1SDimitry Andric cl::Hidden, cl::cat(RTDyldCategory)); 1430b57cec5SDimitry Andric 1448bcb0991SDimitry Andric static cl::opt<bool> ShowTimes("show-times", 1458bcb0991SDimitry Andric cl::desc("Show times for llvm-rtdyld phases"), 146fe6060f1SDimitry Andric cl::init(false), cl::cat(RTDyldCategory)); 1478bcb0991SDimitry Andric 1480b57cec5SDimitry Andric ExitOnError ExitOnErr; 1490b57cec5SDimitry Andric 1508bcb0991SDimitry Andric struct RTDyldTimers { 1518bcb0991SDimitry Andric TimerGroup RTDyldTG{"llvm-rtdyld timers", "timers for llvm-rtdyld phases"}; 1528bcb0991SDimitry Andric Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTG}; 1538bcb0991SDimitry Andric Timer LinkTimer{"link", "time to link object files", RTDyldTG}; 1548bcb0991SDimitry Andric Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTG}; 1558bcb0991SDimitry Andric }; 1568bcb0991SDimitry Andric 1578bcb0991SDimitry Andric std::unique_ptr<RTDyldTimers> Timers; 1588bcb0991SDimitry Andric 1590b57cec5SDimitry Andric /* *** */ 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric using SectionIDMap = StringMap<unsigned>; 1620b57cec5SDimitry Andric using FileToSectionIDMap = StringMap<SectionIDMap>; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric void dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) { 1650b57cec5SDimitry Andric for (const auto &KV : FileToSecIDMap) { 1660b57cec5SDimitry Andric llvm::dbgs() << "In " << KV.first() << "\n"; 1670b57cec5SDimitry Andric for (auto &KV2 : KV.second) 1680b57cec5SDimitry Andric llvm::dbgs() << " \"" << KV2.first() << "\" -> " << KV2.second << "\n"; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric Expected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap, 1730b57cec5SDimitry Andric StringRef FileName, StringRef SectionName) { 1740b57cec5SDimitry Andric auto I = FileToSecIDMap.find(FileName); 1750b57cec5SDimitry Andric if (I == FileToSecIDMap.end()) 1760b57cec5SDimitry Andric return make_error<StringError>("No file named " + FileName, 1770b57cec5SDimitry Andric inconvertibleErrorCode()); 1780b57cec5SDimitry Andric auto &SectionIDs = I->second; 1790b57cec5SDimitry Andric auto J = SectionIDs.find(SectionName); 1800b57cec5SDimitry Andric if (J == SectionIDs.end()) 1810b57cec5SDimitry Andric return make_error<StringError>("No section named \"" + SectionName + 1820b57cec5SDimitry Andric "\" in file " + FileName, 1830b57cec5SDimitry Andric inconvertibleErrorCode()); 1840b57cec5SDimitry Andric return J->second; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // A trivial memory manager that doesn't do anything fancy, just uses the 1880b57cec5SDimitry Andric // support library allocation routines directly. 1890b57cec5SDimitry Andric class TrivialMemoryManager : public RTDyldMemoryManager { 1900b57cec5SDimitry Andric public: 1910b57cec5SDimitry Andric struct SectionInfo { 1920b57cec5SDimitry Andric SectionInfo(StringRef Name, sys::MemoryBlock MB, unsigned SectionID) 1935ffd83dbSDimitry Andric : Name(std::string(Name)), MB(std::move(MB)), SectionID(SectionID) {} 1940b57cec5SDimitry Andric std::string Name; 1950b57cec5SDimitry Andric sys::MemoryBlock MB; 1960b57cec5SDimitry Andric unsigned SectionID = ~0U; 1970b57cec5SDimitry Andric }; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric SmallVector<SectionInfo, 16> FunctionMemory; 2000b57cec5SDimitry Andric SmallVector<SectionInfo, 16> DataMemory; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 2030b57cec5SDimitry Andric unsigned SectionID, 2040b57cec5SDimitry Andric StringRef SectionName) override; 2050b57cec5SDimitry Andric uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 2060b57cec5SDimitry Andric unsigned SectionID, StringRef SectionName, 2070b57cec5SDimitry Andric bool IsReadOnly) override; 208349cc55cSDimitry Andric TrivialMemoryManager::TLSSection 209349cc55cSDimitry Andric allocateTLSSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, 210349cc55cSDimitry Andric StringRef SectionName) override; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric /// If non null, records subsequent Name -> SectionID mappings. 2130b57cec5SDimitry Andric void setSectionIDsMap(SectionIDMap *SecIDMap) { 2140b57cec5SDimitry Andric this->SecIDMap = SecIDMap; 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric void *getPointerToNamedFunction(const std::string &Name, 2180b57cec5SDimitry Andric bool AbortOnFailure = true) override { 2190b57cec5SDimitry Andric return nullptr; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric bool finalizeMemory(std::string *ErrMsg) override { return false; } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric void addDummySymbol(const std::string &Name, uint64_t Addr) { 2250b57cec5SDimitry Andric DummyExterns[Name] = Addr; 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric JITSymbol findSymbol(const std::string &Name) override { 2290b57cec5SDimitry Andric auto I = DummyExterns.find(Name); 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric if (I != DummyExterns.end()) 2320b57cec5SDimitry Andric return JITSymbol(I->second, JITSymbolFlags::Exported); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric if (auto Sym = RTDyldMemoryManager::findSymbol(Name)) 2350b57cec5SDimitry Andric return Sym; 2360b57cec5SDimitry Andric else if (auto Err = Sym.takeError()) 2370b57cec5SDimitry Andric ExitOnErr(std::move(Err)); 2380b57cec5SDimitry Andric else 2390b57cec5SDimitry Andric ExitOnErr(make_error<StringError>("Could not find definition for \"" + 2400b57cec5SDimitry Andric Name + "\"", 2410b57cec5SDimitry Andric inconvertibleErrorCode())); 2420b57cec5SDimitry Andric llvm_unreachable("Should have returned or exited by now"); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 2460b57cec5SDimitry Andric size_t Size) override {} 2470b57cec5SDimitry Andric void deregisterEHFrames() override {} 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric void preallocateSlab(uint64_t Size) { 2500b57cec5SDimitry Andric std::error_code EC; 2510b57cec5SDimitry Andric sys::MemoryBlock MB = 2520b57cec5SDimitry Andric sys::Memory::allocateMappedMemory(Size, nullptr, 2530b57cec5SDimitry Andric sys::Memory::MF_READ | 2540b57cec5SDimitry Andric sys::Memory::MF_WRITE, 2550b57cec5SDimitry Andric EC); 2560b57cec5SDimitry Andric if (!MB.base()) 257349cc55cSDimitry Andric report_fatal_error(Twine("Can't allocate enough memory: ") + 258349cc55cSDimitry Andric EC.message()); 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric PreallocSlab = MB; 2610b57cec5SDimitry Andric UsePreallocation = true; 2620b57cec5SDimitry Andric SlabSize = Size; 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode, 2660b57cec5SDimitry Andric StringRef SectionName, unsigned SectionID) { 2670b57cec5SDimitry Andric Size = alignTo(Size, Alignment); 2680b57cec5SDimitry Andric if (CurrentSlabOffset + Size > SlabSize) 2690b57cec5SDimitry Andric report_fatal_error("Can't allocate enough memory. Tune --preallocate"); 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric uintptr_t OldSlabOffset = CurrentSlabOffset; 2720b57cec5SDimitry Andric sys::MemoryBlock MB((void *)OldSlabOffset, Size); 2730b57cec5SDimitry Andric if (isCode) 2740b57cec5SDimitry Andric FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 2750b57cec5SDimitry Andric else 2760b57cec5SDimitry Andric DataMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 2770b57cec5SDimitry Andric CurrentSlabOffset += Size; 2780b57cec5SDimitry Andric return (uint8_t*)OldSlabOffset; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric private: 2820b57cec5SDimitry Andric std::map<std::string, uint64_t> DummyExterns; 2830b57cec5SDimitry Andric sys::MemoryBlock PreallocSlab; 2840b57cec5SDimitry Andric bool UsePreallocation = false; 2850b57cec5SDimitry Andric uintptr_t SlabSize = 0; 2860b57cec5SDimitry Andric uintptr_t CurrentSlabOffset = 0; 2870b57cec5SDimitry Andric SectionIDMap *SecIDMap = nullptr; 288d781ede6SDimitry Andric #if defined(__x86_64__) && defined(__ELF__) && defined(__linux__) 289349cc55cSDimitry Andric unsigned UsedTLSStorage = 0; 290349cc55cSDimitry Andric #endif 2910b57cec5SDimitry Andric }; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 2940b57cec5SDimitry Andric unsigned Alignment, 2950b57cec5SDimitry Andric unsigned SectionID, 2960b57cec5SDimitry Andric StringRef SectionName) { 2970b57cec5SDimitry Andric if (PrintAllocationRequests) 2980b57cec5SDimitry Andric outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " 2990b57cec5SDimitry Andric << Alignment << ", SectionName = " << SectionName << ")\n"; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric if (SecIDMap) 3020b57cec5SDimitry Andric (*SecIDMap)[SectionName] = SectionID; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric if (UsePreallocation) 3050b57cec5SDimitry Andric return allocateFromSlab(Size, Alignment, true /* isCode */, 3060b57cec5SDimitry Andric SectionName, SectionID); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric std::error_code EC; 3090b57cec5SDimitry Andric sys::MemoryBlock MB = 3100b57cec5SDimitry Andric sys::Memory::allocateMappedMemory(Size, nullptr, 3110b57cec5SDimitry Andric sys::Memory::MF_READ | 3120b57cec5SDimitry Andric sys::Memory::MF_WRITE, 3130b57cec5SDimitry Andric EC); 3140b57cec5SDimitry Andric if (!MB.base()) 315349cc55cSDimitry Andric report_fatal_error(Twine("MemoryManager allocation failed: ") + 316349cc55cSDimitry Andric EC.message()); 3170b57cec5SDimitry Andric FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 3180b57cec5SDimitry Andric return (uint8_t*)MB.base(); 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 3220b57cec5SDimitry Andric unsigned Alignment, 3230b57cec5SDimitry Andric unsigned SectionID, 3240b57cec5SDimitry Andric StringRef SectionName, 3250b57cec5SDimitry Andric bool IsReadOnly) { 3260b57cec5SDimitry Andric if (PrintAllocationRequests) 3270b57cec5SDimitry Andric outs() << "allocateDataSection(Size = " << Size << ", Alignment = " 3280b57cec5SDimitry Andric << Alignment << ", SectionName = " << SectionName << ")\n"; 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric if (SecIDMap) 3310b57cec5SDimitry Andric (*SecIDMap)[SectionName] = SectionID; 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric if (UsePreallocation) 3340b57cec5SDimitry Andric return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName, 3350b57cec5SDimitry Andric SectionID); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric std::error_code EC; 3380b57cec5SDimitry Andric sys::MemoryBlock MB = 3390b57cec5SDimitry Andric sys::Memory::allocateMappedMemory(Size, nullptr, 3400b57cec5SDimitry Andric sys::Memory::MF_READ | 3410b57cec5SDimitry Andric sys::Memory::MF_WRITE, 3420b57cec5SDimitry Andric EC); 3430b57cec5SDimitry Andric if (!MB.base()) 344349cc55cSDimitry Andric report_fatal_error(Twine("MemoryManager allocation failed: ") + 345349cc55cSDimitry Andric EC.message()); 3460b57cec5SDimitry Andric DataMemory.push_back(SectionInfo(SectionName, MB, SectionID)); 3470b57cec5SDimitry Andric return (uint8_t*)MB.base(); 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 350349cc55cSDimitry Andric // In case the execution needs TLS storage, we define a very small TLS memory 351349cc55cSDimitry Andric // area here that will be used in allocateTLSSection(). 352d781ede6SDimitry Andric #if defined(__x86_64__) && defined(__ELF__) && defined(__linux__) 353349cc55cSDimitry Andric extern "C" { 354349cc55cSDimitry Andric alignas(16) __attribute__((visibility("hidden"), tls_model("initial-exec"), 355349cc55cSDimitry Andric used)) thread_local char LLVMRTDyldTLSSpace[16]; 356349cc55cSDimitry Andric } 357349cc55cSDimitry Andric #endif 358349cc55cSDimitry Andric 359349cc55cSDimitry Andric TrivialMemoryManager::TLSSection 360349cc55cSDimitry Andric TrivialMemoryManager::allocateTLSSection(uintptr_t Size, unsigned Alignment, 361349cc55cSDimitry Andric unsigned SectionID, 362349cc55cSDimitry Andric StringRef SectionName) { 363d781ede6SDimitry Andric #if defined(__x86_64__) && defined(__ELF__) && defined(__linux__) 364349cc55cSDimitry Andric if (Size + UsedTLSStorage > sizeof(LLVMRTDyldTLSSpace)) { 365349cc55cSDimitry Andric return {}; 366349cc55cSDimitry Andric } 367349cc55cSDimitry Andric 368349cc55cSDimitry Andric // Get the offset of the TLSSpace in the TLS block by using a tpoff 369349cc55cSDimitry Andric // relocation here. 370349cc55cSDimitry Andric int64_t TLSOffset; 371349cc55cSDimitry Andric asm("leaq LLVMRTDyldTLSSpace@tpoff, %0" : "=r"(TLSOffset)); 372349cc55cSDimitry Andric 373349cc55cSDimitry Andric TLSSection Section; 374349cc55cSDimitry Andric // We use the storage directly as the initialization image. This means that 375349cc55cSDimitry Andric // when a new thread is spawned after this allocation, it will not be 376349cc55cSDimitry Andric // initialized correctly. This means, llvm-rtdyld will only support TLS in a 377349cc55cSDimitry Andric // single thread. 378349cc55cSDimitry Andric Section.InitializationImage = 379349cc55cSDimitry Andric reinterpret_cast<uint8_t *>(LLVMRTDyldTLSSpace + UsedTLSStorage); 380349cc55cSDimitry Andric Section.Offset = TLSOffset + UsedTLSStorage; 381349cc55cSDimitry Andric 382349cc55cSDimitry Andric UsedTLSStorage += Size; 383349cc55cSDimitry Andric 384349cc55cSDimitry Andric return Section; 385349cc55cSDimitry Andric #else 386349cc55cSDimitry Andric return {}; 387349cc55cSDimitry Andric #endif 388349cc55cSDimitry Andric } 389349cc55cSDimitry Andric 3900b57cec5SDimitry Andric static const char *ProgramName; 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric static void ErrorAndExit(const Twine &Msg) { 3930b57cec5SDimitry Andric errs() << ProgramName << ": error: " << Msg << "\n"; 3940b57cec5SDimitry Andric exit(1); 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric static void loadDylibs() { 3980b57cec5SDimitry Andric for (const std::string &Dylib : Dylibs) { 3990b57cec5SDimitry Andric if (!sys::fs::is_regular_file(Dylib)) 400349cc55cSDimitry Andric report_fatal_error(Twine("Dylib not found: '") + Dylib + "'."); 4010b57cec5SDimitry Andric std::string ErrMsg; 4020b57cec5SDimitry Andric if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg)) 403349cc55cSDimitry Andric report_fatal_error(Twine("Error loading '") + Dylib + "': " + ErrMsg); 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric /* *** */ 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { 4100b57cec5SDimitry Andric assert(LoadObjects || !UseDebugObj); 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric // Load any dylibs requested on the command line. 4130b57cec5SDimitry Andric loadDylibs(); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric // If we don't have any input files, read from stdin. 4160b57cec5SDimitry Andric if (!InputFileList.size()) 4170b57cec5SDimitry Andric InputFileList.push_back("-"); 4180b57cec5SDimitry Andric for (auto &File : InputFileList) { 4190b57cec5SDimitry Andric // Instantiate a dynamic linker. 4200b57cec5SDimitry Andric TrivialMemoryManager MemMgr; 4210b57cec5SDimitry Andric RuntimeDyld Dyld(MemMgr, MemMgr); 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric // Load the input memory buffer. 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 4260b57cec5SDimitry Andric MemoryBuffer::getFileOrSTDIN(File); 4270b57cec5SDimitry Andric if (std::error_code EC = InputBuffer.getError()) 4280b57cec5SDimitry Andric ErrorAndExit("unable to read input: '" + EC.message() + "'"); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> MaybeObj( 4310b57cec5SDimitry Andric ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric if (!MaybeObj) { 4340b57cec5SDimitry Andric std::string Buf; 4350b57cec5SDimitry Andric raw_string_ostream OS(Buf); 4360b57cec5SDimitry Andric logAllUnhandledErrors(MaybeObj.takeError(), OS); 4370b57cec5SDimitry Andric OS.flush(); 4380b57cec5SDimitry Andric ErrorAndExit("unable to create object file: '" + Buf + "'"); 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric ObjectFile &Obj = **MaybeObj; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric OwningBinary<ObjectFile> DebugObj; 4440b57cec5SDimitry Andric std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; 4450b57cec5SDimitry Andric ObjectFile *SymbolObj = &Obj; 4460b57cec5SDimitry Andric if (LoadObjects) { 4470b57cec5SDimitry Andric // Load the object file 4480b57cec5SDimitry Andric LoadedObjInfo = 4490b57cec5SDimitry Andric Dyld.loadObject(Obj); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric if (Dyld.hasError()) 4520b57cec5SDimitry Andric ErrorAndExit(Dyld.getErrorString()); 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric // Resolve all the relocations we can. 4550b57cec5SDimitry Andric Dyld.resolveRelocations(); 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric if (UseDebugObj) { 4580b57cec5SDimitry Andric DebugObj = LoadedObjInfo->getObjectForDebug(Obj); 4590b57cec5SDimitry Andric SymbolObj = DebugObj.getBinary(); 4600b57cec5SDimitry Andric LoadedObjInfo.reset(); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 464349cc55cSDimitry Andric std::unique_ptr<DIContext> Context = DWARFContext::create( 465349cc55cSDimitry Andric *SymbolObj, DWARFContext::ProcessDebugRelocations::Process, 466349cc55cSDimitry Andric LoadedObjInfo.get()); 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = 4690b57cec5SDimitry Andric object::computeSymbolSizes(*SymbolObj); 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric // Use symbol info to iterate functions in the object. 4720b57cec5SDimitry Andric for (const auto &P : SymAddr) { 4730b57cec5SDimitry Andric object::SymbolRef Sym = P.first; 4740b57cec5SDimitry Andric Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); 4750b57cec5SDimitry Andric if (!TypeOrErr) { 4760b57cec5SDimitry Andric // TODO: Actually report errors helpfully. 4770b57cec5SDimitry Andric consumeError(TypeOrErr.takeError()); 4780b57cec5SDimitry Andric continue; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric SymbolRef::Type Type = *TypeOrErr; 4810b57cec5SDimitry Andric if (Type == object::SymbolRef::ST_Function) { 4820b57cec5SDimitry Andric Expected<StringRef> Name = Sym.getName(); 4830b57cec5SDimitry Andric if (!Name) { 4840b57cec5SDimitry Andric // TODO: Actually report errors helpfully. 4850b57cec5SDimitry Andric consumeError(Name.takeError()); 4860b57cec5SDimitry Andric continue; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric Expected<uint64_t> AddrOrErr = Sym.getAddress(); 4890b57cec5SDimitry Andric if (!AddrOrErr) { 4900b57cec5SDimitry Andric // TODO: Actually report errors helpfully. 4910b57cec5SDimitry Andric consumeError(AddrOrErr.takeError()); 4920b57cec5SDimitry Andric continue; 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric uint64_t Addr = *AddrOrErr; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric object::SectionedAddress Address; 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric uint64_t Size = P.second; 4990b57cec5SDimitry Andric // If we're not using the debug object, compute the address of the 5000b57cec5SDimitry Andric // symbol in memory (rather than that in the unrelocated object file) 5010b57cec5SDimitry Andric // and use that to query the DWARFContext. 5020b57cec5SDimitry Andric if (!UseDebugObj && LoadObjects) { 5030b57cec5SDimitry Andric auto SecOrErr = Sym.getSection(); 5040b57cec5SDimitry Andric if (!SecOrErr) { 5050b57cec5SDimitry Andric // TODO: Actually report errors helpfully. 5060b57cec5SDimitry Andric consumeError(SecOrErr.takeError()); 5070b57cec5SDimitry Andric continue; 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric object::section_iterator Sec = *SecOrErr; 5100b57cec5SDimitry Andric Address.SectionIndex = Sec->getIndex(); 5110b57cec5SDimitry Andric uint64_t SectionLoadAddress = 5120b57cec5SDimitry Andric LoadedObjInfo->getSectionLoadAddress(*Sec); 5130b57cec5SDimitry Andric if (SectionLoadAddress != 0) 5140b57cec5SDimitry Andric Addr += SectionLoadAddress - Sec->getAddress(); 5150b57cec5SDimitry Andric } else if (auto SecOrErr = Sym.getSection()) 5160b57cec5SDimitry Andric Address.SectionIndex = SecOrErr.get()->getIndex(); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric outs() << "Function: " << *Name << ", Size = " << Size 5190b57cec5SDimitry Andric << ", Addr = " << Addr << "\n"; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric Address.Address = Addr; 5220b57cec5SDimitry Andric DILineInfoTable Lines = 5230b57cec5SDimitry Andric Context->getLineInfoForAddressRange(Address, Size); 5240b57cec5SDimitry Andric for (auto &D : Lines) { 5250b57cec5SDimitry Andric outs() << " Line info @ " << D.first - Addr << ": " 5260b57cec5SDimitry Andric << D.second.FileName << ", line:" << D.second.Line << "\n"; 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric return 0; 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric static void doPreallocation(TrivialMemoryManager &MemMgr) { 5360b57cec5SDimitry Andric // Allocate a slab of memory upfront, if required. This is used if 5370b57cec5SDimitry Andric // we want to test small code models. 5380b57cec5SDimitry Andric if (static_cast<intptr_t>(PreallocMemory) < 0) 5390b57cec5SDimitry Andric report_fatal_error("Pre-allocated bytes of memory must be a positive integer."); 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric // FIXME: Limit the amount of memory that can be preallocated? 5420b57cec5SDimitry Andric if (PreallocMemory != 0) 5430b57cec5SDimitry Andric MemMgr.preallocateSlab(PreallocMemory); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric static int executeInput() { 5470b57cec5SDimitry Andric // Load any dylibs requested on the command line. 5480b57cec5SDimitry Andric loadDylibs(); 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric // Instantiate a dynamic linker. 5510b57cec5SDimitry Andric TrivialMemoryManager MemMgr; 5520b57cec5SDimitry Andric doPreallocation(MemMgr); 5530b57cec5SDimitry Andric RuntimeDyld Dyld(MemMgr, MemMgr); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // If we don't have any input files, read from stdin. 5560b57cec5SDimitry Andric if (!InputFileList.size()) 5570b57cec5SDimitry Andric InputFileList.push_back("-"); 5588bcb0991SDimitry Andric { 5598bcb0991SDimitry Andric TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr); 5600b57cec5SDimitry Andric for (auto &File : InputFileList) { 5610b57cec5SDimitry Andric // Load the input memory buffer. 5620b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 5630b57cec5SDimitry Andric MemoryBuffer::getFileOrSTDIN(File); 5640b57cec5SDimitry Andric if (std::error_code EC = InputBuffer.getError()) 5650b57cec5SDimitry Andric ErrorAndExit("unable to read input: '" + EC.message() + "'"); 5660b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> MaybeObj( 5670b57cec5SDimitry Andric ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric if (!MaybeObj) { 5700b57cec5SDimitry Andric std::string Buf; 5710b57cec5SDimitry Andric raw_string_ostream OS(Buf); 5720b57cec5SDimitry Andric logAllUnhandledErrors(MaybeObj.takeError(), OS); 5730b57cec5SDimitry Andric OS.flush(); 5740b57cec5SDimitry Andric ErrorAndExit("unable to create object file: '" + Buf + "'"); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric ObjectFile &Obj = **MaybeObj; 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric // Load the object file 5800b57cec5SDimitry Andric Dyld.loadObject(Obj); 5810b57cec5SDimitry Andric if (Dyld.hasError()) { 5820b57cec5SDimitry Andric ErrorAndExit(Dyld.getErrorString()); 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric } 5858bcb0991SDimitry Andric } 5860b57cec5SDimitry Andric 5878bcb0991SDimitry Andric { 5888bcb0991SDimitry Andric TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr); 5890b57cec5SDimitry Andric // Resove all the relocations we can. 5900b57cec5SDimitry Andric // FIXME: Error out if there are unresolved relocations. 5910b57cec5SDimitry Andric Dyld.resolveRelocations(); 5928bcb0991SDimitry Andric } 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // Get the address of the entry point (_main by default). 5950b57cec5SDimitry Andric void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); 5960b57cec5SDimitry Andric if (!MainAddress) 5970b57cec5SDimitry Andric ErrorAndExit("no definition for '" + EntryPoint + "'"); 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric // Invalidate the instruction cache for each loaded function. 6000b57cec5SDimitry Andric for (auto &FM : MemMgr.FunctionMemory) { 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric auto &FM_MB = FM.MB; 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric // Make sure the memory is executable. 6050b57cec5SDimitry Andric // setExecutable will call InvalidateInstructionCache. 6060b57cec5SDimitry Andric if (auto EC = sys::Memory::protectMappedMemory(FM_MB, 6070b57cec5SDimitry Andric sys::Memory::MF_READ | 6080b57cec5SDimitry Andric sys::Memory::MF_EXEC)) 6090b57cec5SDimitry Andric ErrorAndExit("unable to mark function executable: '" + EC.message() + 6100b57cec5SDimitry Andric "'"); 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric // Dispatch to _main(). 6140b57cec5SDimitry Andric errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric int (*Main)(int, const char**) = 6170b57cec5SDimitry Andric (int(*)(int,const char**)) uintptr_t(MainAddress); 6180b57cec5SDimitry Andric std::vector<const char *> Argv; 6190b57cec5SDimitry Andric // Use the name of the first input object module as argv[0] for the target. 6200b57cec5SDimitry Andric Argv.push_back(InputFileList[0].data()); 6210b57cec5SDimitry Andric for (auto &Arg : InputArgv) 6220b57cec5SDimitry Andric Argv.push_back(Arg.data()); 6230b57cec5SDimitry Andric Argv.push_back(nullptr); 6248bcb0991SDimitry Andric int Result = 0; 6258bcb0991SDimitry Andric { 6268bcb0991SDimitry Andric TimeRegion TR(Timers ? &Timers->RunTimer : nullptr); 6278bcb0991SDimitry Andric Result = Main(Argv.size() - 1, Argv.data()); 6288bcb0991SDimitry Andric } 6298bcb0991SDimitry Andric 6308bcb0991SDimitry Andric return Result; 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric static int checkAllExpressions(RuntimeDyldChecker &Checker) { 6340b57cec5SDimitry Andric for (const auto& CheckerFileName : CheckFiles) { 6350b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = 6360b57cec5SDimitry Andric MemoryBuffer::getFileOrSTDIN(CheckerFileName); 6370b57cec5SDimitry Andric if (std::error_code EC = CheckerFileBuf.getError()) 6380b57cec5SDimitry Andric ErrorAndExit("unable to read input '" + CheckerFileName + "': " + 6390b57cec5SDimitry Andric EC.message()); 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", 6420b57cec5SDimitry Andric CheckerFileBuf.get().get())) 6430b57cec5SDimitry Andric ErrorAndExit("some checks in '" + CheckerFileName + "' failed"); 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric return 0; 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric void applySpecificSectionMappings(RuntimeDyld &Dyld, 6490b57cec5SDimitry Andric const FileToSectionIDMap &FileToSecIDMap) { 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric for (StringRef Mapping : SpecificSectionMappings) { 652*0fca6ea1SDimitry Andric size_t EqualsIdx = Mapping.find_first_of('='); 6535ffd83dbSDimitry Andric std::string SectionIDStr = std::string(Mapping.substr(0, EqualsIdx)); 654*0fca6ea1SDimitry Andric size_t ComaIdx = Mapping.find_first_of(','); 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric if (ComaIdx == StringRef::npos) 6570b57cec5SDimitry Andric report_fatal_error("Invalid section specification '" + Mapping + 6580b57cec5SDimitry Andric "'. Should be '<file name>,<section name>=<addr>'"); 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric std::string FileName = SectionIDStr.substr(0, ComaIdx); 6610b57cec5SDimitry Andric std::string SectionName = SectionIDStr.substr(ComaIdx + 1); 6620b57cec5SDimitry Andric unsigned SectionID = 6630b57cec5SDimitry Andric ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName)); 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric auto* OldAddr = Dyld.getSectionContent(SectionID).data(); 6665ffd83dbSDimitry Andric std::string NewAddrStr = std::string(Mapping.substr(EqualsIdx + 1)); 6670b57cec5SDimitry Andric uint64_t NewAddr; 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric if (StringRef(NewAddrStr).getAsInteger(0, NewAddr)) 6700b57cec5SDimitry Andric report_fatal_error("Invalid section address in mapping '" + Mapping + 6710b57cec5SDimitry Andric "'."); 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andric Dyld.mapSectionAddress(OldAddr, NewAddr); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric // Scatter sections in all directions! 6780b57cec5SDimitry Andric // Remaps section addresses for -verify mode. The following command line options 6790b57cec5SDimitry Andric // can be used to customize the layout of the memory within the phony target's 6800b57cec5SDimitry Andric // address space: 6810b57cec5SDimitry Andric // -target-addr-start <s> -- Specify where the phony target address range starts. 6820b57cec5SDimitry Andric // -target-addr-end <e> -- Specify where the phony target address range ends. 6830b57cec5SDimitry Andric // -target-section-sep <d> -- Specify how big a gap should be left between the 6840b57cec5SDimitry Andric // end of one section and the start of the next. 6850b57cec5SDimitry Andric // Defaults to zero. Set to something big 6860b57cec5SDimitry Andric // (e.g. 1 << 32) to stress-test stubs, GOTs, etc. 6870b57cec5SDimitry Andric // 6880b57cec5SDimitry Andric static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, 6890b57cec5SDimitry Andric RuntimeDyld &Dyld, 6900b57cec5SDimitry Andric TrivialMemoryManager &MemMgr) { 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric // Set up a work list (section addr/size pairs). 6930b57cec5SDimitry Andric typedef std::list<const TrivialMemoryManager::SectionInfo*> WorklistT; 6940b57cec5SDimitry Andric WorklistT Worklist; 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric for (const auto& CodeSection : MemMgr.FunctionMemory) 6970b57cec5SDimitry Andric Worklist.push_back(&CodeSection); 6980b57cec5SDimitry Andric for (const auto& DataSection : MemMgr.DataMemory) 6990b57cec5SDimitry Andric Worklist.push_back(&DataSection); 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric // Keep an "already allocated" mapping of section target addresses to sizes. 7020b57cec5SDimitry Andric // Sections whose address mappings aren't specified on the command line will 7030b57cec5SDimitry Andric // allocated around the explicitly mapped sections while maintaining the 7040b57cec5SDimitry Andric // minimum separation. 7050b57cec5SDimitry Andric std::map<uint64_t, uint64_t> AlreadyAllocated; 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric // Move the previously applied mappings (whether explicitly specified on the 7080b57cec5SDimitry Andric // command line, or implicitly set by RuntimeDyld) into the already-allocated 7090b57cec5SDimitry Andric // map. 7100b57cec5SDimitry Andric for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); 7110b57cec5SDimitry Andric I != E;) { 7120b57cec5SDimitry Andric WorklistT::iterator Tmp = I; 7130b57cec5SDimitry Andric ++I; 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric auto LoadAddr = Dyld.getSectionLoadAddress((*Tmp)->SectionID); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric if (LoadAddr != static_cast<uint64_t>( 7180b57cec5SDimitry Andric reinterpret_cast<uintptr_t>((*Tmp)->MB.base()))) { 7190b57cec5SDimitry Andric // A section will have a LoadAddr of 0 if it wasn't loaded for whatever 7200b57cec5SDimitry Andric // reason (e.g. zero byte COFF sections). Don't include those sections in 7210b57cec5SDimitry Andric // the allocation map. 7220b57cec5SDimitry Andric if (LoadAddr != 0) 7230b57cec5SDimitry Andric AlreadyAllocated[LoadAddr] = (*Tmp)->MB.allocatedSize(); 7240b57cec5SDimitry Andric Worklist.erase(Tmp); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric } 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric // If the -target-addr-end option wasn't explicitly passed, then set it to a 7290b57cec5SDimitry Andric // sensible default based on the target triple. 7300b57cec5SDimitry Andric if (TargetAddrEnd.getNumOccurrences() == 0) { 7310b57cec5SDimitry Andric if (TargetTriple.isArch16Bit()) 7320b57cec5SDimitry Andric TargetAddrEnd = (1ULL << 16) - 1; 7330b57cec5SDimitry Andric else if (TargetTriple.isArch32Bit()) 7340b57cec5SDimitry Andric TargetAddrEnd = (1ULL << 32) - 1; 7350b57cec5SDimitry Andric // TargetAddrEnd already has a sensible default for 64-bit systems, so 7360b57cec5SDimitry Andric // there's nothing to do in the 64-bit case. 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric // Process any elements remaining in the worklist. 7400b57cec5SDimitry Andric while (!Worklist.empty()) { 7410b57cec5SDimitry Andric auto *CurEntry = Worklist.front(); 7420b57cec5SDimitry Andric Worklist.pop_front(); 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric uint64_t NextSectionAddr = TargetAddrStart; 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric for (const auto &Alloc : AlreadyAllocated) 7470b57cec5SDimitry Andric if (NextSectionAddr + CurEntry->MB.allocatedSize() + TargetSectionSep <= 7480b57cec5SDimitry Andric Alloc.first) 7490b57cec5SDimitry Andric break; 7500b57cec5SDimitry Andric else 7510b57cec5SDimitry Andric NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric Dyld.mapSectionAddress(CurEntry->MB.base(), NextSectionAddr); 7540b57cec5SDimitry Andric AlreadyAllocated[NextSectionAddr] = CurEntry->MB.allocatedSize(); 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric // Add dummy symbols to the memory manager. 7580b57cec5SDimitry Andric for (const auto &Mapping : DummySymbolMappings) { 7590b57cec5SDimitry Andric size_t EqualsIdx = Mapping.find_first_of('='); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric if (EqualsIdx == StringRef::npos) 762349cc55cSDimitry Andric report_fatal_error(Twine("Invalid dummy symbol specification '") + 763349cc55cSDimitry Andric Mapping + "'. Should be '<symbol name>=<addr>'"); 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric std::string Symbol = Mapping.substr(0, EqualsIdx); 7660b57cec5SDimitry Andric std::string AddrStr = Mapping.substr(EqualsIdx + 1); 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric uint64_t Addr; 7690b57cec5SDimitry Andric if (StringRef(AddrStr).getAsInteger(0, Addr)) 770349cc55cSDimitry Andric report_fatal_error(Twine("Invalid symbol mapping '") + Mapping + "'."); 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric MemMgr.addDummySymbol(Symbol, Addr); 7730b57cec5SDimitry Andric } 7740b57cec5SDimitry Andric } 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric // Load and link the objects specified on the command line, but do not execute 7770b57cec5SDimitry Andric // anything. Instead, attach a RuntimeDyldChecker instance and call it to 7780b57cec5SDimitry Andric // verify the correctness of the linked memory. 7790b57cec5SDimitry Andric static int linkAndVerify() { 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric // Check for missing triple. 7820b57cec5SDimitry Andric if (TripleName == "") 7830b57cec5SDimitry Andric ErrorAndExit("-triple required when running in -verify mode."); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric // Look up the target and build the disassembler. 7860b57cec5SDimitry Andric Triple TheTriple(Triple::normalize(TripleName)); 7870b57cec5SDimitry Andric std::string ErrorStr; 7880b57cec5SDimitry Andric const Target *TheTarget = 7890b57cec5SDimitry Andric TargetRegistry::lookupTarget("", TheTriple, ErrorStr); 7900b57cec5SDimitry Andric if (!TheTarget) 7910b57cec5SDimitry Andric ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr); 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric TripleName = TheTriple.getTriple(); 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric std::unique_ptr<MCSubtargetInfo> STI( 7960b57cec5SDimitry Andric TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); 7970b57cec5SDimitry Andric if (!STI) 7980b57cec5SDimitry Andric ErrorAndExit("Unable to create subtarget info!"); 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 8010b57cec5SDimitry Andric if (!MRI) 8020b57cec5SDimitry Andric ErrorAndExit("Unable to create target register info!"); 8030b57cec5SDimitry Andric 804480093f4SDimitry Andric MCTargetOptions MCOptions; 805480093f4SDimitry Andric std::unique_ptr<MCAsmInfo> MAI( 806480093f4SDimitry Andric TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 8070b57cec5SDimitry Andric if (!MAI) 8080b57cec5SDimitry Andric ErrorAndExit("Unable to create target asm info!"); 8090b57cec5SDimitry Andric 810fe6060f1SDimitry Andric MCContext Ctx(Triple(TripleName), MAI.get(), MRI.get(), STI.get()); 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric std::unique_ptr<MCDisassembler> Disassembler( 8130b57cec5SDimitry Andric TheTarget->createMCDisassembler(*STI, Ctx)); 8140b57cec5SDimitry Andric if (!Disassembler) 8150b57cec5SDimitry Andric ErrorAndExit("Unable to create disassembler!"); 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 818e8d8bef9SDimitry Andric if (!MII) 819e8d8bef9SDimitry Andric ErrorAndExit("Unable to create target instruction info!"); 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric std::unique_ptr<MCInstPrinter> InstPrinter( 8220b57cec5SDimitry Andric TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric // Load any dylibs requested on the command line. 8250b57cec5SDimitry Andric loadDylibs(); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric // Instantiate a dynamic linker. 8280b57cec5SDimitry Andric TrivialMemoryManager MemMgr; 8290b57cec5SDimitry Andric doPreallocation(MemMgr); 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric struct StubID { 8320b57cec5SDimitry Andric unsigned SectionID; 8330b57cec5SDimitry Andric uint32_t Offset; 8340b57cec5SDimitry Andric }; 8350b57cec5SDimitry Andric using StubInfos = StringMap<StubID>; 8360b57cec5SDimitry Andric using StubContainers = StringMap<StubInfos>; 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric StubContainers StubMap; 8390b57cec5SDimitry Andric RuntimeDyld Dyld(MemMgr, MemMgr); 8400b57cec5SDimitry Andric Dyld.setProcessAllSections(true); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric Dyld.setNotifyStubEmitted([&StubMap](StringRef FilePath, 8430b57cec5SDimitry Andric StringRef SectionName, 8440b57cec5SDimitry Andric StringRef SymbolName, unsigned SectionID, 8450b57cec5SDimitry Andric uint32_t StubOffset) { 8460b57cec5SDimitry Andric std::string ContainerName = 8470b57cec5SDimitry Andric (sys::path::filename(FilePath) + "/" + SectionName).str(); 8480b57cec5SDimitry Andric StubMap[ContainerName][SymbolName] = {SectionID, StubOffset}; 8490b57cec5SDimitry Andric }); 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric auto GetSymbolInfo = 8520b57cec5SDimitry Andric [&Dyld, &MemMgr]( 8530b57cec5SDimitry Andric StringRef Symbol) -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 8540b57cec5SDimitry Andric RuntimeDyldChecker::MemoryRegionInfo SymInfo; 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric // First get the target address. 8570b57cec5SDimitry Andric if (auto InternalSymbol = Dyld.getSymbol(Symbol)) 8580b57cec5SDimitry Andric SymInfo.setTargetAddress(InternalSymbol.getAddress()); 8590b57cec5SDimitry Andric else { 8600b57cec5SDimitry Andric // Symbol not found in RuntimeDyld. Fall back to external lookup. 8610b57cec5SDimitry Andric #ifdef _MSC_VER 8620b57cec5SDimitry Andric using ExpectedLookupResult = 8630b57cec5SDimitry Andric MSVCPExpected<JITSymbolResolver::LookupResult>; 8640b57cec5SDimitry Andric #else 8650b57cec5SDimitry Andric using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>; 8660b57cec5SDimitry Andric #endif 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>(); 8690b57cec5SDimitry Andric auto ResultF = ResultP->get_future(); 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric MemMgr.lookup(JITSymbolResolver::LookupSet({Symbol}), 8720b57cec5SDimitry Andric [=](Expected<JITSymbolResolver::LookupResult> Result) { 8730b57cec5SDimitry Andric ResultP->set_value(std::move(Result)); 8740b57cec5SDimitry Andric }); 8750b57cec5SDimitry Andric 8760b57cec5SDimitry Andric auto Result = ResultF.get(); 8770b57cec5SDimitry Andric if (!Result) 8780b57cec5SDimitry Andric return Result.takeError(); 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric auto I = Result->find(Symbol); 8810b57cec5SDimitry Andric assert(I != Result->end() && 8820b57cec5SDimitry Andric "Expected symbol address if no error occurred"); 8830b57cec5SDimitry Andric SymInfo.setTargetAddress(I->second.getAddress()); 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric 8860b57cec5SDimitry Andric // Now find the symbol content if possible (otherwise leave content as a 8870b57cec5SDimitry Andric // default-constructed StringRef). 8880b57cec5SDimitry Andric if (auto *SymAddr = Dyld.getSymbolLocalAddress(Symbol)) { 8890b57cec5SDimitry Andric unsigned SectionID = Dyld.getSymbolSectionID(Symbol); 8900b57cec5SDimitry Andric if (SectionID != ~0U) { 8910b57cec5SDimitry Andric char *CSymAddr = static_cast<char *>(SymAddr); 8920b57cec5SDimitry Andric StringRef SecContent = Dyld.getSectionContent(SectionID); 8930b57cec5SDimitry Andric uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data()); 894fe6060f1SDimitry Andric SymInfo.setContent(ArrayRef<char>(CSymAddr, SymSize)); 8955f757f3fSDimitry Andric SymInfo.setTargetFlags( 8965f757f3fSDimitry Andric Dyld.getSymbol(Symbol).getFlags().getTargetFlags()); 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric return SymInfo; 9000b57cec5SDimitry Andric }; 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric auto IsSymbolValid = [&Dyld, GetSymbolInfo](StringRef Symbol) { 9030b57cec5SDimitry Andric if (Dyld.getSymbol(Symbol)) 9040b57cec5SDimitry Andric return true; 9050b57cec5SDimitry Andric auto SymInfo = GetSymbolInfo(Symbol); 9060b57cec5SDimitry Andric if (!SymInfo) { 9070b57cec5SDimitry Andric logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: "); 9080b57cec5SDimitry Andric return false; 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric return SymInfo->getTargetAddress() != 0; 9110b57cec5SDimitry Andric }; 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric FileToSectionIDMap FileToSecIDMap; 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric auto GetSectionInfo = [&Dyld, &FileToSecIDMap](StringRef FileName, 9160b57cec5SDimitry Andric StringRef SectionName) 9170b57cec5SDimitry Andric -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 9180b57cec5SDimitry Andric auto SectionID = getSectionId(FileToSecIDMap, FileName, SectionName); 9190b57cec5SDimitry Andric if (!SectionID) 9200b57cec5SDimitry Andric return SectionID.takeError(); 9210b57cec5SDimitry Andric RuntimeDyldChecker::MemoryRegionInfo SecInfo; 9220b57cec5SDimitry Andric SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID)); 923fe6060f1SDimitry Andric StringRef SecContent = Dyld.getSectionContent(*SectionID); 924fe6060f1SDimitry Andric SecInfo.setContent(ArrayRef<char>(SecContent.data(), SecContent.size())); 9250b57cec5SDimitry Andric return SecInfo; 9260b57cec5SDimitry Andric }; 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer, 9297a6dacacSDimitry Andric StringRef SymbolName, 9307a6dacacSDimitry Andric StringRef KindNameFilter) 9310b57cec5SDimitry Andric -> Expected<RuntimeDyldChecker::MemoryRegionInfo> { 9320b57cec5SDimitry Andric if (!StubMap.count(StubContainer)) 9330b57cec5SDimitry Andric return make_error<StringError>("Stub container not found: " + 9340b57cec5SDimitry Andric StubContainer, 9350b57cec5SDimitry Andric inconvertibleErrorCode()); 9360b57cec5SDimitry Andric if (!StubMap[StubContainer].count(SymbolName)) 9370b57cec5SDimitry Andric return make_error<StringError>("Symbol name " + SymbolName + 9380b57cec5SDimitry Andric " in stub container " + StubContainer, 9390b57cec5SDimitry Andric inconvertibleErrorCode()); 9400b57cec5SDimitry Andric auto &SI = StubMap[StubContainer][SymbolName]; 9410b57cec5SDimitry Andric RuntimeDyldChecker::MemoryRegionInfo StubMemInfo; 9420b57cec5SDimitry Andric StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) + 9430b57cec5SDimitry Andric SI.Offset); 944fe6060f1SDimitry Andric StringRef SecContent = 945fe6060f1SDimitry Andric Dyld.getSectionContent(SI.SectionID).substr(SI.Offset); 9460b57cec5SDimitry Andric StubMemInfo.setContent( 947fe6060f1SDimitry Andric ArrayRef<char>(SecContent.data(), SecContent.size())); 9480b57cec5SDimitry Andric return StubMemInfo; 9490b57cec5SDimitry Andric }; 9500b57cec5SDimitry Andric 9517a6dacacSDimitry Andric auto GetGOTInfo = [&GetStubInfo](StringRef StubContainer, 9527a6dacacSDimitry Andric StringRef SymbolName) { 9537a6dacacSDimitry Andric return GetStubInfo(StubContainer, SymbolName, ""); 9547a6dacacSDimitry Andric }; 9557a6dacacSDimitry Andric 9560b57cec5SDimitry Andric // We will initialize this below once we have the first object file and can 9570b57cec5SDimitry Andric // know the endianness. 9580b57cec5SDimitry Andric std::unique_ptr<RuntimeDyldChecker> Checker; 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric // If we don't have any input files, read from stdin. 9610b57cec5SDimitry Andric if (!InputFileList.size()) 9620b57cec5SDimitry Andric InputFileList.push_back("-"); 9630b57cec5SDimitry Andric for (auto &InputFile : InputFileList) { 9640b57cec5SDimitry Andric // Load the input memory buffer. 9650b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 9660b57cec5SDimitry Andric MemoryBuffer::getFileOrSTDIN(InputFile); 9670b57cec5SDimitry Andric 9680b57cec5SDimitry Andric if (std::error_code EC = InputBuffer.getError()) 9690b57cec5SDimitry Andric ErrorAndExit("unable to read input: '" + EC.message() + "'"); 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> MaybeObj( 9720b57cec5SDimitry Andric ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric if (!MaybeObj) { 9750b57cec5SDimitry Andric std::string Buf; 9760b57cec5SDimitry Andric raw_string_ostream OS(Buf); 9770b57cec5SDimitry Andric logAllUnhandledErrors(MaybeObj.takeError(), OS); 9780b57cec5SDimitry Andric OS.flush(); 9790b57cec5SDimitry Andric ErrorAndExit("unable to create object file: '" + Buf + "'"); 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric 9820b57cec5SDimitry Andric ObjectFile &Obj = **MaybeObj; 9830b57cec5SDimitry Andric 9840b57cec5SDimitry Andric if (!Checker) 9858bcb0991SDimitry Andric Checker = std::make_unique<RuntimeDyldChecker>( 9867a6dacacSDimitry Andric IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo, 9875f757f3fSDimitry Andric Obj.isLittleEndian() ? llvm::endianness::little 9885f757f3fSDimitry Andric : llvm::endianness::big, 9895f757f3fSDimitry Andric TheTriple, MCPU, SubtargetFeatures(), dbgs()); 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric auto FileName = sys::path::filename(InputFile); 9920b57cec5SDimitry Andric MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]); 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric // Load the object file 9950b57cec5SDimitry Andric Dyld.loadObject(Obj); 9960b57cec5SDimitry Andric if (Dyld.hasError()) { 9970b57cec5SDimitry Andric ErrorAndExit(Dyld.getErrorString()); 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric } 10000b57cec5SDimitry Andric 10010b57cec5SDimitry Andric // Re-map the section addresses into the phony target address space and add 10020b57cec5SDimitry Andric // dummy symbols. 10030b57cec5SDimitry Andric applySpecificSectionMappings(Dyld, FileToSecIDMap); 10040b57cec5SDimitry Andric remapSectionsAndSymbols(TheTriple, Dyld, MemMgr); 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric // Resolve all the relocations we can. 10070b57cec5SDimitry Andric Dyld.resolveRelocations(); 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric // Register EH frames. 10100b57cec5SDimitry Andric Dyld.registerEHFrames(); 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric int ErrorCode = checkAllExpressions(*Checker); 10130b57cec5SDimitry Andric if (Dyld.hasError()) 10140b57cec5SDimitry Andric ErrorAndExit("RTDyld reported an error applying relocations:\n " + 10150b57cec5SDimitry Andric Dyld.getErrorString()); 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric return ErrorCode; 10180b57cec5SDimitry Andric } 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric int main(int argc, char **argv) { 10210b57cec5SDimitry Andric InitLLVM X(argc, argv); 10220b57cec5SDimitry Andric ProgramName = argv[0]; 10230b57cec5SDimitry Andric 10240b57cec5SDimitry Andric llvm::InitializeAllTargetInfos(); 10250b57cec5SDimitry Andric llvm::InitializeAllTargetMCs(); 10260b57cec5SDimitry Andric llvm::InitializeAllDisassemblers(); 10270b57cec5SDimitry Andric 1028fe6060f1SDimitry Andric cl::HideUnrelatedOptions({&RTDyldCategory, &getColorCategory()}); 10290b57cec5SDimitry Andric cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric ExitOnErr.setBanner(std::string(argv[0]) + ": "); 10320b57cec5SDimitry Andric 10338bcb0991SDimitry Andric Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr; 10348bcb0991SDimitry Andric 1035349cc55cSDimitry Andric int Result = 0; 10360b57cec5SDimitry Andric switch (Action) { 10370b57cec5SDimitry Andric case AC_Execute: 10388bcb0991SDimitry Andric Result = executeInput(); 10398bcb0991SDimitry Andric break; 10400b57cec5SDimitry Andric case AC_PrintDebugLineInfo: 10418bcb0991SDimitry Andric Result = 10428bcb0991SDimitry Andric printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ true); 10438bcb0991SDimitry Andric break; 10440b57cec5SDimitry Andric case AC_PrintLineInfo: 10458bcb0991SDimitry Andric Result = 10468bcb0991SDimitry Andric printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ false); 10478bcb0991SDimitry Andric break; 10480b57cec5SDimitry Andric case AC_PrintObjectLineInfo: 10498bcb0991SDimitry Andric Result = 10508bcb0991SDimitry Andric printLineInfoForInput(/* LoadObjects */ false, /* UseDebugObj */ false); 10518bcb0991SDimitry Andric break; 10520b57cec5SDimitry Andric case AC_Verify: 10538bcb0991SDimitry Andric Result = linkAndVerify(); 10548bcb0991SDimitry Andric break; 10550b57cec5SDimitry Andric } 10568bcb0991SDimitry Andric return Result; 10570b57cec5SDimitry Andric } 1058