diff options
Diffstat (limited to 'deps/v8/test/fuzzer/wasm-fuzzer-common.cc')
-rw-r--r-- | deps/v8/test/fuzzer/wasm-fuzzer-common.cc | 159 |
1 files changed, 76 insertions, 83 deletions
diff --git a/deps/v8/test/fuzzer/wasm-fuzzer-common.cc b/deps/v8/test/fuzzer/wasm-fuzzer-common.cc index c253da9cb5..48c94be426 100644 --- a/deps/v8/test/fuzzer/wasm-fuzzer-common.cc +++ b/deps/v8/test/fuzzer/wasm-fuzzer-common.cc @@ -4,9 +4,12 @@ #include "test/fuzzer/wasm-fuzzer-common.h" +#include <ctime> + #include "include/v8.h" #include "src/isolate.h" #include "src/objects-inl.h" +#include "src/ostreams.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" @@ -22,49 +25,6 @@ namespace internal { namespace wasm { namespace fuzzer { -static constexpr const char* kNameString = "name"; -static constexpr size_t kNameStringLength = 4; - -int FuzzWasmSection(SectionCode section, const uint8_t* data, size_t size) { - v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get(); - v8::Isolate* isolate = support->GetIsolate(); - i::Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); - - // Clear any pending exceptions from a prior run. - i_isolate->clear_pending_exception(); - - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(support->GetContext()); - v8::TryCatch try_catch(isolate); - - AccountingAllocator allocator; - Zone zone(&allocator, ZONE_NAME); - - ZoneBuffer buffer(&zone); - buffer.write_u32(kWasmMagic); - buffer.write_u32(kWasmVersion); - if (section == kNameSectionCode) { - buffer.write_u8(kUnknownSectionCode); - buffer.write_size(size + kNameStringLength + 1); - buffer.write_u8(kNameStringLength); - buffer.write(reinterpret_cast<const uint8_t*>(kNameString), - kNameStringLength); - buffer.write(data, size); - } else { - buffer.write_u8(section); - buffer.write_size(size); - buffer.write(data, size); - } - - ErrorThrower thrower(i_isolate, "decoder"); - - testing::DecodeWasmModuleForTesting(i_isolate, &thrower, buffer.begin(), - buffer.end(), kWasmOrigin); - - return 0; -} - void InterpretAndExecuteModule(i::Isolate* isolate, Handle<WasmModuleObject> module_object) { // We do not instantiate the module if there is a start function, because a @@ -158,12 +118,23 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, 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(); + WasmModule* module = module_res.value().get(); CHECK_NOT_NULL(module); StdoutStream os; - os << "// Copyright 2018 the V8 project authors. All rights reserved.\n" + tzset(); + time_t current_time = time(nullptr); + struct tm current_localtime; +#ifdef V8_OS_WIN + localtime_s(¤t_localtime, ¤t_time); +#else + localtime_r(¤t_time, ¤t_localtime); +#endif + int year = 1900 + current_localtime.tm_year; + + os << "// Copyright " << year + << " the V8 project authors. All rights reserved.\n" "// Use of this source code is governed by a BSD-style license that " "can be\n" "// found in the LICENSE file.\n" @@ -183,7 +154,7 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, } os << ", " << (module->mem_export ? "true" : "false"); if (module->has_shared_memory) { - os << ", shared"; + os << ", true"; } os << ");\n"; } @@ -193,19 +164,46 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, << glob.mutability << ");\n"; } + for (const FunctionSig* sig : module->signatures) { + os << " builder.addType(makeSig(" << PrintParameters(sig) << ", " + << PrintReturns(sig) << "));\n"; + } + Zone tmp_zone(isolate->allocator(), ZONE_NAME); + // There currently cannot be more than one table. + DCHECK_GE(1, module->tables.size()); + for (const WasmTable& table : module->tables) { + os << " builder.setTableBounds(" << table.initial_size << ", "; + if (table.has_maximum_size) { + os << table.maximum_size << ");\n"; + } else { + os << "undefined);\n"; + } + } + for (const WasmElemSegment& elem_segment : module->elem_segments) { + os << " builder.addElementSegment("; + switch (elem_segment.offset.kind) { + case WasmInitExpr::kGlobalIndex: + os << elem_segment.offset.val.global_index << ", true"; + break; + case WasmInitExpr::kI32Const: + os << elem_segment.offset.val.i32_const << ", false"; + break; + default: + UNREACHABLE(); + } + os << ", " << PrintCollection(elem_segment.entries) << ");\n"; + } + for (const WasmFunction& func : module->functions) { Vector<const uint8_t> func_code = wire_bytes.GetFunctionBytes(&func); os << " // Generate function " << (func.func_index + 1) << " (out of " << module->functions.size() << ").\n"; - // Generate signature. - os << " sig" << (func.func_index + 1) << " = makeSig(" - << PrintParameters(func.sig) << ", " << PrintReturns(func.sig) << ");\n"; // Add function. - os << " builder.addFunction(undefined, sig" << (func.func_index + 1) - << ")\n"; + os << " builder.addFunction(undefined, " << func.sig_index + << " /* sig */)\n"; // Add locals. BodyLocalDecls decls(&tmp_zone); @@ -249,8 +247,13 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes, os << "})();\n"; } -int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, - bool require_valid) { +void WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, + bool require_valid) { + // Strictly enforce the input size limit. Note that setting "max_len" on the + // fuzzer target is not enough, since different fuzzers are used and not all + // respect that limit. + if (data.size() > max_input_size()) return; + v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get(); v8::Isolate* isolate = support->GetIsolate(); i::Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); @@ -277,7 +280,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, if (!data.is_empty()) data += 1; if (!GenerateModule(i_isolate, &zone, data, buffer, num_args, interpreter_args, compiler_args)) { - return 0; + return; } testing::SetupIsolateForWasmModule(i_isolate); @@ -309,31 +312,24 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, CHECK_EQ(compiles, validates); CHECK_IMPLIES(require_valid, validates); - if (!compiles) return 0; + if (!compiles) return; - int32_t result_interpreter; - bool possible_nondeterminism = false; - { - MaybeHandle<WasmInstanceObject> interpreter_instance = - i_isolate->wasm_engine()->SyncInstantiate( - i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(), - MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>()); + MaybeHandle<WasmInstanceObject> interpreter_instance = + i_isolate->wasm_engine()->SyncInstantiate( + i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(), + MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>()); - // Ignore instantiation failure. - if (interpreter_thrower.error()) { - return 0; - } + // Ignore instantiation failure. + if (interpreter_thrower.error()) return; - result_interpreter = testing::InterpretWasmModule( - i_isolate, interpreter_instance.ToHandleChecked(), &interpreter_thrower, - 0, interpreter_args.get(), &possible_nondeterminism); - } + testing::WasmInterpretationResult interpreter_result = + testing::InterpretWasmModule(i_isolate, + interpreter_instance.ToHandleChecked(), 0, + interpreter_args.get()); // Do not execute the generated code if the interpreter did not finished after // a bounded number of steps. - if (interpreter_thrower.error()) { - return 0; - } + if (interpreter_result.stopped()) return; // 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 @@ -341,12 +337,7 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, // 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); + if (interpreter_result.possible_nondeterminism()) return; int32_t result_compiled; { @@ -362,17 +353,19 @@ int WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data, "main", num_args, compiler_args.get()); } - if (expect_exception != i_isolate->has_pending_exception()) { + if (interpreter_result.trapped() != i_isolate->has_pending_exception()) { const char* exception_text[] = {"no exception", "exception"}; - FATAL("interpreter: %s; compiled: %s", exception_text[expect_exception], + FATAL("interpreter: %s; compiled: %s", + exception_text[interpreter_result.trapped()], exception_text[i_isolate->has_pending_exception()]); } - if (!expect_exception) CHECK_EQ(result_interpreter, result_compiled); + if (!interpreter_result.trapped()) { + CHECK_EQ(interpreter_result.result(), result_compiled); + } // Cleanup any pending exception. i_isolate->clear_pending_exception(); - return 0; } } // namespace fuzzer |