Updated evmc to version tracked by evmone v0.1.0

This commit is contained in:
Bhargava Shastry 2019-07-16 11:11:20 +02:00
parent 810a0de1aa
commit 00bca77cca
11 changed files with 46 additions and 101 deletions

View File

@ -29,7 +29,6 @@
#include <libdevcore/FixedHash.h> #include <libdevcore/FixedHash.h>
namespace dev namespace dev
{ {
namespace test namespace test

View File

@ -27,10 +27,6 @@
#include <boost/test/framework.hpp> #include <boost/test/framework.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <test/evmc/evmc.hpp>
#include <test/evmc/loader.h>
#include <test/evmc/helpers.hpp>
#include <cstdlib> #include <cstdlib>
#include <chrono> #include <chrono>

View File

@ -974,12 +974,12 @@ struct evmc_instance
evmc_execute_fn execute; evmc_execute_fn execute;
/** /**
* A method returning capabilities supported by the VM instance. * Pointer to function returning capabilities supported by the VM instance.
* *
* The value returned MAY change when different options are set via the set_option() method. * The value returned might change when different options are requested via set_option.
* *
* A Client SHOULD only rely on the value returned if it has queried it after * A Client SHOULD only rely on the value returned here if it has queried it after
* it has called the set_option(). * it has called set_option.
* *
* This is a mandatory method and MUST NOT be set to NULL. * This is a mandatory method and MUST NOT be set to NULL.
*/ */

View File

@ -2,7 +2,6 @@
* Copyright 2018-2019 The EVMC Authors. * Copyright 2018-2019 The EVMC Authors.
* Licensed under the Apache License, Version 2.0. * Licensed under the Apache License, Version 2.0.
*/ */
#pragma once
#include <evmc/evmc.h> #include <evmc/evmc.h>
#include <evmc/helpers.h> #include <evmc/helpers.h>
@ -105,12 +104,6 @@ public:
/// @copydoc evmc_instance::version /// @copydoc evmc_instance::version
char const* version() const noexcept { return m_instance->version; } char const* version() const noexcept { return m_instance->version; }
/// @copydoc evmc::instance::get_capabilities
evmc_capabilities_flagset get_capabilities() const noexcept
{
return m_instance->get_capabilities(m_instance);
}
/// @copydoc evmc_set_option() /// @copydoc evmc_set_option()
evmc_set_option_result set_option(const char name[], const char value[]) noexcept evmc_set_option_result set_option(const char name[], const char value[]) noexcept
{ {

View File

@ -42,33 +42,18 @@
#define ATTR_FORMAT(...) #define ATTR_FORMAT(...)
#endif #endif
#if _WIN32 #if !_WIN32
#define strcpy_sx strcpy_s
#else
/* /*
* Limited variant of strcpy_s(). * Provide strcpy_s() for GNU libc.
*
* Provided for C standard libraries where strcpy_s() is not available.
* The availability check might need to adjusted for other C standard library implementations. * The availability check might need to adjusted for other C standard library implementations.
*/ */
#if !defined(EVMC_LOADER_MOCK) static void strcpy_s(char* dest, size_t destsz, const char* src)
static
#endif
int
strcpy_sx(char* restrict dest, size_t destsz, const char* restrict src)
{ {
size_t len = strlen(src); size_t len = strlen(src);
if (len >= destsz) if (len > destsz - 1)
{ len = destsz - 1;
// The input src will not fit into the dest buffer.
// Set the first byte of the dest to null to make it effectively empty string
// and return error.
dest[0] = 0;
return 1;
}
memcpy(dest, src, len); memcpy(dest, src, len);
dest[len] = 0; dest[len] = 0;
return 0;
} }
#endif #endif
@ -139,7 +124,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
const char prefix[] = "evmc_create_"; const char prefix[] = "evmc_create_";
const size_t prefix_length = strlen(prefix); const size_t prefix_length = strlen(prefix);
char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH]; char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH];
strcpy_sx(prefixed_name, sizeof(prefixed_name), prefix); strcpy_s(prefixed_name, sizeof(prefixed_name), prefix);
// Find filename in the path. // Find filename in the path.
const char* sep_pos = strrchr(filename, '/'); const char* sep_pos = strrchr(filename, '/');
@ -157,7 +142,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
name_pos += lib_prefix_length; name_pos += lib_prefix_length;
char* base_name = prefixed_name + prefix_length; char* base_name = prefixed_name + prefix_length;
strcpy_sx(base_name, PATH_MAX_LENGTH, name_pos); strcpy_s(base_name, PATH_MAX_LENGTH, name_pos);
// Trim the file extension. // Trim the file extension.
char* ext_pos = strrchr(prefixed_name, '.'); char* ext_pos = strrchr(prefixed_name, '.');
@ -212,29 +197,21 @@ struct evmc_instance* evmc_load_and_create(const char* filename,
if (!create_fn) if (!create_fn)
return NULL; return NULL;
enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;
struct evmc_instance* instance = create_fn(); struct evmc_instance* instance = create_fn();
if (!instance) if (!instance)
{ {
ec = set_error(EVMC_LOADER_INSTANCE_CREATION_FAILURE, *error_code = set_error(EVMC_LOADER_INSTANCE_CREATION_FAILURE,
"creating EVMC instance of %s has failed", filename); "creating EVMC instance of %s has failed", filename);
goto exit; return NULL;
} }
if (!evmc_is_abi_compatible(instance)) if (!evmc_is_abi_compatible(instance))
{ {
ec = set_error(EVMC_LOADER_ABI_VERSION_MISMATCH, *error_code = set_error(EVMC_LOADER_ABI_VERSION_MISMATCH,
"EVMC ABI version %d of %s mismatches the expected version %d", "EVMC ABI version %d of %s mismatches the expected version %d",
instance->abi_version, filename, EVMC_ABI_VERSION); instance->abi_version, filename, EVMC_ABI_VERSION);
evmc_destroy(instance); return NULL;
instance = NULL;
goto exit;
} }
exit:
if (error_code)
*error_code = ec;
return instance; return instance;
} }

View File

@ -44,10 +44,10 @@ enum evmc_loader_error_code
}; };
/** /**
* Dynamically loads the EVMC module with a VM implementation. * Dynamically loads the shared object (DLL) with an EVM implementation.
* *
* This function tries to open a dynamically loaded library (DLL) at the given `filename`. * This function tries to open a DLL at the given `filename`. On UNIX-like systems dlopen() function
* On UNIX-like systems dlopen() function is used. On Windows LoadLibrary() function is used. * is used. On Windows LoadLibrary() function is used.
* *
* If the file does not exist or is not a valid shared library the ::EVMC_LOADER_CANNOT_OPEN error * If the file does not exist or is not a valid shared library the ::EVMC_LOADER_CANNOT_OPEN error
* code is signaled and NULL is returned. * code is signaled and NULL is returned.
@ -77,36 +77,28 @@ enum evmc_loader_error_code
* It is safe to call this function with the same filename argument multiple times * It is safe to call this function with the same filename argument multiple times
* (the DLL is not going to be loaded multiple times). * (the DLL is not going to be loaded multiple times).
* *
* @param filename The null terminated path (absolute or relative) to an EVMC module * @param filename The null terminated path (absolute or relative) to the shared library
* (dynamically loaded library) containing the VM implementation. * containing the EVM implementation. If the value is NULL, an empty C-string
* If the value is NULL, an empty C-string or longer than the path maximum length * or longer than the path maximum length the ::EVMC_LOADER_INVALID_ARGUMENT is
* the ::EVMC_LOADER_INVALID_ARGUMENT is signaled. * signaled.
* @param error_code The pointer to the error code. If not NULL the value is set to * @param error_code The pointer to the error code. If not NULL the value is set to
* ::EVMC_LOADER_SUCCESS on success or any other error code as described above. * ::EVMC_LOADER_SUCCESS on success or any other error code as described above.
* @return The pointer to the EVM create function or NULL in case of error. * @return The pointer to the EVM create function or NULL.
*/ */
evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code); evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code);
/** /**
* Dynamically loads the EVMC module and creates the VM instance. * Dynamically loads the VM DLL and creates the VM instance.
* *
* This is a macro for creating the VM instance with the function returned from evmc_load(). * This is a macro for creating the VM instance with the function returned from evmc_load().
* The function signals the same errors as evmc_load() and additionally: * The function signals the same errors as evmc_load() and additionally:
* - ::EVMC_LOADER_INSTANCE_CREATION_FAILURE when the create function returns NULL, * - ::EVMC_LOADER_INSTANCE_CREATION_FAILURE when the create function returns NULL,
* - ::EVMC_LOADER_ABI_VERSION_MISMATCH when the created VM instance has ABI version different * - ::EVMC_LOADER_ABI_VERSION_MISMATCH when the created VM instance has ABI version different
* from the ABI version of this library (::EVMC_ABI_VERSION). * from the ABI version of this library (::EVMC_ABI_VERSION).
* *
* It is safe to call this function with the same filename argument multiple times: * It is safe to call this function with the same filename argument multiple times:
* the DLL is not going to be loaded multiple times, but the function will return new VM instance * the DLL is not going to be loaded multiple times, but the function will return new VM instance
* each time. * each time.
*
* @param filename The null terminated path (absolute or relative) to an EVMC module
* (dynamically loaded library) containing the VM implementation.
* If the value is NULL, an empty C-string or longer than the path maximum length
* the ::EVMC_LOADER_INVALID_ARGUMENT is signaled.
* @param error_code The pointer to the error code. If not NULL the value is set to
* ::EVMC_LOADER_SUCCESS on success or any other error code as described above.
* @return The pointer to the created VM or NULL in case of error.
*/ */
struct evmc_instance* evmc_load_and_create(const char* filename, struct evmc_instance* evmc_load_and_create(const char* filename,
enum evmc_loader_error_code* error_code); enum evmc_loader_error_code* error_code);

