Skip to content

Commit

Permalink
EVM-C: Add get_code_size() callback function
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Mar 26, 2018
1 parent fdd4117 commit b6d14d8
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
9 changes: 9 additions & 0 deletions examples/capi.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ static void get_balance(struct evm_uint256be* result,
*result = balance(context, address);
}

static size_t get_code_size(struct evm_context* context, const struct evm_address* address)
{
printf("EVM-C: CODESIZE @");
print_address(address);
printf("\n");
return 0;
}

static size_t get_code(const uint8_t** code,
struct evm_context* context,
const struct evm_address* address)
Expand Down Expand Up @@ -121,6 +129,7 @@ static const struct evm_context_fn_table ctx_fn_table = {
get_storage,
set_storage,
get_balance,
get_code_size,
get_code,
selfdestruct,
call,
Expand Down
14 changes: 11 additions & 3 deletions include/evm.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,21 @@ typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
struct evm_context* context,
const struct evm_address* address);

/// Get code size callback function.
///
/// This callback function is used by an EVM to get the size of the code stored
/// in the account at the given address. For accounts not having a code, this
/// function returns 0.
typedef size_t (*evm_get_code_size_fn)(struct evm_context* context,
const struct evm_address* address);

/// Get code callback function.
///
/// This callback function is used by an EVM to get the code of a contract of
/// given address.
///
/// @param[out] result_code The pointer to the contract code. This argument is
/// optional. If NULL is provided, the host MUST only
/// return the code size. It will be freed by the Client.
/// @param[out] result_code The pointer to the contract code.
/// It will be freed by the Client.
/// @param context The pointer to the Host execution context.
/// @see ::evm_context.
/// @param address The address of the contract.
Expand Down Expand Up @@ -408,6 +415,7 @@ struct evm_context_fn_table {
evm_get_storage_fn get_storage;
evm_set_storage_fn set_storage;
evm_get_balance_fn get_balance;
evm_get_code_size_fn get_code_size;
evm_get_code_fn get_code;
evm_selfdestruct_fn selfdestruct;
evm_call_fn call;
Expand Down
22 changes: 19 additions & 3 deletions libevmjit/Ext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,23 @@ llvm::Function* getGetBalanceFunc(llvm::Module* _module)
return func;
}

llvm::Function* getGetCodeSizeFunc(llvm::Module* _module)
{
static const auto funcName = "evm.codesize";
auto func = _module->getFunction(funcName);
if (!func)
{
auto addrTy = llvm::IntegerType::get(_module->getContext(), 160);
auto fty = llvm::FunctionType::get(
Type::Size, {Type::EnvPtr, addrTy->getPointerTo()}, false);
func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, funcName, _module);
func->addAttribute(2, llvm::Attribute::ReadOnly);
func->addAttribute(2, llvm::Attribute::NoAlias);
func->addAttribute(2, llvm::Attribute::NoCapture);
}
return func;
}

llvm::Function* getGetCodeFunc(llvm::Module* _module)
{
static const auto funcName = "evm.code";
Expand Down Expand Up @@ -482,13 +499,12 @@ MemoryRef Ext::extcode(llvm::Value* _address)

llvm::Value* Ext::extcodesize(llvm::Value* _address)
{
auto func = getGetCodeFunc(getModule());
auto func = getGetCodeSizeFunc(getModule());
auto addrTy = m_builder.getIntNTy(160);
auto address = Endianness::toBE(m_builder, m_builder.CreateTrunc(_address, addrTy));
auto pAddr = m_builder.CreateBitCast(getArgAlloca(), addrTy->getPointerTo());
m_builder.CreateStore(address, pAddr);
auto ignoreCode = llvm::ConstantPointerNull::get(Type::BytePtr->getPointerTo());
auto size = createCABICall(func, {ignoreCode, getRuntimeManager().getEnvPtr(), pAddr});
auto size = createCABICall(func, {getRuntimeManager().getEnvPtr(), pAddr});
return m_builder.CreateZExt(size, Type::Word);
}

Expand Down
1 change: 1 addition & 0 deletions libevmjit/JIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class SymbolResolver : public llvm::SectionMemoryManager
.Case("evm.sload", reinterpret_cast<uint64_t>(jit.host->get_storage))
.Case("evm.sstore", reinterpret_cast<uint64_t>(jit.host->set_storage))
.Case("evm.balance", reinterpret_cast<uint64_t>(jit.host->get_balance))
.Case("evm.codesize", reinterpret_cast<uint64_t>(jit.host->get_code_size))
.Case("evm.code", reinterpret_cast<uint64_t>(jit.host->get_code))
.Case("evm.selfdestruct", reinterpret_cast<uint64_t>(jit.host->selfdestruct))
.Case("evm.call", reinterpret_cast<uint64_t>(call_v2))
Expand Down

0 comments on commit b6d14d8

Please sign in to comment.