llvm-rtdyld.cpp revision 234353
175295Sdes//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===// 2230132Suqs// 375295Sdes// The LLVM Compiler Infrastructure 475295Sdes// 575295Sdes// This file is distributed under the University of Illinois Open Source 675295Sdes// License. See LICENSE.TXT for details. 775295Sdes// 875295Sdes//===----------------------------------------------------------------------===// 975295Sdes// 1075295Sdes// This is a testing tool for use with the MC-JIT LLVM components. 1175295Sdes// 1275295Sdes//===----------------------------------------------------------------------===// 1375295Sdes 1475295Sdes#include "llvm/ADT/StringMap.h" 1575295Sdes#include "llvm/ADT/OwningPtr.h" 1675295Sdes#include "llvm/ExecutionEngine/RuntimeDyld.h" 1775295Sdes#include "llvm/Object/MachOObject.h" 1875295Sdes#include "llvm/Support/CommandLine.h" 1975295Sdes#include "llvm/Support/ManagedStatic.h" 2075295Sdes#include "llvm/Support/Memory.h" 2175295Sdes#include "llvm/Support/MemoryBuffer.h" 2275295Sdes#include "llvm/Support/raw_ostream.h" 2375295Sdes#include "llvm/Support/system_error.h" 2475295Sdesusing namespace llvm; 2575295Sdesusing namespace llvm::object; 2675295Sdes 2775295Sdesstatic cl::list<std::string> 2875295SdesInputFileList(cl::Positional, cl::ZeroOrMore, 2975295Sdes cl::desc("<input file>")); 3075295Sdes 3175295Sdesenum ActionType { 3275295Sdes AC_Execute 3375295Sdes}; 34232278Smm 35232278Smmstatic cl::opt<ActionType> 3675295SdesAction(cl::desc("Action to perform:"), 3785940Sdes cl::init(AC_Execute), 3885940Sdes cl::values(clEnumValN(AC_Execute, "execute", 39158611Skbyanc "Load, link, and execute the inputs."), 4085940Sdes clEnumValEnd)); 4185940Sdes 4285940Sdesstatic cl::opt<std::string> 4385940SdesEntryPoint("entry", 4485940Sdes cl::desc("Function to call as entry point."), 4585940Sdes cl::init("_main")); 4685940Sdes 4785940Sdes/* *** */ 4885940Sdes 4985940Sdes// A trivial memory manager that doesn't do anything fancy, just uses the 5085940Sdes// support library allocation routines directly. 5175295Sdesclass TrivialMemoryManager : public RTDyldMemoryManager { 5275295Sdespublic: 5375295Sdes SmallVector<sys::MemoryBlock, 16> FunctionMemory; 5485940Sdes SmallVector<sys::MemoryBlock, 16> DataMemory; 5575295Sdes 5675295Sdes uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 5775295Sdes unsigned SectionID); 5875295Sdes uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 5975295Sdes unsigned SectionID); 6075295Sdes 6175295Sdes virtual void *getPointerToNamedFunction(const std::string &Name, 6275295Sdes bool AbortOnFailure = true) { 6375295Sdes return 0; 6475295Sdes } 6577998Sdes 6675295Sdes}; 6775295Sdes 6875295Sdesuint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, 6983927Sdes unsigned Alignment, 7083927Sdes unsigned SectionID) { 7184187Sdes return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); 7284187Sdes} 7384187Sdes 7483927Sdesuint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, 7583927Sdes unsigned Alignment, 7684187Sdes unsigned SectionID) { 7785128Sdes return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base(); 7883927Sdes} 7983927Sdes 8075295Sdesstatic const char *ProgramName; 8175295Sdes 8275295Sdesstatic void Message(const char *Type, const Twine &Msg) { 8375295Sdes errs() << ProgramName << ": " << Type << ": " << Msg << "\n"; 8475295Sdes} 8575295Sdes 8684098Sdesstatic int Error(const Twine &Msg) { 8785128Sdes Message("error", Msg); 8885128Sdes return 1; 8985128Sdes} 9085128Sdes 91168764Sdes/* *** */ 92168764Sdes 9385128Sdesstatic int executeInput() { 9485128Sdes // Instantiate a dynamic linker. 9585128Sdes TrivialMemoryManager *MemMgr = new TrivialMemoryManager; 9685128Sdes RuntimeDyld Dyld(MemMgr); 9785128Sdes 9884098Sdes // If we don't have any input files, read from stdin. 99168764Sdes if (!InputFileList.size()) 10084098Sdes InputFileList.push_back("-"); 10177998Sdes for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { 10283927Sdes // Load the input memory buffer. 10383927Sdes OwningPtr<MemoryBuffer> InputBuffer; 104168764Sdes if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i], 105168764Sdes InputBuffer)) 10677998Sdes return Error("unable to read input: '" + ec.message() + "'"); 10777998Sdes 10877998Sdes // Load the object file into it. 10975295Sdes if (Dyld.loadObject(InputBuffer.take())) { 11084098Sdes return Error(Dyld.getErrorString()); 11184098Sdes } 112168764Sdes } 11384098Sdes 11484098Sdes // Resolve all the relocations we can. 11584098Sdes Dyld.resolveRelocations(); 11684098Sdes 11784098Sdes // FIXME: Error out if there are unresolved relocations. 118168764Sdes 119168764Sdes // Get the address of the entry point (_main by default). 12084098Sdes void *MainAddress = Dyld.getSymbolAddress(EntryPoint); 12184098Sdes if (MainAddress == 0) 12284098Sdes return Error("no definition for '" + EntryPoint + "'"); 12384098Sdes 12475295Sdes // Invalidate the instruction cache for each loaded function. 12575295Sdes for (unsigned i = 0, e = MemMgr->FunctionMemory.size(); i != e; ++i) { 12675295Sdes sys::MemoryBlock &Data = MemMgr->FunctionMemory[i]; 12784246Sdes // Make sure the memory is executable. 128168764Sdes std::string ErrorStr; 12984246Sdes sys::Memory::InvalidateInstructionCache(Data.base(), Data.size()); 13084246Sdes if (!sys::Memory::setExecutable(Data, &ErrorStr)) 13184246Sdes return Error("unable to mark function executable: '" + ErrorStr + "'"); 132168764Sdes } 133168764Sdes 13484246Sdes // Dispatch to _main(). 13584246Sdes errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; 13684246Sdes 13784246Sdes int (*Main)(int, const char**) = 13884246Sdes (int(*)(int,const char**)) uintptr_t(MainAddress); 13985561Sdes const char **Argv = new const char*[2]; 140168764Sdes // Use the name of the first input object module as argv[0] for the target. 14185561Sdes Argv[0] = InputFileList[0].c_str(); 14285561Sdes Argv[1] = 0; 14385561Sdes return Main(1, Argv); 144111769Sdes} 145168764Sdes 146168764Sdesint main(int argc, char **argv) { 14785561Sdes ProgramName = argv[0]; 14885561Sdes llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 14985561Sdes 15085561Sdes cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n"); 15185561Sdes 15287670Sgreen switch (Action) { 153168764Sdes case AC_Execute: 15487670Sgreen return executeInput(); 15587670Sgreen } 15687670Sgreen} 15787670Sgreen