diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index 7a9caab651..7a92d3014d 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -89,7 +89,7 @@ CodeAnalysis analyze_eof1(bytes_view container) // FIXME: Better way of getting EOF version. const auto eof_version = container[2]; - return CodeAnalysis{executable_code, {}, eof_version, relative_offsets}; + return CodeAnalysis{executable_code, {}, eof_version, relative_offsets, header}; } } // namespace diff --git a/lib/evmone/baseline.hpp b/lib/evmone/baseline.hpp index 1519534bc7..91e47f6a8f 100644 --- a/lib/evmone/baseline.hpp +++ b/lib/evmone/baseline.hpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once +#include "eof.hpp" #include #include #include @@ -30,6 +31,7 @@ class CodeAnalysis /// Offset of each code section relative to the beginning of the first code /// section. We flatten the sections for cheap execution. CodeOffsets code_offsets; + EOF1Header eof_header; private: /// Padded code for faster legacy code execution. @@ -43,11 +45,13 @@ class CodeAnalysis m_padded_code{std::move(padded_code)} {} - CodeAnalysis(bytes_view code, JumpdestMap map, uint8_t version, CodeOffsets offsets) + CodeAnalysis( + bytes_view code, JumpdestMap map, uint8_t version, CodeOffsets offsets, EOF1Header header) : executable_code{code}, jumpdest_map{std::move(map)}, eof_version{version}, - code_offsets{std::move(offsets)} + code_offsets{std::move(offsets)}, + eof_header{std::move(header)} {} }; static_assert(std::is_move_constructible_v); diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 6a95e48662..0fc08d12c2 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -933,10 +933,20 @@ evmc_status_code create_impl(StackTop stack, ExecutionState& state) noexcept; inline constexpr auto create = create_impl; inline constexpr auto create2 = create_impl; -inline code_iterator callf(StackTop /*stack*/, ExecutionState& state, code_iterator pos) noexcept +inline code_iterator callf(StackTop stack, ExecutionState& state, code_iterator pos) noexcept { const auto index = read_uint16_be(&pos[1]); + state.call_stack.push_back(pos + 3); + + const auto stack_size = &stack.top() - state.stack_space.bottom(); + if (stack_size + state.analysis.baseline->eof_header.types[index].max_stack_height > + StackSpace::limit) + { + state.status = EVMC_STACK_OVERFLOW; + return nullptr; + } + const auto offset = state.analysis.baseline->code_offsets[index]; auto code = state.analysis.baseline->executable_code; return code.data() + offset;