From 21423925e69601c479e415183110fdc41f4c4741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 16 Sep 2019 21:22:04 +0200 Subject: [PATCH 1/3] Fix cast to broad in scope --- lib/evmone/analysis.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/evmone/analysis.cpp b/lib/evmone/analysis.cpp index c2c59151c8..cb23f7452e 100644 --- a/lib/evmone/analysis.cpp +++ b/lib/evmone/analysis.cpp @@ -91,7 +91,7 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) case ANY_SMALL_PUSH: { - const auto push_size = size_t(opcode - OP_PUSH1 + 1); + const auto push_size = static_cast(opcode - OP_PUSH1) + 1; const auto push_end = code_pos + push_size; uint8_t value_bytes[8]{}; @@ -106,7 +106,7 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) case ANY_LARGE_PUSH: { - const auto push_size = size_t(opcode - OP_PUSH1 + 1); + const auto push_size = static_cast(opcode - OP_PUSH1) + 1; const auto push_end = code_pos + push_size; auto& push_value = analysis.push_values.emplace_back(); From 408ad24ac330eefeb4e214326aa9d28a162cb491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 16 Sep 2019 21:24:06 +0200 Subject: [PATCH 2/3] Make small push value parsing endianness independent This way is also faster. --- lib/evmone/analysis.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/lib/evmone/analysis.cpp b/lib/evmone/analysis.cpp index cb23f7452e..499b2d0046 100644 --- a/lib/evmone/analysis.cpp +++ b/lib/evmone/analysis.cpp @@ -23,13 +23,6 @@ struct block_analysis explicit block_analysis(size_t index) noexcept : begin_block_index{index} {} }; -inline constexpr uint64_t load64be(const unsigned char* data) noexcept -{ - return uint64_t{data[7]} | (uint64_t{data[6]} << 8) | (uint64_t{data[5]} << 16) | - (uint64_t{data[4]} << 24) | (uint64_t{data[3]} << 32) | (uint64_t{data[2]} << 40) | - (uint64_t{data[1]} << 48) | (uint64_t{data[0]} << 56); -} - code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) noexcept { static constexpr auto stack_req_max = std::numeric_limits::max(); @@ -94,13 +87,14 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) const auto push_size = static_cast(opcode - OP_PUSH1) + 1; const auto push_end = code_pos + push_size; - uint8_t value_bytes[8]{}; - auto insert_pos = &value_bytes[sizeof(value_bytes) - push_size]; - - // TODO: Consier the same endianness-specific loop as in ANY_LARGE_PUSH case. + uint64_t value = 0; + auto insert_bit_pos = (push_size - 1) * 8; while (code_pos < push_end && code_pos < code_end) - *insert_pos++ = *code_pos++; - instr.arg.small_push_value = load64be(value_bytes); + { + value |= uint64_t{*code_pos++} << insert_bit_pos; + insert_bit_pos -= 8; + } + instr.arg.small_push_value = value; break; } From 95b9b0496cbb8847000a527ac343dca29a86f27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 17 Sep 2019 12:09:39 +0200 Subject: [PATCH 3/3] Find single push_end value --- lib/evmone/analysis.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/evmone/analysis.cpp b/lib/evmone/analysis.cpp index 499b2d0046..763018ab98 100644 --- a/lib/evmone/analysis.cpp +++ b/lib/evmone/analysis.cpp @@ -85,11 +85,11 @@ code_analysis analyze(evmc_revision rev, const uint8_t* code, size_t code_size) case ANY_SMALL_PUSH: { const auto push_size = static_cast(opcode - OP_PUSH1) + 1; - const auto push_end = code_pos + push_size; + const auto push_end = std::min(code_pos + push_size, code_end); uint64_t value = 0; auto insert_bit_pos = (push_size - 1) * 8; - while (code_pos < push_end && code_pos < code_end) + while (code_pos < push_end) { value |= uint64_t{*code_pos++} << insert_bit_pos; insert_bit_pos -= 8;