View File

@ -61,12 +61,10 @@ if (OSSFUZZ)
abiV2Proto.pb.cc abiV2Proto.pb.cc
) )
target_include_directories(abiv2_proto_ossfuzz PRIVATE target_include_directories(abiv2_proto_ossfuzz PRIVATE
/src/LPM/external.protobuf/include /usr/include/libprotobuf-mutator
/src/libprotobuf-mutator
/src/evmone/include
) )
target_link_libraries(abiv2_proto_ossfuzz PRIVATE solidity target_link_libraries(abiv2_proto_ossfuzz PRIVATE solidity
evmone intx ethash keccak evmc-instructions evmc evmone intx ethash evmc-instructions
protobuf-mutator-libfuzzer.a protobuf-mutator-libfuzzer.a
protobuf-mutator.a protobuf-mutator.a
protobuf.a protobuf.a

View File

@ -1,9 +1,12 @@
#pragma once #pragma once
#include <libsolidity/interface/CompilerStack.h> #include <libsolidity/interface/CompilerStack.h>
#include <libyul/AssemblyStack.h> #include <libyul/AssemblyStack.h>
#include <liblangutil/Exceptions.h> #include <liblangutil/Exceptions.h>
#include <liblangutil/SourceReferenceFormatter.h> #include <liblangutil/SourceReferenceFormatter.h>
#include <libdevcore/Keccak256.h> #include <libdevcore/Keccak256.h>
namespace dev namespace dev

View File

@ -18,8 +18,10 @@
#include <test/EVMHost.h> #include <test/EVMHost.h>
#include <test/tools/ossfuzz/abiV2FuzzerCommon.h> #include <test/tools/ossfuzz/abiV2FuzzerCommon.h>
#include <test/tools/ossfuzz/protoToAbiV2.h> #include <test/tools/ossfuzz/protoToAbiV2.h>
#include <evmone/evmone.h> #include <evmone/evmone.h>
#include <src/libfuzzer/libfuzzer_macro.h> #include <src/libfuzzer/libfuzzer_macro.h>
#include <fstream> #include <fstream>
static evmc::vm evmone = evmc::vm{evmc_create_evmone()}; static evmc::vm evmone = evmc::vm{evmc_create_evmone()};

View File

@ -300,7 +300,7 @@ void ProtoConverter::visit(DynamicByteArrayType const& _x)
visitType( visitType(
(_x.type() == DynamicByteArrayType::BYTES) ? DataType::BYTES : DataType::STRING, (_x.type() == DynamicByteArrayType::BYTES) ? DataType::BYTES : DataType::STRING,
bytesArrayTypeAsString(_x), bytesArrayTypeAsString(_x),
bytesArrayValueAsString() bytesArrayValueAsString(getNextCounter())
); );
} }
@ -630,7 +630,7 @@ std::string ProtoConverter::typedParametersAsString(CalleeType _calleeType)
} }
} }
// Function that is called by the factory contract /// Test function to be called externally.
void ProtoConverter::visit(TestFunction const& _x) void ProtoConverter::visit(TestFunction const& _x)
{ {
m_output << R"( m_output << R"(
@ -672,12 +672,12 @@ void ProtoConverter::writeHelperFunctions()
// memory/calldata and check if decoded value matches storage value // memory/calldata and check if decoded value matches storage value
// return true on successful match, false otherwise // return true on successful match, false otherwise
m_output << Whiskers(R"( m_output << Whiskers(R"(
function coder_public(<parameters_memory>) public view returns (uint) { function coder_public(<parameters_memory>) public pure returns (uint) {
<equality_checks> <equality_checks>
return 0; return 0;
} }
function coder_external(<parameters_calldata>) external view returns (uint) { function coder_external(<parameters_calldata>) external pure returns (uint) {
<equality_checks> <equality_checks>
return 0; return 0;
} }
@ -693,13 +693,6 @@ void ProtoConverter::visit(Contract const& _x)
m_output << R"(pragma solidity >=0.0; m_output << R"(pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
contract Factory {
function test() external returns (uint) {
C c = new C();
return c.test();
}
}
contract C { contract C {
)"; )";
// TODO: Support more than one but less than N state variables // TODO: Support more than one but less than N state variables

View File

@ -14,18 +14,10 @@
* pragma solidity >=0.0; * pragma solidity >=0.0;
* pragma experimental ABIEncoderV2; * pragma experimental ABIEncoderV2;
* *
* contract Factory {
* // Factory test function. Called by EVM client
* function test() external returns (uint) {
* C c = new C();
* return c.test();
* }
* }
*
* contract C { * contract C {
* // State variable * // State variable
* string x_0; * string x_0;
* // Test function. Called by Factory test function * // Test function that is called by the VM.
* function test() public returns (uint) { * function test() public returns (uint) {
* // Local variable * // Local variable
* bytes x_1 = "1"; * bytes x_1 = "1";
@ -45,7 +37,7 @@
* *
* // Public function that is called by test() function. Accepts one or more arguments and returns * // Public function that is called by test() function. Accepts one or more arguments and returns
* // a uint value (zero if abi en/decoding was successful, non-zero otherwise) * // a uint value (zero if abi en/decoding was successful, non-zero otherwise)
* function coder_public(string memory c_0, bytes memory c_1) public view returns (uint) { * function coder_public(string memory c_0, bytes memory c_1) public pure returns (uint) {
* if (!bytesCompare(bytes(c_0), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")) * if (!bytesCompare(bytes(c_0), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"))
* return 1; * return 1;
* if (!bytesCompare(c_1, "1")) * if (!bytesCompare(c_1, "1"))
@ -55,7 +47,7 @@
* *
* // External function that is called by test() function. Accepts one or more arguments and returns * // External function that is called by test() function. Accepts one or more arguments and returns
* // a uint value (zero if abi en/decoding was successful, non-zero otherwise) * // a uint value (zero if abi en/decoding was successful, non-zero otherwise)
* function coder_external(string calldata c_0, bytes calldata c_1) external view returns (uint) { * function coder_external(string calldata c_0, bytes calldata c_1) external pure returns (uint) {
* if (!stringCompare(c_0, "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")) * if (!stringCompare(c_0, "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"))
* return 1; * return 1;
* if (!bytesCompare(c_1, "1")) * if (!bytesCompare(c_1, "1"))
@ -243,9 +235,9 @@ private:
// String and bytes literals are derived by hashing a monotonically increasing // String and bytes literals are derived by hashing a monotonically increasing
// counter and enclosing the said hash inside double quotes. // counter and enclosing the said hash inside double quotes.
std::string bytesArrayValueAsString() std::string bytesArrayValueAsString(unsigned _counter)
{ {
return "\"" + toHex(hashUnsignedInt(getNextCounter()), HexPrefix::DontAdd) + "\""; return "\"" + toHex(hashUnsignedInt(_counter), HexPrefix::DontAdd) + "\"";
} }
std::string getQualifier(DataType _dataType) std::string getQualifier(DataType _dataType)