Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix instruction tracing of EOF code #536

Merged
merged 2 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lib/evmone/baseline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ std::unique_ptr<uint8_t[]> pad_code(bytes_view code)
CodeAnalysis analyze_legacy(bytes_view code)
{
// TODO: The padded code buffer and jumpdest bitmap can be created with single allocation.
return {pad_code(code), analyze_jumpdests(code)};
return {pad_code(code), code.size(), analyze_jumpdests(code)};
}

CodeAnalysis analyze_eof1(bytes_view eof_container, const EOF1Header& header)
{
const auto executable_code = eof_container.substr(header.code_begin(), header.code_size);
return {executable_code.data(), analyze_jumpdests(executable_code)};
return {executable_code, analyze_jumpdests(executable_code)};
}
} // namespace

Expand Down Expand Up @@ -326,17 +326,17 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana
auto* tracer = vm.get_tracer();
if (INTX_UNLIKELY(tracer != nullptr))
{
tracer->notify_execution_start(state.rev, *state.msg, state.original_code);
dispatch<true>(cost_table, state, code, tracer);
tracer->notify_execution_start(state.rev, *state.msg, analysis.executable_code);
dispatch<true>(cost_table, state, code.data(), tracer);
}
else
{
#if EVMONE_CGOTO_SUPPORTED
if (vm.cgoto)
dispatch_cgoto(cost_table, state, code);
dispatch_cgoto(cost_table, state, code.data());
else
#endif
dispatch<false>(cost_table, state, code);
dispatch<false>(cost_table, state, code.data());
}

const auto gas_left =
Expand Down
10 changes: 5 additions & 5 deletions lib/evmone/baseline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@ class CodeAnalysis
public:
using JumpdestMap = std::vector<bool>;

const uint8_t* executable_code; ///< Pointer to the beginning of executable code section.
JumpdestMap jumpdest_map; ///< Map of valid jump destinations.
bytes_view executable_code; ///< Executable code section.
JumpdestMap jumpdest_map; ///< Map of valid jump destinations.

private:
/// Padded code for faster legacy code execution.
/// If not nullptr the executable_code must point to it.
std::unique_ptr<uint8_t[]> m_padded_code;

public:
CodeAnalysis(std::unique_ptr<uint8_t[]> padded_code, JumpdestMap map)
: executable_code{padded_code.get()},
CodeAnalysis(std::unique_ptr<uint8_t[]> padded_code, size_t code_size, JumpdestMap map)
: executable_code{padded_code.get(), code_size},
jumpdest_map{std::move(map)},
m_padded_code{std::move(padded_code)}
{}

CodeAnalysis(const uint8_t* code, JumpdestMap map)
CodeAnalysis(bytes_view code, JumpdestMap map)
: executable_code{code}, jumpdest_map{std::move(map)}
{}
};
Expand Down
4 changes: 2 additions & 2 deletions lib/evmone/instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ inline code_iterator jump_impl(ExecutionState& state, const uint256& dst) noexce
return nullptr;
}

return state.analysis.baseline->executable_code + static_cast<size_t>(dst);
return &state.analysis.baseline->executable_code[static_cast<size_t>(dst)];
}

/// JUMP instruction implementation using baseline::CodeAnalysis.
Expand All @@ -703,7 +703,7 @@ inline code_iterator jumpi(StackTop stack, ExecutionState& state, code_iterator

inline code_iterator pc(StackTop stack, ExecutionState& state, code_iterator pos) noexcept
{
stack.push(static_cast<uint64_t>(pos - state.analysis.baseline->executable_code));
stack.push(static_cast<uint64_t>(pos - state.analysis.baseline->executable_code.data()));
return pos + 1;
}

Expand Down
22 changes: 19 additions & 3 deletions test/unittests/tracing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ class tracing : public Test
vm{*static_cast<evmone::VM*>(m_baseline_vm.get_raw_pointer())}
{}

std::string trace(bytes_view code, int32_t depth = 0, uint32_t flags = 0)
std::string trace(
bytes_view code, int32_t depth = 0, uint32_t flags = 0, evmc_revision rev = EVMC_BERLIN)
{
evmc::MockedHost host;
evmc_message msg{};
msg.flags = flags;
msg.depth = depth;
msg.flags = flags;
msg.gas = 1000000;
m_baseline_vm.execute(host, EVMC_BERLIN, msg, code.data(), code.size());
m_baseline_vm.execute(host, rev, msg, code.data(), code.size());
auto result = trace_stream.str();
trace_stream.str({});
return result;
Expand Down Expand Up @@ -290,3 +291,18 @@ TEST_F(tracing, trace_code_containing_zero)

EXPECT_EQ(tracer.get_last_code().size(), code.size());
}

TEST_F(tracing, trace_eof)
{
vm.add_tracer(evmone::create_instruction_tracer(trace_stream));

trace_stream << '\n';
EXPECT_EQ(trace(eof1_bytecode(add(2, 3) + OP_STOP), 0, 0, EVMC_SHANGHAI), R"(
{"depth":0,"rev":"Shanghai","static":false}
{"pc":0,"op":96,"opName":"PUSH1","gas":1000000,"stack":[],"memorySize":0}
{"pc":2,"op":96,"opName":"PUSH1","gas":999997,"stack":["0x3"],"memorySize":0}
{"pc":4,"op":1,"opName":"ADD","gas":999994,"stack":["0x3","0x2"],"memorySize":0}
{"pc":5,"op":0,"opName":"STOP","gas":999991,"stack":["0x5"],"memorySize":0}
{"error":null,"gas":999991,"gasUsed":9,"output":""}
)");
}