mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Yul interpreter: Add flag to disable memory tracing and dump for fuzzing.
Model revert in yul interpreter. Add logTrace for a few more instructions and clear trace on revert.
This commit is contained in:
@@ -81,10 +81,15 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
|
||||
|
||||
ostringstream os1;
|
||||
ostringstream os2;
|
||||
// Disable memory tracing to avoid false positive reports
|
||||
// such as unused write to memory e.g.,
|
||||
// { mstore(0, 1) }
|
||||
// that would be removed by the redundant store eliminator.
|
||||
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
|
||||
os1,
|
||||
stack.parserResult()->code,
|
||||
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion())
|
||||
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
|
||||
/*disableMemoryTracing=*/true
|
||||
);
|
||||
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
|
||||
return 0;
|
||||
@@ -93,7 +98,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
|
||||
termReason = yulFuzzerUtil::interpret(
|
||||
os2,
|
||||
stack.parserResult()->code,
|
||||
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion())
|
||||
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
|
||||
/*disableMemoryTracing=*/true
|
||||
);
|
||||
|
||||
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
|
||||
|
||||
@@ -26,6 +26,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
|
||||
ostream& _os,
|
||||
shared_ptr<yul::Block> _ast,
|
||||
Dialect const& _dialect,
|
||||
bool _disableMemoryTracing,
|
||||
bool _outputStorageOnly,
|
||||
size_t _maxSteps,
|
||||
size_t _maxTraceSize,
|
||||
@@ -52,7 +53,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
|
||||
TerminationReason reason = TerminationReason::None;
|
||||
try
|
||||
{
|
||||
Interpreter::run(state, _dialect, *_ast);
|
||||
Interpreter::run(state, _dialect, *_ast, _disableMemoryTracing);
|
||||
}
|
||||
catch (StepLimitReached const&)
|
||||
{
|
||||
@@ -74,7 +75,7 @@ yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
|
||||
if (_outputStorageOnly)
|
||||
state.dumpStorage(_os);
|
||||
else
|
||||
state.dumpTraceAndState(_os);
|
||||
state.dumpTraceAndState(_os, _disableMemoryTracing);
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,17 @@ struct yulFuzzerUtil
|
||||
None
|
||||
};
|
||||
|
||||
/// Interprets the Yul AST pointed to by @param _ast. Flag @param _outputStorageOnly
|
||||
/// (unset by default) outputs an execution trace of both memory and storage;
|
||||
/// if set, only storage contents are output as part of the execution trace. The
|
||||
/// latter avoids false positives that will be produced by the fuzzer when certain
|
||||
/// optimizer steps are activated e.g., Redundant store eliminator, Equal store
|
||||
/// eliminator.
|
||||
static TerminationReason interpret(
|
||||
std::ostream& _os,
|
||||
std::shared_ptr<yul::Block> _ast,
|
||||
Dialect const& _dialect,
|
||||
bool _disableMemoryTracing = false,
|
||||
bool _outputStorageOnly = false,
|
||||
size_t _maxSteps = maxSteps,
|
||||
size_t _maxTraceSize = maxTraceSize,
|
||||
|
||||
@@ -88,10 +88,15 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
|
||||
ostringstream os1;
|
||||
ostringstream os2;
|
||||
// Disable memory tracing to avoid false positive reports
|
||||
// such as unused write to memory e.g.,
|
||||
// { mstore(0, 1) }
|
||||
// that would be removed by the redundant store eliminator.
|
||||
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
|
||||
os1,
|
||||
stack.parserResult()->code,
|
||||
EVMDialect::strictAssemblyForEVMObjects(version)
|
||||
EVMDialect::strictAssemblyForEVMObjects(version),
|
||||
/*disableMemoryTracing=*/true
|
||||
);
|
||||
|
||||
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
|
||||
@@ -107,12 +112,18 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
termReason = yulFuzzerUtil::interpret(
|
||||
os2,
|
||||
astBlock,
|
||||
EVMDialect::strictAssemblyForEVMObjects(version)
|
||||
EVMDialect::strictAssemblyForEVMObjects(version),
|
||||
true
|
||||
);
|
||||
if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
|
||||
return;
|
||||
|
||||
bool isTraceEq = (os1.str() == os2.str());
|
||||
yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ.");
|
||||
if (!isTraceEq)
|
||||
{
|
||||
cout << os1.str() << endl;
|
||||
cout << os2.str() << endl;
|
||||
yulAssert(false, "Interpreted traces for optimized and unoptimized code differ.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user