#include "ExecutionEngine.h" #include #include #include #include #include #include #include #include #include #include #include #include "Ext.h" #include "Memory.h" namespace evmcc { ExecutionEngine::ExecutionEngine() { } int ExecutionEngine::run(std::unique_ptr _module) { auto module = _module.get(); // Keep ownership of the module in _module llvm::sys::PrintStackTraceOnErrorSignal(); static const auto program = "evmcc"; llvm::PrettyStackTraceProgram X(1, &program); auto&& context = llvm::getGlobalContext(); llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetAsmParser(); std::string errorMsg; llvm::EngineBuilder builder(module); //builder.setMArch(MArch); //builder.setMCPU(MCPU); //builder.setMAttrs(MAttrs); //builder.setRelocationModel(RelocModel); //builder.setCodeModel(CMModel); builder.setErrorStr(&errorMsg); builder.setEngineKind(llvm::EngineKind::JIT); builder.setUseMCJIT(true); builder.setMCJITMemoryManager(new llvm::SectionMemoryManager()); builder.setOptLevel(llvm::CodeGenOpt::None); auto triple = llvm::Triple(llvm::sys::getProcessTriple()); if (triple.getOS() == llvm::Triple::OSType::Win32) triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format module->setTargetTriple(triple.str()); auto exec = std::unique_ptr(builder.create()); if (!exec) { if (!errorMsg.empty()) std::cerr << "error creating EE: " << errorMsg << std::endl; else std::cerr << "unknown error creating llvm::ExecutionEngine" << std::endl; exit(1); } _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module exec->finalizeObject(); auto&& memory = Memory::init(); auto ext = std::make_unique(); ext->myAddress = dev::Address(1122334455667788); ext->caller = dev::Address(0xfacefacefaceface); ext->origin = dev::Address(101010101010101010); ext->value = 0xabcd; ext->gasPrice = 1002; ext->previousBlock.hash = dev::u256(1003); ext->currentBlock.coinbaseAddress = dev::Address(1004); ext->currentBlock.timestamp = 1005; ext->currentBlock.number = 1006; ext->currentBlock.difficulty = 1007; ext->currentBlock.gasLimit = 1008; std::string calldata = "Hello the Beautiful World of Ethereum!"; ext->data = calldata; Ext::init(std::move(ext)); auto entryFunc = module->getFunction("main"); if (!entryFunc) { std::cerr << "main function not found\n"; exit(1); } auto result = exec->runFunction(entryFunc, {}); if (auto intResult = result.IntVal.getZExtValue()) { auto index = intResult >> 32; auto size = 0xFFFFFFFF & intResult; std::cout << "RETURN [ "; for (dev::bytes::const_iterator it = memory.cbegin() + index, end = it + size; it != end; ++it) std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " "; std::cout << "]"; return 10; } return 0; } }