mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Draft
This commit is contained in:
parent
3045770a6f
commit
68146e7c28
@ -29,6 +29,11 @@
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
|
||||
#include <test/tools/ossfuzz/yulFuzzerCommon.h>
|
||||
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
@ -36,6 +41,22 @@ using namespace solidity;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::evmasm;
|
||||
using namespace solidity::langutil;
|
||||
using namespace solidity::yul;
|
||||
using namespace solidity::yul::test::yul_fuzzer;
|
||||
|
||||
namespace
|
||||
{
|
||||
void printErrors(ostream& _stream, ErrorList const& _errors)
|
||||
{
|
||||
SourceReferenceFormatter formatter(_stream);
|
||||
|
||||
for (auto const& error: _errors)
|
||||
formatter.printExceptionInformation(
|
||||
*error,
|
||||
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static vector<EVMVersion> s_evmVersions = {
|
||||
EVMVersion::homestead(),
|
||||
@ -81,6 +102,73 @@ void FuzzerUtil::forceSMT(StringMap& _input)
|
||||
sourceUnit.second += smtPragma;
|
||||
}
|
||||
|
||||
void FuzzerUtil::yulIRDiff(EVMVersion _version, string const& _ir, string const& _irOpt)
|
||||
{
|
||||
YulStringRepository::reset();
|
||||
|
||||
if (_ir.empty() && _irOpt.empty())
|
||||
return;
|
||||
|
||||
// AssemblyStack entry point
|
||||
AssemblyStack stackIr(
|
||||
_version,
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
solidity::frontend::OptimiserSettings::full()
|
||||
);
|
||||
|
||||
// Parse protobuf mutated YUL code
|
||||
if (
|
||||
!stackIr.parseAndAnalyze("source", _ir) ||
|
||||
!stackIr.parserResult()->code ||
|
||||
!stackIr.parserResult()->analysisInfo ||
|
||||
!Error::containsOnlyWarnings(stackIr.errors())
|
||||
)
|
||||
{
|
||||
std::cout << _ir << std::endl;
|
||||
printErrors(std::cout, stackIr.errors());
|
||||
yulAssert(false, "Compiler generated malformed IR");
|
||||
}
|
||||
|
||||
AssemblyStack stackIrOpt(
|
||||
_version,
|
||||
AssemblyStack::Language::StrictAssembly,
|
||||
solidity::frontend::OptimiserSettings::full()
|
||||
);
|
||||
|
||||
// Parse protobuf mutated YUL code
|
||||
if (
|
||||
!stackIrOpt.parseAndAnalyze("source", _irOpt) ||
|
||||
!stackIrOpt.parserResult()->code ||
|
||||
!stackIrOpt.parserResult()->analysisInfo ||
|
||||
!Error::containsOnlyWarnings(stackIrOpt.errors())
|
||||
)
|
||||
{
|
||||
std::cout << _irOpt << std::endl;
|
||||
printErrors(std::cout, stackIrOpt.errors());
|
||||
yulAssert(false, "Compiler generated malformed optimized IR");
|
||||
}
|
||||
|
||||
ostringstream os1;
|
||||
ostringstream os2;
|
||||
yulFuzzerUtil::interpret(
|
||||
os1,
|
||||
stackIr.parserResult()->code,
|
||||
EVMDialect::strictAssemblyForEVMObjects(_version)
|
||||
);
|
||||
|
||||
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
|
||||
os2,
|
||||
stackIrOpt.parserResult()->code,
|
||||
EVMDialect::strictAssemblyForEVMObjects(_version)
|
||||
);
|
||||
|
||||
if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached)
|
||||
return;
|
||||
|
||||
bool isTraceEq = (os1.str() == os2.str());
|
||||
yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ.");
|
||||
}
|
||||
|
||||
void FuzzerUtil::testCompiler(StringMap& _input, bool _optimize, unsigned _rand, bool _forceSMT)
|
||||
{
|
||||
frontend::CompilerStack compiler;
|
||||
@ -96,11 +184,23 @@ void FuzzerUtil::testCompiler(StringMap& _input, bool _optimize, unsigned _rand,
|
||||
compiler.setModelCheckerSettings({frontend::ModelCheckerEngine::All(), frontend::ModelCheckerTargets::All(), /*timeout=*/1});
|
||||
}
|
||||
compiler.setSources(_input);
|
||||
compiler.enableIRGeneration();
|
||||
compiler.setEVMVersion(evmVersion);
|
||||
compiler.setOptimiserSettings(optimiserSettings);
|
||||
try
|
||||
{
|
||||
compiler.compile();
|
||||
if (compiler.compile() && !compiler.contractNames().empty())
|
||||
{
|
||||
string lastContractName = compiler.lastContractName();
|
||||
yulIRDiff(
|
||||
evmVersion,
|
||||
compiler.yulIR(lastContractName),
|
||||
compiler.yulIROptimized(lastContractName)
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (InternalCompilerError const&)
|
||||
{
|
||||
}
|
||||
catch (Error const&)
|
||||
{
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
@ -46,4 +47,5 @@ struct FuzzerUtil
|
||||
/// Adds the experimental SMTChecker pragma to each source file in the
|
||||
/// source map.
|
||||
static void forceSMT(solidity::StringMap& _input);
|
||||
static void yulIRDiff(solidity::langutil::EVMVersion _version, std::string const& _ir, std::string const& _irOpt);
|
||||
};
|
||||
|
@ -28,8 +28,13 @@ if (OSSFUZZ)
|
||||
solc_opt_ossfuzz.cpp
|
||||
../fuzzer_common.cpp
|
||||
../../TestCaseReader.cpp
|
||||
yulFuzzerCommon.cpp
|
||||
)
|
||||
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm)
|
||||
target_compile_options(solc_opt_ossfuzz
|
||||
PUBLIC
|
||||
${COMPILE_OPTIONS} -Wno-extra-semi -Wno-unused-parameter
|
||||
)
|
||||
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm yul yulInterpreter)
|
||||
set_target_properties(solc_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(solc_opt_mutator_ossfuzz
|
||||
@ -46,8 +51,13 @@ if (OSSFUZZ)
|
||||
solc_noopt_ossfuzz.cpp
|
||||
../fuzzer_common.cpp
|
||||
../../TestCaseReader.cpp
|
||||
yulFuzzerCommon.cpp
|
||||
)
|
||||
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm)
|
||||
target_compile_options(solc_noopt_ossfuzz
|
||||
PUBLIC
|
||||
${COMPILE_OPTIONS} -Wno-extra-semi -Wno-unused-parameter
|
||||
)
|
||||
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm yul yulInterpreter)
|
||||
set_target_properties(solc_noopt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(solc_noopt_mutator_ossfuzz
|
||||
|
@ -30,7 +30,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size);
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
|
||||
{
|
||||
if (_size <= 600)
|
||||
if (_size <= 4096)
|
||||
{
|
||||
string input(reinterpret_cast<char const*>(_data), _size);
|
||||
map<string, string> sourceCode;
|
||||
|
@ -40,7 +40,7 @@ struct yulFuzzerUtil
|
||||
size_t _maxTraceSize = maxTraceSize,
|
||||
size_t _maxExprNesting = maxExprNesting
|
||||
);
|
||||
static size_t constexpr maxSteps = 100;
|
||||
static size_t constexpr maxSteps = 10000000;
|
||||
static size_t constexpr maxTraceSize = 75;
|
||||
static size_t constexpr maxExprNesting = 64;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user