Skip to content

Commit

Permalink
Merge pull request #536 from ethereum/fix-eof-tracing
Browse files Browse the repository at this point in the history
Fix instruction tracing of EOF code
  • Loading branch information
gumb0 authored Dec 7, 2022
2 parents 83ad7bc + ec2ea9f commit 6d03f5d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 16 deletions.
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":""}
)");
}

0 comments on commit 6d03f5d

Please sign in to comment.