11cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===// 21cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// 31cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// The LLVM Compiler Infrastructure 41cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// 51cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// This file is distributed under the University of Illinois Open Source 61cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// License. See LICENSE.TXT for details. 71cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// 81cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//===----------------------------------------------------------------------===// 91cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// 101cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// This is a testing tool for use with the MC-JIT LLVM components. 111cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// 121cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//===----------------------------------------------------------------------===// 131cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 14f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/StringMap.h" 156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/DebugInfo/DIContext.h" 166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/DebugInfo/DWARF/DWARFContext.h" 170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 18f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ExecutionEngine/RuntimeDyld.h" 19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 20c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCAsmInfo.h" 21c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCContext.h" 22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/MC/MCDisassembler/MCDisassembler.h" 23c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCInstPrinter.h" 24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCInstrInfo.h" 25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCRegisterInfo.h" 266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSubtargetInfo.h" 272173e1839c2d00f7f980450dd537047b7b376e6bRafael Espindola#include "llvm/Object/MachO.h" 28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Object/SymbolSize.h" 291cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/CommandLine.h" 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/DynamicLibrary.h" 311cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/ManagedStatic.h" 321cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/Memory.h" 331cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/MemoryBuffer.h" 344d6b695c953462c3317e3a7eb57d0534db858ac2Alp Toker#include "llvm/Support/PrettyStackTrace.h" 35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/Signals.h" 36c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetRegistry.h" 37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetSelect.h" 38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/raw_ostream.h" 3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include <list> 40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 41c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 421cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachusing namespace llvm; 431cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachusing namespace llvm::object; 441cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 454f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbachstatic cl::list<std::string> 464f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim GrosbachInputFileList(cl::Positional, cl::ZeroOrMore, 474f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach cl::desc("<input file>")); 481cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 491cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachenum ActionType { 50ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor AC_Execute, 516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AC_PrintObjectLineInfo, 52c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AC_PrintLineInfo, 536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AC_PrintDebugLineInfo, 54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AC_Verify 551cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach}; 561cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 571cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachstatic cl::opt<ActionType> 581cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim GrosbachAction(cl::desc("Action to perform:"), 591cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach cl::init(AC_Execute), 601cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach cl::values(clEnumValN(AC_Execute, "execute", 611cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach "Load, link, and execute the inputs."), 62ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor clEnumValN(AC_PrintLineInfo, "printline", 63ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor "Load, link, and print line information for each function."), 646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar clEnumValN(AC_PrintDebugLineInfo, "printdebugline", 656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "Load, link, and print line information for each function using the debug object"), 666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar clEnumValN(AC_PrintObjectLineInfo, "printobjline", 676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "Like -printlineinfo but does not load the object first"), 68c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines clEnumValN(AC_Verify, "verify", 69c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines "Load, link and verify the resulting memory image."), 701cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach clEnumValEnd)); 711cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 726b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbachstatic cl::opt<std::string> 736b32e7e213ca14d5d898c84053d6f38a4c360763Jim GrosbachEntryPoint("entry", 746b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach cl::desc("Function to call as entry point."), 756b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach cl::init("_main")); 766b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::list<std::string> 78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDylibs("dylib", 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::desc("Add library."), 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::ZeroOrMore); 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 82c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic cl::opt<std::string> 83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesTripleName("triple", cl::desc("Target triple for disassembler")); 84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<std::string> 86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarMCPU("mcpu", 87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("Target a specific cpu type (-mcpu=help for details)"), 88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::value_desc("cpu-name"), 89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::init("")); 90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 91c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic cl::list<std::string> 92c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCheckFiles("check", 93c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::desc("File containing RuntimeDyld verifier checks."), 94c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::ZeroOrMore); 95c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<uint64_t> 97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarPreallocMemory("preallocate", 98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("Allocate memory upfront rather than on-demand"), 99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::init(0)); 100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<uint64_t> 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTargetAddrStart("target-addr-start", 10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("For -verify only: start of phony target address " 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "range."), 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::init(4096), // Start at "page 1" - no allocating at "null". 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::Hidden); 10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<uint64_t> 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTargetAddrEnd("target-addr-end", 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("For -verify only: end of phony target address range."), 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::init(~0ULL), 11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::Hidden); 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<uint64_t> 11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTargetSectionSep("target-section-sep", 11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("For -verify only: Separation between sections in " 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "phony target address space."), 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::init(0), 11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::Hidden); 12037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::list<std::string> 12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesSpecificSectionMappings("map-section", 123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("For -verify only: Map a section to a " 124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "specific address."), 125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::ZeroOrMore, 126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden); 127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::list<std::string> 129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarDummySymbolMappings("dummy-extern", 130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("For -verify only: Inject a symbol into the extern " 131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "symbol table."), 132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::ZeroOrMore, 133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden); 134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<bool> 136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarPrintAllocationRequests("print-alloc-requests", 137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("Print allocation requests made to the memory " 138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "manager by RuntimeDyld"), 139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden); 14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1411cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach/* *** */ 1421cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 143fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach// A trivial memory manager that doesn't do anything fancy, just uses the 144fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach// support library allocation routines directly. 145fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbachclass TrivialMemoryManager : public RTDyldMemoryManager { 146fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbachpublic: 1477cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach SmallVector<sys::MemoryBlock, 16> FunctionMemory; 14861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<sys::MemoryBlock, 16> DataMemory; 14961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 15061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID, 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SectionName) override; 15361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 1546eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo unsigned SectionID, StringRef SectionName, 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsReadOnly) override; 1567cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void *getPointerToNamedFunction(const std::string &Name, 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool AbortOnFailure = true) override { 159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 16030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 16130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool finalizeMemory(std::string *ErrMsg) override { return false; } 16353608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor 164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void addDummySymbol(const std::string &Name, uint64_t Addr) { 165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DummyExterns[Name] = Addr; 166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override { 169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto I = DummyExterns.find(Name); 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I != DummyExterns.end()) 172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return RuntimeDyld::SymbolInfo(I->second, JITSymbolFlags::Exported); 173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return RTDyldMemoryManager::findSymbol(Name); 175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 1786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar size_t Size) override {} 1796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, 1806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar size_t Size) override {} 181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void preallocateSlab(uint64_t Size) { 183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string Err; 184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err); 185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MB.base()) 186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Can't allocate enough memory: " + Err); 187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PreallocSlab = MB; 189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar UsePreallocation = true; 190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SlabSize = Size; 191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode) { 194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Size = alignTo(Size, Alignment); 195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (CurrentSlabOffset + Size > SlabSize) 196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Can't allocate enough memory. Tune --preallocate"); 197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uintptr_t OldSlabOffset = CurrentSlabOffset; 199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock MB((void *)OldSlabOffset, Size); 200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (isCode) 201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FunctionMemory.push_back(MB); 202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DataMemory.push_back(MB); 204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CurrentSlabOffset += Size; 205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return (uint8_t*)OldSlabOffset; 206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarprivate: 209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::map<std::string, uint64_t> DummyExterns; 210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock PreallocSlab; 211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool UsePreallocation = false; 212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uintptr_t SlabSize = 0; 213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uintptr_t CurrentSlabOffset = 0; 214fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach}; 215fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach 21661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachuint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 21761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned Alignment, 2186eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo unsigned SectionID, 2196eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo StringRef SectionName) { 220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (PrintAllocationRequests) 221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " 222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << Alignment << ", SectionName = " << SectionName << ")\n"; 223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (UsePreallocation) 225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return allocateFromSlab(Size, Alignment, true /* isCode */); 226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string Err; 228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err); 229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MB.base()) 230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("MemoryManager allocation failed: " + Err); 231068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev FunctionMemory.push_back(MB); 232068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev return (uint8_t*)MB.base(); 23361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 23461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 23561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachuint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 23661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned Alignment, 23753608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor unsigned SectionID, 2386eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo StringRef SectionName, 23953608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor bool IsReadOnly) { 240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (PrintAllocationRequests) 241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar outs() << "allocateDataSection(Size = " << Size << ", Alignment = " 242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << Alignment << ", SectionName = " << SectionName << ")\n"; 243068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev 244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (UsePreallocation) 245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return allocateFromSlab(Size, Alignment, false /* isCode */); 246068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev 247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string Err; 248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err); 249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MB.base()) 250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("MemoryManager allocation failed: " + Err); 251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DataMemory.push_back(MB); 252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return (uint8_t*)MB.base(); 25361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 25461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 2551cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachstatic const char *ProgramName; 2561cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void ErrorAndExit(const Twine &Msg) { 258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar errs() << ProgramName << ": error: " << Msg << "\n"; 259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar exit(1); 2601cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach} 2611cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void loadDylibs() { 263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const std::string &Dylib : Dylibs) { 264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!sys::fs::is_regular_file(Dylib)) 265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Dylib not found: '" + Dylib + "'."); 266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string ErrMsg; 267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg)) 268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg); 269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2721cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach/* *** */ 27335fdeb7b373e416ff00c54abef12e786963af725Jim Grosbach 2746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { 2756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(LoadObjects || !UseDebugObj); 2766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Load any dylibs requested on the command line. 278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines loadDylibs(); 279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 280ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor // If we don't have any input files, read from stdin. 281ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor if (!InputFileList.size()) 282ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor InputFileList.push_back("-"); 283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &File : InputFileList) { 284ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor // Instantiate a dynamic linker. 285a757e936263d0a95cbacff4fedd4703e5185800cBenjamin Kramer TrivialMemoryManager MemMgr; 2860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar RuntimeDyld Dyld(MemMgr, MemMgr); 287ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 288ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor // Load the input memory buffer. 289ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 290c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemoryBuffer::getFileOrSTDIN(File); 292c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = InputBuffer.getError()) 293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to read input: '" + EC.message() + "'"); 294c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Expected<std::unique_ptr<ObjectFile>> MaybeObj( 296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MaybeObj) { 299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::string Buf; 300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_string_ostream OS(Buf); 301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); 302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.flush(); 303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to create object file: '" + Buf + "'"); 304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjectFile &Obj = **MaybeObj; 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OwningBinary<ObjectFile> DebugObj; 3096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; 3106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ObjectFile *SymbolObj = &Obj; 3116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (LoadObjects) { 3126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Load the object file 3136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar LoadedObjInfo = 3146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Dyld.loadObject(Obj); 315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Dyld.hasError()) 317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit(Dyld.getErrorString()); 318ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 3196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Resolve all the relocations we can. 3206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Dyld.resolveRelocations(); 321ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 3226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (UseDebugObj) { 3236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DebugObj = LoadedObjInfo->getObjectForDebug(Obj); 3246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymbolObj = DebugObj.getBinary(); 325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LoadedObjInfo.reset(); 3266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 3276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<DIContext> Context( 3306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); 3316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = 333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar object::computeSymbolSizes(*SymbolObj); 334ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 335ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor // Use symbol info to iterate functions in the object. 336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const auto &P : SymAddr) { 337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar object::SymbolRef Sym = P.first; 338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); 339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!TypeOrErr) { 340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TODO: Actually report errors helpfully. 341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar consumeError(TypeOrErr.takeError()); 342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SymbolRef::Type Type = *TypeOrErr; 345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Type == object::SymbolRef::ST_Function) { 346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Expected<StringRef> Name = Sym.getName(); 347de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Name) { 348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TODO: Actually report errors helpfully. 349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar consumeError(Name.takeError()); 3506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Expected<uint64_t> AddrOrErr = Sym.getAddress(); 353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!AddrOrErr) { 354de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TODO: Actually report errors helpfully. 355de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar consumeError(AddrOrErr.takeError()); 3566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uint64_t Addr = *AddrOrErr; 3596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uint64_t Size = P.second; 3616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // If we're not using the debug object, compute the address of the 3626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // symbol in memory (rather than that in the unrelocated object file) 3636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // and use that to query the DWARFContext. 3646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!UseDebugObj && LoadObjects) { 365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto SecOrErr = Sym.getSection(); 366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!SecOrErr) { 367de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TODO: Actually report errors helpfully. 368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar consumeError(SecOrErr.takeError()); 369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar object::section_iterator Sec = *SecOrErr; 3726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StringRef SecName; 3736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Sec->getName(SecName); 3746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t SectionLoadAddress = 375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LoadedObjInfo->getSectionLoadAddress(*Sec); 3766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (SectionLoadAddress != 0) 3776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Addr += SectionLoadAddress - Sec->getAddress(); 3786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 379ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar outs() << "Function: " << *Name << ", Size = " << Size 381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << ", Addr = " << Addr << "\n"; 382ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 383e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); 384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &D : Lines) { 385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar outs() << " Line info @ " << D.first - Addr << ": " 386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << D.second.FileName << ", line:" << D.second.Line << "\n"; 387e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor } 388ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor } 389ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor } 390ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor } 391ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 392ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor return 0; 393ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor} 394ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor 395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void doPreallocation(TrivialMemoryManager &MemMgr) { 396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Allocate a slab of memory upfront, if required. This is used if 397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // we want to test small code models. 398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (static_cast<intptr_t>(PreallocMemory) < 0) 399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Pre-allocated bytes of memory must be a positive integer."); 400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // FIXME: Limit the amount of memory that can be preallocated? 402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (PreallocMemory != 0) 403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemMgr.preallocateSlab(PreallocMemory); 404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 40635fdeb7b373e416ff00c54abef12e786963af725Jim Grosbachstatic int executeInput() { 407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Load any dylibs requested on the command line. 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines loadDylibs(); 409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 4106e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach // Instantiate a dynamic linker. 411a757e936263d0a95cbacff4fedd4703e5185800cBenjamin Kramer TrivialMemoryManager MemMgr; 412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar doPreallocation(MemMgr); 4130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar RuntimeDyld Dyld(MemMgr, MemMgr); 4140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 4154f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach // If we don't have any input files, read from stdin. 4164f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach if (!InputFileList.size()) 4174f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach InputFileList.push_back("-"); 418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &File : InputFileList) { 4194f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach // Load the input memory buffer. 420c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemoryBuffer::getFileOrSTDIN(File); 422c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = InputBuffer.getError()) 423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to read input: '" + EC.message() + "'"); 424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Expected<std::unique_ptr<ObjectFile>> MaybeObj( 425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MaybeObj) { 428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::string Buf; 429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_string_ostream OS(Buf); 430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); 431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.flush(); 432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to create object file: '" + Buf + "'"); 433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjectFile &Obj = **MaybeObj; 436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 4373f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // Load the object file 438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Dyld.loadObject(Obj); 439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Dyld.hasError()) { 440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit(Dyld.getErrorString()); 4414f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach } 442b3eecaf19e81f0cccffdeff940afbfd1a3754af2Jim Grosbach } 4434f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach 444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Resove all the relocations we can. 4454f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach // FIXME: Error out if there are unresolved relocations. 446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Dyld.resolveRelocations(); 4474f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach 4486b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach // Get the address of the entry point (_main by default). 4494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); 450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!MainAddress) 451de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("no definition for '" + EntryPoint + "'"); 4521cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 4537cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach // Invalidate the instruction cache for each loaded function. 454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &FM : MemMgr.FunctionMemory) { 455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 4567cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach // Make sure the memory is executable. 457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // setExecutable will call InvalidateInstructionCache. 4587cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach std::string ErrorStr; 459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!sys::Memory::setExecutable(FM, &ErrorStr)) 460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to mark function executable: '" + ErrorStr + "'"); 4617cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach } 4621cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 4631cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach // Dispatch to _main(). 4644f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; 4651cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 4661cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach int (*Main)(int, const char**) = 4671cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach (int(*)(int,const char**)) uintptr_t(MainAddress); 4681cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach const char **Argv = new const char*[2]; 4694f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach // Use the name of the first input object module as argv[0] for the target. 4704f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach Argv[0] = InputFileList[0].c_str(); 471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Argv[1] = nullptr; 4721cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach return Main(1, Argv); 4731cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach} 4741cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 475c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic int checkAllExpressions(RuntimeDyldChecker &Checker) { 476c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto& CheckerFileName : CheckFiles) { 477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = 478c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MemoryBuffer::getFileOrSTDIN(CheckerFileName); 479c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = CheckerFileBuf.getError()) 480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to read input '" + CheckerFileName + "': " + 481c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EC.message()); 482c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 483c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", 484c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines CheckerFileBuf.get().get())) 485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("some checks in '" + CheckerFileName + "' failed"); 486c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 487c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return 0; 488c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 489c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 4904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic std::map<void *, uint64_t> 49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesapplySpecificSectionMappings(RuntimeDyldChecker &Checker) { 49237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 49337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::map<void*, uint64_t> SpecificMappings; 49437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 49537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (StringRef Mapping : SpecificSectionMappings) { 49637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines size_t EqualsIdx = Mapping.find_first_of("="); 498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string SectionIDStr = Mapping.substr(0, EqualsIdx); 49937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines size_t ComaIdx = Mapping.find_first_of(","); 50037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (ComaIdx == StringRef::npos) 502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Invalid section specification '" + Mapping + 503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "'. Should be '<file name>,<section name>=<addr>'"); 50437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string FileName = SectionIDStr.substr(0, ComaIdx); 506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string SectionName = SectionIDStr.substr(ComaIdx + 1); 50737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 50837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t OldAddrInt; 50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string ErrorMsg; 51037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::tie(OldAddrInt, ErrorMsg) = 51137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Checker.getSectionAddr(FileName, SectionName, true); 51237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (ErrorMsg != "") 514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error(ErrorMsg); 51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 51637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void* OldAddr = reinterpret_cast<void*>(static_cast<uintptr_t>(OldAddrInt)); 51737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string NewAddrStr = Mapping.substr(EqualsIdx + 1); 51937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t NewAddr; 52037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (StringRef(NewAddrStr).getAsInteger(0, NewAddr)) 522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Invalid section address in mapping '" + Mapping + 523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "'."); 52437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 52537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr); 52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SpecificMappings[OldAddr] = NewAddr; 52737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 52937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return SpecificMappings; 53037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 53137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 53237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Scatter sections in all directions! 53337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Remaps section addresses for -verify mode. The following command line options 53437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// can be used to customize the layout of the memory within the phony target's 53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// address space: 53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// -target-addr-start <s> -- Specify where the phony target addres range starts. 53737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// -target-addr-end <e> -- Specify where the phony target address range ends. 53837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// -target-section-sep <d> -- Specify how big a gap should be left between the 53937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// end of one section and the start of the next. 54037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Defaults to zero. Set to something big 54137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// (e.g. 1 << 32) to stress-test stubs, GOTs, etc. 54237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, 544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TrivialMemoryManager &MemMgr, 545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RuntimeDyldChecker &Checker) { 54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Set up a work list (section addr/size pairs). 54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines typedef std::list<std::pair<void*, uint64_t>> WorklistT; 54937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines WorklistT Worklist; 55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto& CodeSection : MemMgr.FunctionMemory) 55237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size())); 55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto& DataSection : MemMgr.DataMemory) 55437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size())); 55537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 55637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Apply any section-specific mappings that were requested on the command 55737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // line. 55837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines typedef std::map<void*, uint64_t> AppliedMappingsT; 55937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker); 56037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 56137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Keep an "already allocated" mapping of section target addresses to sizes. 56237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Sections whose address mappings aren't specified on the command line will 56337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // allocated around the explicitly mapped sections while maintaining the 56437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // minimum separation. 56537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::map<uint64_t, uint64_t> AlreadyAllocated; 56637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 56737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Move the previously applied mappings into the already-allocated map. 56837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); 56937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines I != E;) { 57037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines WorklistT::iterator Tmp = I; 57137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++I; 57237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first); 57337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 57437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (AI != AppliedMappings.end()) { 57537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AlreadyAllocated[AI->second] = Tmp->second; 57637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Worklist.erase(Tmp); 57737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 57837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 57937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 58037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // If the -target-addr-end option wasn't explicitly passed, then set it to a 58137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // sensible default based on the target triple. 58237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (TargetAddrEnd.getNumOccurrences() == 0) { 58337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (TargetTriple.isArch16Bit()) 58437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetAddrEnd = (1ULL << 16) - 1; 58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (TargetTriple.isArch32Bit()) 58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetAddrEnd = (1ULL << 32) - 1; 58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // TargetAddrEnd already has a sensible default for 64-bit systems, so 58837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // there's nothing to do in the 64-bit case. 58937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 59137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Process any elements remaining in the worklist. 59237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines while (!Worklist.empty()) { 59337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::pair<void*, uint64_t> CurEntry = Worklist.front(); 59437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Worklist.pop_front(); 59537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 59637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t NextSectionAddr = TargetAddrStart; 59737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 59837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Alloc : AlreadyAllocated) 59937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first) 60037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 60237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; 60337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 60437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AlreadyAllocated[NextSectionAddr] = CurEntry.second; 60537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr); 60637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 60737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Add dummy symbols to the memory manager. 609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const auto &Mapping : DummySymbolMappings) { 610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar size_t EqualsIdx = Mapping.find_first_of("="); 611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (EqualsIdx == StringRef::npos) 613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Invalid dummy symbol specification '" + Mapping + 614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "'. Should be '<symbol name>=<addr>'"); 615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string Symbol = Mapping.substr(0, EqualsIdx); 617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::string AddrStr = Mapping.substr(EqualsIdx + 1); 618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar uint64_t Addr; 620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (StringRef(AddrStr).getAsInteger(0, Addr)) 621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar report_fatal_error("Invalid symbol mapping '" + Mapping + "'."); 622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemMgr.addDummySymbol(Symbol, Addr); 624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 62637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 62737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Load and link the objects specified on the command line, but do not execute 62837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// anything. Instead, attach a RuntimeDyldChecker instance and call it to 62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// verify the correctness of the linked memory. 630c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic int linkAndVerify() { 631c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 632c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Check for missing triple. 633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TripleName == "") 634de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("-triple required when running in -verify mode."); 635c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 636c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Look up the target and build the disassembler. 637c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Triple TheTriple(Triple::normalize(TripleName)); 638c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::string ErrorStr; 639c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines const Target *TheTarget = 640c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines TargetRegistry::lookupTarget("", TheTriple, ErrorStr); 641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!TheTarget) 642de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr); 643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 644c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines TripleName = TheTriple.getTriple(); 645c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 646c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MCSubtargetInfo> STI( 647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); 648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!STI) 649de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("Unable to create subtarget info!"); 650c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 651c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MRI) 653de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("Unable to create target register info!"); 654c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 655c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); 656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!MAI) 657de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("Unable to create target asm info!"); 658c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 659c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MCContext Ctx(MAI.get(), MRI.get(), nullptr); 660c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 661c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MCDisassembler> Disassembler( 662c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines TheTarget->createMCDisassembler(*STI, Ctx)); 663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!Disassembler) 664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("Unable to create disassembler!"); 665c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 666c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 667c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 668c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::unique_ptr<MCInstPrinter> InstPrinter( 6690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); 670c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 671c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Load any dylibs requested on the command line. 672c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines loadDylibs(); 673c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 674c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Instantiate a dynamic linker. 675c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines TrivialMemoryManager MemMgr; 676f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar doPreallocation(MemMgr); 6770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar RuntimeDyld Dyld(MemMgr, MemMgr); 67837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Dyld.setProcessAllSections(true); 67937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(), 68037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::dbgs()); 681c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 682c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // If we don't have any input files, read from stdin. 683c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!InputFileList.size()) 684c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines InputFileList.push_back("-"); 685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &Filename : InputFileList) { 686c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Load the input memory buffer. 687c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = 688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemoryBuffer::getFileOrSTDIN(Filename); 689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 690c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = InputBuffer.getError()) 691de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to read input: '" + EC.message() + "'"); 692c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Expected<std::unique_ptr<ObjectFile>> MaybeObj( 694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); 695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MaybeObj) { 697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::string Buf; 698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_string_ostream OS(Buf); 699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar logAllUnhandledErrors(MaybeObj.takeError(), OS, ""); 700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.flush(); 701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("unable to create object file: '" + Buf + "'"); 702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 703ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjectFile &Obj = **MaybeObj; 705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 706c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Load the object file 707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Dyld.loadObject(Obj); 708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Dyld.hasError()) { 709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit(Dyld.getErrorString()); 710c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 711c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 712c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Re-map the section addresses into the phony target address space and add 714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // dummy symbols. 715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar remapSectionsAndSymbols(TheTriple, MemMgr, Checker); 71637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 717c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Resolve all the relocations we can. 718c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Dyld.resolveRelocations(); 719c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Register EH frames. 72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Dyld.registerEHFrames(); 72237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 72337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int ErrorCode = checkAllExpressions(Checker); 724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Dyld.hasError()) 725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ErrorAndExit("RTDyld reported an error applying relocations:\n " + 726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Dyld.getErrorString()); 72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 72837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return ErrorCode; 729c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 730c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 7311cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachint main(int argc, char **argv) { 732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar sys::PrintStackTraceOnErrorSignal(argv[0]); 7334d6b695c953462c3317e3a7eb57d0534db858ac2Alp Toker PrettyStackTraceProgram X(argc, argv); 7344d6b695c953462c3317e3a7eb57d0534db858ac2Alp Toker 7351cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach ProgramName = argv[0]; 7361cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 7371cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 738c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines llvm::InitializeAllTargetInfos(); 739c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines llvm::InitializeAllTargetMCs(); 740c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines llvm::InitializeAllDisassemblers(); 741c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 7421cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); 7431cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach 7441cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach switch (Action) { 7451cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach case AC_Execute: 74682c25b4964f91760fb4731cdef114b2ba2a950ccJim Grosbach return executeInput(); 7476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case AC_PrintDebugLineInfo: 7486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */ true); 749ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor case AC_PrintLineInfo: 7506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */false); 7516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case AC_PrintObjectLineInfo: 7526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return printLineInfoForInput(/* LoadObjects */false,/* UseDebugObj */false); 753c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines case AC_Verify: 754c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return linkAndVerify(); 7551cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach } 7561cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach} 757