diff options
Diffstat (limited to 'deps/v8/test/fuzzer')
-rw-r--r-- | deps/v8/test/fuzzer/multi-return.cc | 5 | ||||
-rw-r--r-- | deps/v8/test/fuzzer/regexp-builtins.cc | 14 | ||||
-rw-r--r-- | deps/v8/test/fuzzer/wasm-async.cc | 4 | ||||
-rw-r--r-- | deps/v8/test/fuzzer/wasm-compile.cc | 21 | ||||
-rw-r--r-- | deps/v8/test/fuzzer/wasm-fuzzer-common.cc | 49 | ||||
-rw-r--r-- | deps/v8/test/fuzzer/wasm.cc | 8 |
6 files changed, 65 insertions, 36 deletions
diff --git a/deps/v8/test/fuzzer/multi-return.cc b/deps/v8/test/fuzzer/multi-return.cc index 4f109228a5..0be812c8dd 100644 --- a/deps/v8/test/fuzzer/multi-return.cc +++ b/deps/v8/test/fuzzer/multi-return.cc @@ -19,6 +19,7 @@ #include "src/optimized-compilation-info.h" #include "src/simulator.h" #include "src/wasm/wasm-engine.h" +#include "src/wasm/wasm-features.h" #include "src/wasm/wasm-limits.h" #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-objects.h" @@ -160,7 +161,8 @@ std::unique_ptr<wasm::NativeModule> AllocateNativeModule(i::Isolate* isolate, // WasmCallDescriptor assumes that code is on the native heap and not // within a code object. return isolate->wasm_engine()->code_manager()->NewNativeModule( - isolate, code_size, false, std::move(module), env); + isolate, i::wasm::kAllWasmFeatures, code_size, false, std::move(module), + env); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -306,6 +308,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { &wrapper_info, i_isolate, wrapper_desc, caller.graph(), AssemblerOptions::Default(i_isolate), caller.Export()) .ToHandleChecked(); + auto fn = GeneratedCode<int32_t>::FromCode(*wrapper_code); int result = fn.Call(); diff --git a/deps/v8/test/fuzzer/regexp-builtins.cc b/deps/v8/test/fuzzer/regexp-builtins.cc index 495604b071..c4ff115d72 100644 --- a/deps/v8/test/fuzzer/regexp-builtins.cc +++ b/deps/v8/test/fuzzer/regexp-builtins.cc @@ -319,12 +319,12 @@ std::string GenerateSourceString(FuzzerArgs* args, const std::string& test) { return ss.str(); } -void PrintExceptionMessage(v8::TryCatch* try_catch) { +void PrintExceptionMessage(v8::Isolate* isolate, v8::TryCatch* try_catch) { CHECK(try_catch->HasCaught()); static const int kBufferLength = 256; char buffer[kBufferLength + 1]; try_catch->Message()->Get()->WriteOneByte( - reinterpret_cast<uint8_t*>(&buffer[0]), 0, kBufferLength); + isolate, reinterpret_cast<uint8_t*>(&buffer[0]), 0, kBufferLength); fprintf(stderr, "%s\n", buffer); } @@ -337,9 +337,10 @@ bool ResultsAreIdentical(FuzzerArgs* args) { "assertEquals(fast.re.lastIndex, slow.re.lastIndex);\n"; v8::Local<v8::Value> result; - v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(args->isolate)); + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(args->isolate); + v8::TryCatch try_catch(isolate); if (!CompileRun(args->context, source.c_str()).ToLocal(&result)) { - PrintExceptionMessage(&try_catch); + PrintExceptionMessage(isolate, &try_catch); args->isolate->clear_pending_exception(); return false; } @@ -349,14 +350,15 @@ bool ResultsAreIdentical(FuzzerArgs* args) { void CompileRunAndVerify(FuzzerArgs* args, const std::string& source) { v8::Local<v8::Value> result; - v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(args->isolate)); + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(args->isolate); + v8::TryCatch try_catch(isolate); if (!CompileRun(args->context, source.c_str()).ToLocal(&result)) { args->isolate->clear_pending_exception(); // No need to verify result if an exception was thrown here, since that // implies a syntax error somewhere in the pattern or string. We simply // ignore those. if (kVerbose) { - PrintExceptionMessage(&try_catch); + PrintExceptionMessage(isolate, &try_catch); fprintf(stderr, "Failed to run script:\n```\n%s\n```\n", source.c_str()); } return; diff --git a/deps/v8/test/fuzzer/wasm-async.cc b/deps/v8/test/fuzzer/wasm-async.cc index 5ceb8d8bf8..8e140b71f2 100644 --- a/deps/v8/test/fuzzer/wasm-async.cc +++ b/deps/v8/test/fuzzer/wasm-async.cc @@ -68,8 +68,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { testing::SetupIsolateForWasmModule(i_isolate); bool done = false; + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); i_isolate->wasm_engine()->AsyncCompile( - i_isolate, base::make_unique<AsyncFuzzerResolver>(i_isolate, &done), + i_isolate, enabled_features, + std::make_shared<AsyncFuzzerResolver>(i_isolate, &done), ModuleWireBytes(data, data + size), false); // Wait for the promise to resolve. diff --git a/deps/v8/test/fuzzer/wasm-compile.cc b/deps/v8/test/fuzzer/wasm-compile.cc index 93c03a92db..a9f4382cd1 100644 --- a/deps/v8/test/fuzzer/wasm-compile.cc +++ b/deps/v8/test/fuzzer/wasm-compile.cc @@ -43,8 +43,10 @@ class DataRange { // lead to OOM because the end might not be reached. // Define move constructor and move assignment, disallow copy constructor and // copy assignment (below). - DataRange(DataRange&& other) : DataRange(other.data_) { other.data_ = {}; } - DataRange& operator=(DataRange&& other) { + DataRange(DataRange&& other) V8_NOEXCEPT : DataRange(other.data_) { + other.data_ = {}; + } + DataRange& operator=(DataRange&& other) V8_NOEXCEPT { data_ = other.data_; other.data_ = {}; return *this; @@ -380,9 +382,9 @@ class WasmGenerator { void set_global(DataRange& data) { global_op<kWasmStmt>(data); } - template <ValueType T1, ValueType T2> + template <ValueType... Types> void sequence(DataRange& data) { - Generate<T1, T2>(data); + Generate<Types...>(data); } void current_memory(DataRange& data) { @@ -472,6 +474,9 @@ void WasmGenerator::Generate<kWasmStmt>(DataRange& data) { constexpr generate_fn alternates[] = { &WasmGenerator::sequence<kWasmStmt, kWasmStmt>, + &WasmGenerator::sequence<kWasmStmt, kWasmStmt, kWasmStmt, kWasmStmt>, + &WasmGenerator::sequence<kWasmStmt, kWasmStmt, kWasmStmt, kWasmStmt, + kWasmStmt, kWasmStmt, kWasmStmt, kWasmStmt>, &WasmGenerator::block<kWasmStmt>, &WasmGenerator::loop<kWasmStmt>, &WasmGenerator::if_<kWasmStmt, kIf>, @@ -508,7 +513,9 @@ void WasmGenerator::Generate<kWasmI32>(DataRange& data) { } constexpr generate_fn alternates[] = { + &WasmGenerator::sequence<kWasmI32, kWasmStmt>, &WasmGenerator::sequence<kWasmStmt, kWasmI32>, + &WasmGenerator::sequence<kWasmStmt, kWasmI32, kWasmStmt>, &WasmGenerator::op<kExprI32Eqz, kWasmI32>, &WasmGenerator::op<kExprI32Eq, kWasmI32, kWasmI32>, @@ -597,7 +604,9 @@ void WasmGenerator::Generate<kWasmI64>(DataRange& data) { } constexpr generate_fn alternates[] = { + &WasmGenerator::sequence<kWasmI64, kWasmStmt>, &WasmGenerator::sequence<kWasmStmt, kWasmI64>, + &WasmGenerator::sequence<kWasmStmt, kWasmI64, kWasmStmt>, &WasmGenerator::op<kExprI64Add, kWasmI64, kWasmI64>, &WasmGenerator::op<kExprI64Sub, kWasmI64, kWasmI64>, @@ -652,7 +661,9 @@ void WasmGenerator::Generate<kWasmF32>(DataRange& data) { } constexpr generate_fn alternates[] = { + &WasmGenerator::sequence<kWasmF32, kWasmStmt>, &WasmGenerator::sequence<kWasmStmt, kWasmF32>, + &WasmGenerator::sequence<kWasmStmt, kWasmF32, kWasmStmt>, &WasmGenerator::op<kExprF32Add, kWasmF32, kWasmF32>, &WasmGenerator::op<kExprF32Sub, kWasmF32, kWasmF32>, @@ -683,7 +694,9 @@ void WasmGenerator::Generate<kWasmF64>(DataRange& data) { } constexpr generate_fn alternates[] = { + &WasmGenerator::sequence<kWasmF64, kWasmStmt>, &WasmGenerator::sequence<kWasmStmt, kWasmF64>, + &WasmGenerator::sequence<kWasmStmt, kWasmF64, kWasmStmt>, &WasmGenerator::op<kExprF64Add, kWasmF64, kWasmF64>, &WasmGenerator::op<kExprF64Sub, kWasmF64, kWasmF64>, diff --git a/deps/v8/test/fuzzer/wasm-fuzzer-common.cc b/deps/v8/test/fuzzer/wasm-fuzzer-common.cc index f84e700fc9..c253da9cb5 100644 --- a/deps/v8/test/fuzzer/wasm-fuzzer-common.cc +++ b/deps/v8/test/fuzzer/wasm-fuzzer-common.cc @@ -10,7 +10,7 @@ #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" -#include "src/wasm/wasm-objects.h" +#include "src/wasm/wasm-objects-inl.h" #include "src/zone/accounting-allocator.h" #include "src/zone/zone.h" #include "test/common/wasm/flag-utils.h" @@ -153,9 +153,10 @@ std::ostream& operator<<(std::ostream& os, const PrintName& name) { void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, bool compiles) { constexpr bool kVerifyFunctions = false; - ModuleResult module_res = - SyncDecodeWasmModule(isolate, wire_bytes.start(), wire_bytes.end(), - kVerifyFunctions, ModuleOrigin::kWasmOrigin); + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(isolate); + ModuleResult module_res = DecodeWasmModule( + enabled_features, wire_bytes.start(), wire_bytes.end(), kVerifyFunctions, + ModuleOrigin::kWasmOrigin, isolate->counters(), isolate->allocator()); CHECK(module_res.ok()); WasmModule* module = module_res.val.get(); CHECK_NOT_NULL(module); @@ -181,7 +182,7 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, os << ", undefined"; } os << ", " << (module->mem_export ? "true" : "false"); - if (FLAG_experimental_wasm_threads && module->has_shared_memory) { + if (module->has_shared_memory) { os << ", shared"; } os << ");\n"; @@ -208,7 +209,8 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, // Add locals. BodyLocalDecls decls(&tmp_zone); - DecodeLocalDecls(&decls, func_code.start(), func_code.end()); + DecodeLocalDecls(enabled_features, &decls, func_code.start(), + func_code.end()); if (!decls.type_list.empty()) { os << " "; for (size_t pos = 0, count = 1, locals = decls.type_list.size(); @@ -284,6 +286,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, ModuleWireBytes wire_bytes(buffer.begin(), buffer.end()); // Compile with Turbofan here. Liftoff will be tested later. + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); MaybeHandle<WasmModuleObject> compiled_module; { // Explicitly enable Liftoff, disable tiering and set the tier_mask. This @@ -292,7 +295,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, FlagScope<bool> no_tier_up(&FLAG_wasm_tier_up, false); FlagScope<int> tier_mask_scope(&FLAG_wasm_tier_mask_for_testing, tier_mask); compiled_module = i_isolate->wasm_engine()->SyncCompile( - i_isolate, &interpreter_thrower, wire_bytes); + i_isolate, enabled_features, &interpreter_thrower, wire_bytes); } bool compiles = !compiled_module.is_null(); @@ -300,8 +303,8 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, GenerateTestCase(i_isolate, wire_bytes, compiles); } - bool validates = - i_isolate->wasm_engine()->SyncValidate(i_isolate, wire_bytes); + bool validates = i_isolate->wasm_engine()->SyncValidate( + i_isolate, enabled_features, wire_bytes); CHECK_EQ(compiles, validates); CHECK_IMPLIES(require_valid, validates); @@ -332,6 +335,16 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, return 0; } + // The WebAssembly spec allows the sign bit of NaN to be non-deterministic. + // This sign bit can make the difference between an infinite loop and + // terminating code. With possible non-determinism we cannot guarantee that + // the generated code will not go into an infinite loop and cause a timeout in + // Clusterfuzz. Therefore we do not execute the generated code if the result + // may be non-deterministic. + if (possible_nondeterminism) { + return 0; + } + bool expect_exception = result_interpreter == static_cast<int32_t>(0xDEADBEEF); @@ -349,20 +362,14 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, "main", num_args, compiler_args.get()); } - // The WebAssembly spec allows the sign bit of NaN to be non-deterministic. - // This sign bit may cause result_interpreter to be different than - // result_compiled. Therefore we do not check the equality of the results - // if the execution may have produced a NaN at some point. - if (!possible_nondeterminism) { - if (expect_exception != i_isolate->has_pending_exception()) { - const char* exception_text[] = {"no exception", "exception"}; - FATAL("interpreter: %s; compiled: %s", exception_text[expect_exception], - exception_text[i_isolate->has_pending_exception()]); - } - - if (!expect_exception) CHECK_EQ(result_interpreter, result_compiled); + if (expect_exception != i_isolate->has_pending_exception()) { + const char* exception_text[] = {"no exception", "exception"}; + FATAL("interpreter: %s; compiled: %s", exception_text[expect_exception], + exception_text[i_isolate->has_pending_exception()]); } + if (!expect_exception) CHECK_EQ(result_interpreter, result_compiled); + // Cleanup any pending exception. i_isolate->clear_pending_exception(); return 0; diff --git a/deps/v8/test/fuzzer/wasm.cc b/deps/v8/test/fuzzer/wasm.cc index 75a6dd9865..fb9135b0f1 100644 --- a/deps/v8/test/fuzzer/wasm.cc +++ b/deps/v8/test/fuzzer/wasm.cc @@ -42,9 +42,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { i::HandleScope scope(i_isolate); i::wasm::ErrorThrower thrower(i_isolate, "wasm fuzzer"); i::Handle<i::WasmModuleObject> module_object; - bool compiles = i_isolate->wasm_engine() - ->SyncCompile(i_isolate, &thrower, wire_bytes) - .ToHandle(&module_object); + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); + bool compiles = + i_isolate->wasm_engine() + ->SyncCompile(i_isolate, enabled_features, &thrower, wire_bytes) + .ToHandle(&module_object); if (i::FLAG_wasm_fuzzer_gen_test) { i::wasm::fuzzer::GenerateTestCase(i_isolate, wire_bytes, compiles); |