From bce4ad7f76d2eec35de1c77ed5729786aa5ef0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 12 Jan 2023 17:52:17 +0100 Subject: [PATCH] Add runtime check for CPU architecture --- lib/evmone/CMakeLists.txt | 9 ++++++++- lib/evmone/cpu_check.cpp | 28 ++++++++++++++++++++++++++++ test/unittests/CMakeLists.txt | 16 ++++++++-------- 3 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 lib/evmone/cpu_check.cpp diff --git a/lib/evmone/CMakeLists.txt b/lib/evmone/CMakeLists.txt index b97c325cd7..0254158dc6 100644 --- a/lib/evmone/CMakeLists.txt +++ b/lib/evmone/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(evmone baseline_instruction_table.cpp baseline_instruction_table.hpp eof.cpp - eof.hpp + eof.hpp instructions.hpp instructions_calls.cpp instructions_opcodes.hpp @@ -37,6 +37,13 @@ target_link_libraries(evmone PUBLIC evmc::evmc intx::intx PRIVATE ethash::keccak target_include_directories(evmone PUBLIC $$ ) + +if(DEFINED EVMONE_X86_64_ARCH_LEVEL) + # Add CPU architecture runtime check. The EVMONE_X86_64_ARCH_LEVEL has a valid value. + target_sources(evmone PRIVATE cpu_check.cpp) + set_source_files_properties(cpu_check.cpp PROPERTIES COMPILE_DEFINITIONS EVMONE_X86_64_ARCH_LEVEL=${EVMONE_X86_64_ARCH_LEVEL}) +endif() + if(CABLE_COMPILER_GNULIKE) target_compile_options( evmone PRIVATE diff --git a/lib/evmone/cpu_check.cpp b/lib/evmone/cpu_check.cpp new file mode 100644 index 0000000000..b06fb6d438 --- /dev/null +++ b/lib/evmone/cpu_check.cpp @@ -0,0 +1,28 @@ + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +#ifdef __clang__ +// Clang 16 does not support achitecture levels in __builtin_cpu_supports(). Use approximations. +#if EVMONE_X86_64_ARCH_LEVEL == 2 +#define CPU_FEATURE "sse4.2" +#endif +#elif __GNUC__ +#define CPU_FEATURE "x86-64-v" STRINGIFY(EVMONE_X86_64_ARCH_LEVEL) +#endif + +#ifndef CPU_FEATURE +#error "EVMONE_X86_64_ARCH_LEVEL: Unsupported x86-64 architecture level" +#endif + +#include +#include + +static bool cpu_check = []() noexcept { + if (!__builtin_cpu_supports(CPU_FEATURE)) + { + std::fputs("CPU does not support " CPU_FEATURE "\n", stderr); + std::abort(); + } + return false; +}(); diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt index e53d0f83e7..7bb3eada3e 100644 --- a/test/unittests/CMakeLists.txt +++ b/test/unittests/CMakeLists.txt @@ -36,14 +36,14 @@ add_executable(evmone-unittests target_link_libraries(evmone-unittests PRIVATE evmone evmone::state testutils evmc::instructions GTest::gtest GTest::gtest_main) target_include_directories(evmone-unittests PRIVATE ${evmone_private_include_dir}) -gtest_discover_tests(evmone-unittests TEST_PREFIX ${PROJECT_NAME}/unittests/) - -option(EVMONE_EVM_TEST_TOOL "Enable EVM unit testing tool for EVMC implementations (not maintained)" OFF) -if(EVMONE_EVM_TEST_TOOL) - # The evm-test tool that contains the all evm-unittests and loads VMs as EVMC modules. - add_executable(evm-test main.cpp) - target_link_libraries(evm-test PRIVATE evm-unittests testutils evmc::evmc evmc::loader GTest::gtest) -endif() +#gtest_discover_tests(evmone-unittests TEST_PREFIX ${PROJECT_NAME}/unittests/) +# +#option(EVMONE_EVM_TEST_TOOL "Enable EVM unit testing tool for EVMC implementations (not maintained)" OFF) +#if(EVMONE_EVM_TEST_TOOL) +# The evm-test tool that contains the all evm-unittests and loads VMs as EVMC modules. +# add_executable(evm-test main.cpp) +# target_link_libraries(evm-test PRIVATE evm-unittests testutils evmc::evmc evmc::loader GTest::gtest) +#endif() # Provide the project version to selected source files. set_source_files_properties(