From 05741c2d4e652cb68bb546f0a7c5a4f10f5986b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 21 Oct 2014 17:35:18 +0200 Subject: [PATCH 1/5] Handle endianness for CALLDATALOAD correctly [#79877740] --- libevmjit/Ext.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index 26ed962b21..ca0a83307c 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -8,6 +8,7 @@ #include #include "Runtime.h" +#include "Endianness.h" using namespace llvm; @@ -145,7 +146,8 @@ Value* Ext::calldataload(Value* _index) { m_builder.CreateStore(_index, m_args[0]); m_builder.CreateCall(m_calldataload, m_args); - return m_builder.CreateLoad(m_args[1]); + auto ret = m_builder.CreateLoad(m_args[1]); + return Endianness::toNative(m_builder, ret); } Value* Ext::bswap(Value* _value) @@ -282,8 +284,8 @@ EXPORT void ext_calldataload(i256* _index, i256* _value) auto index = static_cast(llvm2eth(*_index)); assert(index + 31 > index); // TODO: Handle large index auto b = reinterpret_cast(_value); - for (size_t i = index, j = 31; i <= index + 31; ++i, --j) - b[j] = i < Runtime::getExt().data.size() ? Runtime::getExt().data[i] : 0; + for (size_t i = index, j = 0; i <= index + 31; ++i, ++j) + b[j] = i < Runtime::getExt().data.size() ? Runtime::getExt().data[i] : 0; // Keep Big Endian // TODO: It all can be done by adding padding to data or by using min() algorithm without branch } From 920ea2ec7e60701bb259bcbe3e4cb93877c729a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 21 Oct 2014 17:44:48 +0200 Subject: [PATCH 2/5] Comment: storage uses native endianness [#79877740] --- libevmjit/Ext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index ca0a83307c..98cb791e01 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -109,7 +109,7 @@ Ext::Ext(llvm::IRBuilder<>& _builder): llvm::Value* Ext::store(llvm::Value* _index) { m_builder.CreateStore(_index, m_args[0]); - m_builder.CreateCall(m_store, m_args); + m_builder.CreateCall(m_store, m_args); // Uses native endianness return m_builder.CreateLoad(m_args[1]); } @@ -117,7 +117,7 @@ void Ext::setStore(llvm::Value* _index, llvm::Value* _value) { m_builder.CreateStore(_index, m_args[0]); m_builder.CreateStore(_value, m_args[1]); - m_builder.CreateCall(m_setStore, m_args); + m_builder.CreateCall(m_setStore, m_args); // Uses native endianness } Value* Ext::getDataElem(unsigned _index, const Twine& _name) @@ -268,7 +268,7 @@ EXPORT void ext_init(ExtData* _extData) EXPORT void ext_store(i256* _index, i256* _value) { auto index = llvm2eth(*_index); - auto value = Runtime::getExt().store(index); + auto value = Runtime::getExt().store(index); // Interface uses native endianness *_value = eth2llvm(value); } @@ -276,7 +276,7 @@ EXPORT void ext_setStore(i256* _index, i256* _value) { auto index = llvm2eth(*_index); auto value = llvm2eth(*_value); - Runtime::getExt().setStore(index, value); + Runtime::getExt().setStore(index, value); // Interface uses native endianness } EXPORT void ext_calldataload(i256* _index, i256* _value) From 075752340a9f8ca0a4435f61f754dc3c4a702e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 21 Oct 2014 17:50:34 +0200 Subject: [PATCH 3/5] Use Endianness in Ext [#79877740] --- libevmjit/Ext.cpp | 21 ++++++++------------- libevmjit/Ext.h | 2 -- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index 98cb791e01..045d25b627 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -150,14 +150,9 @@ Value* Ext::calldataload(Value* _index) return Endianness::toNative(m_builder, ret); } -Value* Ext::bswap(Value* _value) -{ - return m_builder.CreateCall(m_bswap, _value); -} - Value* Ext::balance(Value* _address) { - auto address = bswap(_address); // to BE + auto address = Endianness::toBE(m_builder, _address); m_builder.CreateStore(address, m_args[0]); m_builder.CreateCall(m_balance, m_args); return m_builder.CreateLoad(m_args[1]); @@ -165,7 +160,7 @@ Value* Ext::balance(Value* _address) void Ext::suicide(Value* _address) { - auto address = bswap(_address); // to BE + auto address = Endianness::toBE(m_builder, _address); m_builder.CreateStore(address, m_args[0]); m_builder.CreateCall(m_suicide, m_args[0]); } @@ -178,21 +173,21 @@ Value* Ext::create(llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* Value* args[] = {m_args[0], m_arg2, m_arg3, m_args[1]}; m_builder.CreateCall(m_create, args); Value* address = m_builder.CreateLoad(m_args[1]); - address = bswap(address); // to LE + address = Endianness::toNative(m_builder, address); return address; } llvm::Value* Ext::call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::Value* _value, llvm::Value* _inOff, llvm::Value* _inSize, llvm::Value* _outOff, llvm::Value* _outSize, llvm::Value* _codeAddress) { m_builder.CreateStore(_gas, m_args[0]); - auto receiveAddress = bswap(_receiveAddress); // to BE + auto receiveAddress = Endianness::toBE(m_builder, _receiveAddress); m_builder.CreateStore(receiveAddress, m_arg2); m_builder.CreateStore(_value, m_arg3); m_builder.CreateStore(_inOff, m_arg4); m_builder.CreateStore(_inSize, m_arg5); m_builder.CreateStore(_outOff, m_arg6); m_builder.CreateStore(_outSize, m_arg7); - auto codeAddress = bswap(_codeAddress); // toBE + auto codeAddress = Endianness::toBE(m_builder, _codeAddress); m_builder.CreateStore(codeAddress, m_arg8); llvm::Value* args[] = {m_args[0], m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_args[1]}; @@ -208,7 +203,7 @@ llvm::Value* Ext::sha3(llvm::Value* _inOff, llvm::Value* _inSize) llvm::Value* args[] = {m_args[0], m_arg2, m_args[1]}; m_builder.CreateCall(m_sha3, args); Value* hash = m_builder.CreateLoad(m_args[1]); - hash = bswap(hash); // to LE + hash = Endianness::toNative(m_builder, hash); return hash; } @@ -223,14 +218,14 @@ llvm::Value* Ext::exp(llvm::Value* _left, llvm::Value* _right) llvm::Value* Ext::codeAt(llvm::Value* _addr) { - auto addr = bswap(_addr); + auto addr = Endianness::toBE(m_builder, _addr); m_builder.CreateStore(addr, m_args[0]); return m_builder.CreateCall(m_codeAt, m_args[0]); } llvm::Value* Ext::codesizeAt(llvm::Value* _addr) { - auto addr = bswap(_addr); + auto addr = Endianness::toBE(m_builder, _addr); m_builder.CreateStore(addr, m_args[0]); llvm::Value* args[] = {m_args[0], m_args[1]}; m_builder.CreateCall(m_codesizeAt, args); diff --git a/libevmjit/Ext.h b/libevmjit/Ext.h index 04c17fdac4..361b6e47e5 100644 --- a/libevmjit/Ext.h +++ b/libevmjit/Ext.h @@ -50,8 +50,6 @@ public: private: llvm::Value* getDataElem(unsigned _index, const llvm::Twine& _name = ""); - llvm::Value* bswap(llvm::Value*); - private: llvm::Value* m_args[2]; llvm::Value* m_arg2; From f28f8cc0a59f7110a9669967c6fe80220d27120e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 21 Oct 2014 18:16:57 +0200 Subject: [PATCH 4/5] Add support for Big Endian architectures [Delivers #79877740] --- libevmjit/Endianness.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libevmjit/Endianness.h b/libevmjit/Endianness.h index 9234961c14..951904358c 100644 --- a/libevmjit/Endianness.h +++ b/libevmjit/Endianness.h @@ -1,6 +1,8 @@ #pragma once +#include + #include namespace dev @@ -10,14 +12,19 @@ namespace eth namespace jit { -class Endianness +struct Endianness { -public: +#if defined(BOOST_LITTLE_ENDIAN) static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswap(_builder, _word); } - static llvm::Value* toNative(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswap(_builder, _word); } +#elif defined(BOOST_BIG_ENDIAN) + static llvm::Value* toBE(llvm::IRBuilder<>&, llvm::Value* _word) { return _word; } + static llvm::Value* toNative(llvm::IRBuilder<>&, llvm::Value* _word) { return _word; } + +#endif // Add support for PDP endianness if needed + private: static llvm::Value* bswap(llvm::IRBuilder<>& _builder, llvm::Value* _word); }; From 170ca152a42be81e9474cef8bcc7b54d7d398766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 21 Oct 2014 19:52:08 +0200 Subject: [PATCH 5/5] Null gas in case of out-of-gas exception [Delivers #81118624] --- libevmjit/ExecutionEngine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 9ff4bed99d..4bcaf2c508 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -114,7 +114,8 @@ int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, ExtV else returnCode = static_cast(r); - _gas = Runtime::getGas(); + // Return remaining gas + _gas = returnCode == ReturnCode::OutOfGas ? 0 : Runtime::getGas(); if (returnCode == ReturnCode::Return) {