Paweł Bylica
10 years ago
commit
f5eda1f1b3
6 changed files with 267 additions and 0 deletions
@ -0,0 +1,49 @@ |
|||||
|
cmake_policy(SET CMP0015 NEW) |
||||
|
|
||||
|
aux_source_directory(. SRC_LIST) |
||||
|
|
||||
|
include_directories(..) |
||||
|
|
||||
|
set(EXECUTABLE evmcc) |
||||
|
|
||||
|
add_executable(${EXECUTABLE} ${SRC_LIST}) |
||||
|
|
||||
|
target_link_libraries(${EXECUTABLE} evmface) |
||||
|
target_link_libraries(${EXECUTABLE} devcore) |
||||
|
|
||||
|
if ("${TARGET_PLATFORM}" STREQUAL "w64") |
||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") |
||||
|
target_link_libraries(${EXECUTABLE} gcc) |
||||
|
target_link_libraries(${EXECUTABLE} gdi32) |
||||
|
target_link_libraries(${EXECUTABLE} ws2_32) |
||||
|
target_link_libraries(${EXECUTABLE} mswsock) |
||||
|
target_link_libraries(${EXECUTABLE} shlwapi) |
||||
|
target_link_libraries(${EXECUTABLE} iphlpapi) |
||||
|
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) |
||||
|
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) |
||||
|
elseif (UNIX) |
||||
|
else () |
||||
|
find_package(Threads REQUIRED) |
||||
|
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
||||
|
endif () |
||||
|
|
||||
|
# LLVM specific commands |
||||
|
|
||||
|
find_package(LLVM REQUIRED CONFIG) |
||||
|
|
||||
|
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") |
||||
|
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") |
||||
|
|
||||
|
include_directories(${LLVM_INCLUDE_DIRS}) |
||||
|
add_definitions(${LLVM_DEFINITIONS}) |
||||
|
|
||||
|
llvm_map_components_to_libnames(llvm_libs support core irreader) |
||||
|
target_link_libraries(evmcc ${llvm_libs}) |
||||
|
|
||||
|
# end of LLVM specific commands |
||||
|
|
||||
|
|
||||
|
|
||||
|
install( TARGETS ${EXECUTABLE} DESTINATION bin ) |
||||
|
|
||||
|
cmake_policy(SET CMP0015 NEW) |
@ -0,0 +1,75 @@ |
|||||
|
|
||||
|
#include "Compiler.h" |
||||
|
|
||||
|
#include <llvm/IR/IRBuilder.h> |
||||
|
#include <llvm/IR/Module.h> |
||||
|
|
||||
|
namespace evmcc |
||||
|
{ |
||||
|
|
||||
|
Compiler::Compiler() |
||||
|
{ |
||||
|
auto& context = llvm::getGlobalContext(); |
||||
|
Types.word8 = llvm::Type::getInt8Ty(context); |
||||
|
Types.word8ptr = llvm::Type::getInt8PtrTy(context); |
||||
|
Types.word256 = llvm::Type::getIntNTy(context, 256); |
||||
|
Types.word256ptr = Types.word256->getPointerTo(); |
||||
|
Types.word256arr = llvm::ArrayType::get(Types.word256, 100); |
||||
|
Types.size = llvm::Type::getInt64Ty(context); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void Compiler::compile(const dev::bytes& bytecode) |
||||
|
{ |
||||
|
using namespace llvm; |
||||
|
|
||||
|
auto& context = getGlobalContext(); |
||||
|
|
||||
|
Module* module = new Module("main", context); |
||||
|
IRBuilder<> builder(context); |
||||
|
|
||||
|
// Create globals for memory, memory size, stack and stack top
|
||||
|
auto memory = new GlobalVariable(*module, Types.word8ptr, false, |
||||
|
GlobalValue::LinkageTypes::PrivateLinkage, |
||||
|
Constant::getNullValue(Types.word8ptr), "memory"); |
||||
|
auto memSize = new GlobalVariable(*module, Types.size, false, |
||||
|
GlobalValue::LinkageTypes::PrivateLinkage, |
||||
|
ConstantInt::get(Types.size, 0), "memsize"); |
||||
|
auto stack = new GlobalVariable(*module, Types.word256arr, false, |
||||
|
GlobalValue::LinkageTypes::PrivateLinkage, |
||||
|
ConstantAggregateZero::get(Types.word256arr), "stack"); |
||||
|
auto stackTop = new GlobalVariable(*module, Types.size, false, |
||||
|
GlobalValue::LinkageTypes::PrivateLinkage, |
||||
|
ConstantInt::get(Types.size, 0), "stackTop"); |
||||
|
|
||||
|
// Create value for void* malloc(size_t)
|
||||
|
std::vector<Type*> mallocArgTypes = { Types.size }; |
||||
|
Value* mallocVal = Function::Create(FunctionType::get(Types.word8ptr, mallocArgTypes, false), |
||||
|
GlobalValue::LinkageTypes::ExternalLinkage, "malloc", module); |
||||
|
|
||||
|
// Create main function
|
||||
|
FunctionType* funcType = FunctionType::get(llvm::Type::getInt32Ty(context), false); |
||||
|
Function* mainFunc = Function::Create(funcType, Function::ExternalLinkage, "main", module); |
||||
|
|
||||
|
BasicBlock* entryBlock = BasicBlock::Create(context, "entry", mainFunc); |
||||
|
builder.SetInsertPoint(entryBlock); |
||||
|
|
||||
|
// Initialize memory with call to malloc, update memsize
|
||||
|
std::vector<Value*> mallocMemArgs = { ConstantInt::get(Types.size, 100) }; |
||||
|
auto mallocMemCall = builder.CreateCall(mallocVal, mallocMemArgs, "malloc_mem"); |
||||
|
builder.CreateStore(mallocMemCall, memory); |
||||
|
builder.CreateStore(ConstantInt::get(Types.size, 100), memSize); |
||||
|
|
||||
|
/*
|
||||
|
std::vector<Value*> mallocStackArgs = { ConstantInt::get(sizeTy, 200) }; |
||||
|
auto mallocStackCall = builder.CreateCall(mallocVal, mallocStackArgs, "malloc_stack"); |
||||
|
auto mallocCast = builder.CreatePointerBitCastOrAddrSpaceCast(mallocStackCall, int256ptr); |
||||
|
builder.CreateStore(mallocCast, stackVal); |
||||
|
*/ |
||||
|
|
||||
|
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0)); |
||||
|
|
||||
|
module->dump(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <llvm/IR/Type.h> |
||||
|
|
||||
|
#include <libdevcore/Common.h> |
||||
|
|
||||
|
namespace evmcc |
||||
|
{ |
||||
|
|
||||
|
class Compiler |
||||
|
{ |
||||
|
|
||||
|
private: |
||||
|
|
||||
|
struct |
||||
|
{ |
||||
|
llvm::Type* word8; |
||||
|
llvm::Type* word8ptr; |
||||
|
llvm::Type* word256; |
||||
|
llvm::Type* word256ptr; |
||||
|
llvm::Type* word256arr; |
||||
|
llvm::Type* size; |
||||
|
} Types; |
||||
|
|
||||
|
public: |
||||
|
|
||||
|
Compiler(); |
||||
|
|
||||
|
void compile(const dev::bytes& bytecode); |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
33604557602a8060106000396000f200604556330e0f602a59366080530a0f602a59602060805301356080533557604060805301608054600958 |
@ -0,0 +1,98 @@ |
|||||
|
|
||||
|
#include <iostream> |
||||
|
#include <fstream> |
||||
|
#include <string> |
||||
|
#include <vector> |
||||
|
|
||||
|
#include <boost/algorithm/string.hpp> |
||||
|
|
||||
|
#include <libdevcore/Common.h> |
||||
|
#include <libdevcore/CommonIO.h> |
||||
|
#include <libevmface/Instruction.h> |
||||
|
|
||||
|
#include "Compiler.h" |
||||
|
|
||||
|
using namespace dev; |
||||
|
|
||||
|
|
||||
|
void show_usage() |
||||
|
{ |
||||
|
// FIXME: Use arg[0] as program name?
|
||||
|
std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n"; |
||||
|
} |
||||
|
|
||||
|
int main(int argc, char** argv) |
||||
|
{ |
||||
|
|
||||
|
std::string input_file; |
||||
|
bool opt_dissassemble = false; |
||||
|
bool opt_show_bytes = false; |
||||
|
bool opt_compile = false; |
||||
|
bool opt_unknown = false; |
||||
|
|
||||
|
for (int i = 1; i < argc; i++) |
||||
|
{ |
||||
|
std::string option = argv[i]; |
||||
|
if (option == "-b") |
||||
|
{ |
||||
|
opt_show_bytes = true; |
||||
|
} |
||||
|
else if (option == "-c") |
||||
|
{ |
||||
|
opt_compile = true; |
||||
|
} |
||||
|
else if (option == "-d") |
||||
|
{ |
||||
|
opt_dissassemble = true; |
||||
|
} |
||||
|
else if (option[0] != '-' && input_file.empty()) |
||||
|
{ |
||||
|
input_file = option; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
opt_unknown = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (opt_unknown || |
||||
|
input_file.empty() || |
||||
|
(!opt_show_bytes && !opt_compile && !opt_dissassemble)) |
||||
|
{ |
||||
|
show_usage(); |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
std::ifstream ifs(input_file); |
||||
|
if (!ifs.is_open()) |
||||
|
{ |
||||
|
std::cerr << "cannot open file " << input_file << std::endl; |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
std::string src((std::istreambuf_iterator<char>(ifs)), |
||||
|
(std::istreambuf_iterator<char>())); |
||||
|
|
||||
|
boost::algorithm::trim(src); |
||||
|
|
||||
|
bytes bytecode = fromHex(src); |
||||
|
|
||||
|
if (opt_show_bytes) |
||||
|
{ |
||||
|
std::cout << dev::memDump(bytecode) << std::endl; |
||||
|
} |
||||
|
|
||||
|
if (opt_dissassemble) |
||||
|
{ |
||||
|
std::string assembly = eth::disassemble(bytecode); |
||||
|
std::cout << assembly << std::endl; |
||||
|
} |
||||
|
|
||||
|
if (opt_compile) |
||||
|
{ |
||||
|
evmcc::Compiler().compile(bytecode); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
{ |
||||
|
[[69]] (caller) |
||||
|
(return 0 (lll |
||||
|
(when (= (caller) @@69) |
||||
|
(for {} (< @i (calldatasize)) [i](+ @i 64) |
||||
|
[[ (calldataload @i) ]] (calldataload (+ @i 32)) |
||||
|
) |
||||
|
) |
||||
|
0)) |
||||
|
} |
Loading…
Reference in new issue