Add '-tint_dump_input=true/false' to fuzzers to dump input spv/wgsl to a file

When enabled, the input spv/wgsl is dumped to a file named
"fuzzer_input_<hash of file>.spv/wgsl".

Note that this adds the setting to all the fuzzers in the root of
fuzzers/, but not to tint_ast_fuzzer, tint_regex_fuzzer, nor
tint_spirv_tools_fuzzer as they currently to their own CLI parsing.

Change-Id: I268ffd842b94be1cbb78eb199d5662712ff71053
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/61000
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Antonio Maiorano 2021-08-05 15:52:58 +00:00 committed by Tint LUCI CQ
parent 4038fa7f43
commit 15e89fa7b7
26 changed files with 311 additions and 20 deletions

View File

@ -99,10 +99,20 @@ if (build_with_chromium) {
] ]
} }
source_set("tint_fuzzer_common_with_init") {
public_deps = [ ":tint_fuzzer_common" ]
sources = [
"cli.cc",
"cli.h",
"tint_init_fuzzer.cc",
"tint_init_fuzzer.h",
]
}
if (tint_build_wgsl_reader) { if (tint_build_wgsl_reader) {
fuzzer_test("tint_wgsl_reader_fuzzer") { fuzzer_test("tint_wgsl_reader_fuzzer") {
sources = [ "tint_wgsl_reader_fuzzer.cc" ] sources = [ "tint_wgsl_reader_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -130,7 +140,7 @@ if (build_with_chromium) {
fuzzer_test("tint_wgsl_reader_wgsl_writer_fuzzer") { fuzzer_test("tint_wgsl_reader_wgsl_writer_fuzzer") {
sources = [ "tint_wgsl_reader_wgsl_writer_fuzzer.cc" ] sources = [ "tint_wgsl_reader_wgsl_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -140,7 +150,7 @@ if (build_with_chromium) {
if (tint_build_wgsl_reader && tint_build_spv_writer) { if (tint_build_wgsl_reader && tint_build_spv_writer) {
fuzzer_test("tint_all_transforms_fuzzer") { fuzzer_test("tint_all_transforms_fuzzer") {
sources = [ "tint_all_transforms_fuzzer.cc" ] sources = [ "tint_all_transforms_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -157,7 +167,7 @@ if (build_with_chromium) {
fuzzer_test("tint_binding_remapper_fuzzer") { fuzzer_test("tint_binding_remapper_fuzzer") {
sources = [ "tint_binding_remapper_fuzzer.cc" ] sources = [ "tint_binding_remapper_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -165,7 +175,7 @@ if (build_with_chromium) {
fuzzer_test("tint_first_index_offset_fuzzer") { fuzzer_test("tint_first_index_offset_fuzzer") {
sources = [ "tint_first_index_offset_fuzzer.cc" ] sources = [ "tint_first_index_offset_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -173,7 +183,7 @@ if (build_with_chromium) {
fuzzer_test("tint_inspector_fuzzer") { fuzzer_test("tint_inspector_fuzzer") {
sources = [ "tint_inspector_fuzzer.cc" ] sources = [ "tint_inspector_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -190,7 +200,7 @@ if (build_with_chromium) {
fuzzer_test("tint_renamer_fuzzer") { fuzzer_test("tint_renamer_fuzzer") {
sources = [ "tint_renamer_fuzzer.cc" ] sources = [ "tint_renamer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -198,7 +208,7 @@ if (build_with_chromium) {
fuzzer_test("tint_robustness_fuzzer") { fuzzer_test("tint_robustness_fuzzer") {
sources = [ "tint_robustness_fuzzer.cc" ] sources = [ "tint_robustness_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -206,7 +216,7 @@ if (build_with_chromium) {
fuzzer_test("tint_single_entry_point_fuzzer") { fuzzer_test("tint_single_entry_point_fuzzer") {
sources = [ "tint_single_entry_point_fuzzer.cc" ] sources = [ "tint_single_entry_point_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -214,7 +224,7 @@ if (build_with_chromium) {
fuzzer_test("tint_vertex_pulling_fuzzer") { fuzzer_test("tint_vertex_pulling_fuzzer") {
sources = [ "tint_vertex_pulling_fuzzer.cc" ] sources = [ "tint_vertex_pulling_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -222,7 +232,7 @@ if (build_with_chromium) {
fuzzer_test("tint_wgsl_reader_spv_writer_fuzzer") { fuzzer_test("tint_wgsl_reader_spv_writer_fuzzer") {
sources = [ "tint_wgsl_reader_spv_writer_fuzzer.cc" ] sources = [ "tint_wgsl_reader_spv_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -250,7 +260,7 @@ if (build_with_chromium) {
fuzzer_test("tint_wgsl_reader_hlsl_writer_fuzzer") { fuzzer_test("tint_wgsl_reader_hlsl_writer_fuzzer") {
sources = [ "tint_wgsl_reader_hlsl_writer_fuzzer.cc" ] sources = [ "tint_wgsl_reader_hlsl_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -278,7 +288,7 @@ if (build_with_chromium) {
fuzzer_test("tint_wgsl_reader_msl_writer_fuzzer") { fuzzer_test("tint_wgsl_reader_msl_writer_fuzzer") {
sources = [ "tint_wgsl_reader_msl_writer_fuzzer.cc" ] sources = [ "tint_wgsl_reader_msl_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
@ -288,7 +298,7 @@ if (build_with_chromium) {
if (tint_build_spv_reader) { if (tint_build_spv_reader) {
fuzzer_test("tint_spv_reader_fuzzer") { fuzzer_test("tint_spv_reader_fuzzer") {
sources = [ "tint_spv_reader_fuzzer.cc" ] sources = [ "tint_spv_reader_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
seed_corpus = fuzzer_corpus_spirv_dir seed_corpus = fuzzer_corpus_spirv_dir
seed_corpus_deps = [ ":tint_generate_spirv_corpus" ] seed_corpus_deps = [ ":tint_generate_spirv_corpus" ]
} }
@ -297,7 +307,7 @@ if (build_with_chromium) {
if (tint_build_spv_reader && tint_build_wgsl_writer) { if (tint_build_spv_reader && tint_build_wgsl_writer) {
fuzzer_test("tint_spv_reader_wgsl_writer_fuzzer") { fuzzer_test("tint_spv_reader_wgsl_writer_fuzzer") {
sources = [ "tint_spv_reader_wgsl_writer_fuzzer.cc" ] sources = [ "tint_spv_reader_wgsl_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
seed_corpus = fuzzer_corpus_spirv_dir seed_corpus = fuzzer_corpus_spirv_dir
seed_corpus_deps = [ ":tint_generate_spirv_corpus" ] seed_corpus_deps = [ ":tint_generate_spirv_corpus" ]
} }
@ -314,7 +324,7 @@ if (build_with_chromium) {
if (tint_build_spv_reader && tint_build_spv_writer) { if (tint_build_spv_reader && tint_build_spv_writer) {
fuzzer_test("tint_spv_reader_spv_writer_fuzzer") { fuzzer_test("tint_spv_reader_spv_writer_fuzzer") {
sources = [ "tint_spv_reader_spv_writer_fuzzer.cc" ] sources = [ "tint_spv_reader_spv_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
seed_corpus = fuzzer_corpus_spirv_dir seed_corpus = fuzzer_corpus_spirv_dir
seed_corpus_deps = [ ":tint_generate_spirv_corpus" ] seed_corpus_deps = [ ":tint_generate_spirv_corpus" ]
} }
@ -331,7 +341,7 @@ if (build_with_chromium) {
if (tint_build_spv_reader && tint_build_hlsl_writer) { if (tint_build_spv_reader && tint_build_hlsl_writer) {
fuzzer_test("tint_spv_reader_hlsl_writer_fuzzer") { fuzzer_test("tint_spv_reader_hlsl_writer_fuzzer") {
sources = [ "tint_spv_reader_hlsl_writer_fuzzer.cc" ] sources = [ "tint_spv_reader_hlsl_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
seed_corpus = fuzzer_corpus_spirv_dir seed_corpus = fuzzer_corpus_spirv_dir
seed_corpus_deps = [ ":tint_generate_spirv_corpus" ] seed_corpus_deps = [ ":tint_generate_spirv_corpus" ]
} }
@ -348,7 +358,7 @@ if (build_with_chromium) {
if (tint_build_spv_reader && tint_build_msl_writer) { if (tint_build_spv_reader && tint_build_msl_writer) {
fuzzer_test("tint_spv_reader_msl_writer_fuzzer") { fuzzer_test("tint_spv_reader_msl_writer_fuzzer") {
sources = [ "tint_spv_reader_msl_writer_fuzzer.cc" ] sources = [ "tint_spv_reader_msl_writer_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
seed_corpus = fuzzer_corpus_spirv_dir seed_corpus = fuzzer_corpus_spirv_dir
seed_corpus_deps = [ ":tint_generate_spirv_corpus" ] seed_corpus_deps = [ ":tint_generate_spirv_corpus" ]
} }
@ -365,7 +375,7 @@ if (build_with_chromium) {
if (tint_build_wgsl_reader && tint_build_wgsl_writer) { if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
fuzzer_test("tint_ast_clone_fuzzer") { fuzzer_test("tint_ast_clone_fuzzer") {
sources = [ "tint_ast_clone_fuzzer.cc" ] sources = [ "tint_ast_clone_fuzzer.cc" ]
deps = [ ":tint_fuzzer_common" ] deps = [ ":tint_fuzzer_common_with_init" ]
dict = "dictionary.txt" dict = "dictionary.txt"
seed_corpus = fuzzer_corpus_wgsl_dir seed_corpus = fuzzer_corpus_wgsl_dir
seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ] seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]

View File

@ -15,7 +15,13 @@
function(add_tint_fuzzer NAME) function(add_tint_fuzzer NAME)
add_executable(${NAME} add_executable(${NAME}
${NAME}.cc ${NAME}.cc
tint_common_fuzzer.cc) cli.cc
cli.h
tint_common_fuzzer.cc
tint_common_fuzzer.h
tint_init_fuzzer.cc
tint_init_fuzzer.h
)
target_link_libraries(${NAME} libtint-fuzz) target_link_libraries(${NAME} libtint-fuzz)
tint_default_compile_options(${NAME}) tint_default_compile_options(${NAME})
target_compile_options(${NAME} PRIVATE -Wno-missing-prototypes) target_compile_options(${NAME} PRIVATE -Wno-missing-prototypes)

107
fuzzers/cli.cc Normal file
View File

@ -0,0 +1,107 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fuzzers/cli.h"
#include <cstring>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <utility>
namespace tint {
namespace fuzzers {
namespace {
const char* const kHelpMessage = R"(
This is a fuzzer for the Tint compiler that works by mutating the AST.
Below is a list of all supported parameters for this fuzzer. You may want to
run it with -help=1 to check out libfuzzer parameters.
-tint_dump_input=
If `true`, the fuzzer will dump input data to a file with
name tint_input_<hash>.spv/wgsl, where the hash is the hash
of the input data.
-tint_help
Show this message. Note that there is also a -help=1
parameter that will display libfuzzer's help message.
)";
bool HasPrefix(const char* str, const char* prefix) {
return strncmp(str, prefix, strlen(prefix)) == 0;
}
[[noreturn]] void InvalidParam(const char* param) {
std::cout << "Invalid value for " << param << std::endl;
std::cout << kHelpMessage << std::endl;
exit(1);
}
bool ParseBool(const char* value, bool* out) {
if (!strcmp(value, "true")) {
*out = true;
} else if (!strcmp(value, "false")) {
*out = false;
} else {
return false;
}
return true;
}
} // namespace
CliParams ParseCliParams(int* argc, char** argv) {
CliParams cli_params;
auto help = false;
for (int i = *argc - 1; i > 0; --i) {
auto param = argv[i];
auto recognized_parameter = true;
if (HasPrefix(param, "-tint_dump_input=")) {
if (!ParseBool(param + sizeof("-tint_dump_input=") - 1,
&cli_params.dump_input)) {
InvalidParam(param);
}
} else if (!strcmp(param, "-tint_help")) {
help = true;
} else {
recognized_parameter = false;
}
if (recognized_parameter) {
// Remove the recognized parameter from the list of all parameters by
// swapping it with the last one. This will suppress warnings in the
// libFuzzer about unrecognized parameters. By default, libFuzzer thinks
// that all user-defined parameters start with two dashes. However, we are
// forced to use a single one to make the fuzzer compatible with the
// ClusterFuzz.
std::swap(argv[i], argv[*argc - 1]);
*argc -= 1;
}
}
if (help) {
std::cout << kHelpMessage << std::endl;
exit(0);
}
return cli_params;
}
} // namespace fuzzers
} // namespace tint

43
fuzzers/cli.h Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FUZZERS_CLI_H_
#define FUZZERS_CLI_H_
#include <cstdint>
namespace tint {
namespace fuzzers {
/// CLI parameters accepted by the fuzzer. Type -tint_help in the CLI to see the
/// help message
struct CliParams {
bool dump_input = false;
};
/// @brief Parses CLI parameters.
///
/// This function will exit the process with non-zero return code if some
/// parameters are invalid. This function will remove recognized parameters from
/// `argv` and adjust `argc` accordingly.
///
/// @param argc - the total number of parameters.
/// @param argv - array of all CLI parameters.
/// @return parsed parameters.
CliParams ParseCliParams(int* argc, char** argv);
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_CLI_H_

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -50,6 +51,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&(config.manager), std::move(config.inputs)); fuzzer.SetTransformManager(&(config.manager), std::move(config.inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.Run(config.reader.data(), config.reader.size()); fuzzer.Run(config.reader.data(), config.reader.size());
} }
@ -64,6 +66,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL); fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL);
fuzzer.SetTransformManager(&config.manager, std::move(config.inputs)); fuzzer.SetTransformManager(&config.manager, std::move(config.inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.Run(config.reader.data(), config.reader.size()); fuzzer.Run(config.reader.data(), config.reader.size());
} }
@ -79,6 +82,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL); fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL);
fuzzer.SetTransformManager(&config.manager, std::move(config.inputs)); fuzzer.SetTransformManager(&config.manager, std::move(config.inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.Run(config.reader.data(), config.reader.size()); fuzzer.Run(config.reader.data(), config.reader.size());
} }
@ -93,6 +97,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&config.manager, std::move(config.inputs)); fuzzer.SetTransformManager(&config.manager, std::move(config.inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.Run(config.reader.data(), config.reader.size()); fuzzer.Run(config.reader.data(), config.reader.size());
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -31,6 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs)); fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(r.data(), r.size()); return fuzzer.Run(r.data(), r.size());
} }

View File

@ -15,6 +15,7 @@
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include <cstring> #include <cstring>
#include <fstream>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -28,6 +29,7 @@
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/diagnostic/formatter.h" #include "src/diagnostic/formatter.h"
#include "src/program.h" #include "src/program.h"
#include "src/utils/hash.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -202,6 +204,17 @@ int CommonFuzzer::Run(const uint8_t* data, size_t size) {
#endif // TINT_BUILD_SPV_READER #endif // TINT_BUILD_SPV_READER
#if TINT_BUILD_WGSL_READER || TINT_BUILD_SPV_READER
auto dump_input_data = [&](auto& content, const char* extension) {
size_t hash = utils::Hash(content);
auto filename = "fuzzer_input_" + std::to_string(hash) + extension; //
std::ofstream fout(filename, std::ios::binary);
fout.write(reinterpret_cast<const char*>(data),
static_cast<std::streamsize>(size));
std::cout << "Dumped input data to " << filename << std::endl;
};
#endif
switch (input_) { switch (input_) {
#if TINT_BUILD_WGSL_READER #if TINT_BUILD_WGSL_READER
case InputFormat::kWGSL: { case InputFormat::kWGSL: {
@ -210,6 +223,9 @@ int CommonFuzzer::Run(const uint8_t* data, size_t size) {
diagnostics_ = {}; diagnostics_ = {};
std::string str(reinterpret_cast<const char*>(data), size); std::string str(reinterpret_cast<const char*>(data), size);
file_ = std::make_unique<Source::File>("test.wgsl", str); file_ = std::make_unique<Source::File>("test.wgsl", str);
if (dump_input_) {
dump_input_data(str, ".wgsl");
}
program = reader::wgsl::Parse(file_.get()); program = reader::wgsl::Parse(file_.get());
break; break;
} }
@ -225,6 +241,9 @@ int CommonFuzzer::Run(const uint8_t* data, size_t size) {
if (spirv_input.empty()) { if (spirv_input.empty()) {
return 0; return 0;
} }
if (dump_input_) {
dump_input_data(spirv_input, ".spv");
}
program = reader::spirv::Parse(spirv_input); program = reader::spirv::Parse(spirv_input);
break; break;
} }

View File

@ -121,6 +121,8 @@ class CommonFuzzer {
} }
void EnableInspector() { inspector_enabled_ = true; } void EnableInspector() { inspector_enabled_ = true; }
void SetDumpInput(bool enabled) { dump_input_ = enabled; }
int Run(const uint8_t* data, size_t size); int Run(const uint8_t* data, size_t size);
const tint::diag::List& Diagnostics() const { return diagnostics_; } const tint::diag::List& Diagnostics() const { return diagnostics_; }
@ -159,6 +161,7 @@ class CommonFuzzer {
transform::Manager* transform_manager_; transform::Manager* transform_manager_;
transform::DataMap transform_inputs_; transform::DataMap transform_inputs_;
bool inspector_enabled_; bool inspector_enabled_;
bool dump_input_ = false;
tint::diag::List diagnostics_; tint::diag::List diagnostics_;
std::vector<uint32_t> generated_spirv_; std::vector<uint32_t> generated_spirv_;

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -31,6 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs)); fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(r.data(), r.size()); return fuzzer.Run(r.data(), r.size());
} }

View File

@ -0,0 +1,35 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fuzzers/tint_init_fuzzer.h"
#include "fuzzers/cli.h"
namespace tint {
namespace fuzzers {
namespace {
CliParams cli_params;
}
const CliParams& GetCliParams() {
return cli_params;
}
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
cli_params = ParseCliParams(argc, *argv);
return 0;
}
} // namespace fuzzers
} // namespace tint

View File

@ -0,0 +1,29 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FUZZERS_TINT_INIT_FUZZER_H_
#define FUZZERS_TINT_INIT_FUZZER_H_
#include "fuzzers/cli.h"
namespace tint {
namespace fuzzers {
/// Returns the common CliParams parsed and populated by LLVMFuzzerInitialize()
const CliParams& GetCliParams();
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_INIT_FUZZER_H_

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -20,6 +21,7 @@ namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.EnableInspector(); fuzzer.EnableInspector();
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -23,6 +24,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&transform_manager, {}); fuzzer.SetTransformManager(&transform_manager, {});
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -23,6 +24,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&transform_manager, {}); fuzzer.SetTransformManager(&transform_manager, {});
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -31,6 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs)); fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(r.data(), r.size()); return fuzzer.Run(r.data(), r.size());
} }

View File

@ -15,12 +15,14 @@
#include <vector> #include <vector>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kNone); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kNone);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -15,12 +15,14 @@
#include <vector> #include <vector>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kHLSL); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kHLSL);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -25,6 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
ExtractMslOptions(&reader, &options); ExtractMslOptions(&reader, &options);
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kMSL); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kMSL);
fuzzer.SetOptionsMsl(options); fuzzer.SetOptionsMsl(options);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(reader.data(), reader.size()); return fuzzer.Run(reader.data(), reader.size());
} }

View File

@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -25,6 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
ExtractSpirvOptions(&reader, &options); ExtractSpirvOptions(&reader, &options);
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kSpv);
fuzzer.SetOptionsSpirv(options); fuzzer.SetOptionsSpirv(options);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(reader.data(), reader.size()); return fuzzer.Run(reader.data(), reader.size());
} }

View File

@ -15,12 +15,14 @@
#include <vector> #include <vector>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kWGSL); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kSpv, OutputFormat::kWGSL);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -31,6 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(&transform_manager, {}); fuzzer.SetTransformManager(&transform_manager, {});
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(r.data(), r.size()); return fuzzer.Run(r.data(), r.size());
} }

View File

@ -15,12 +15,14 @@
#include <string> #include <string>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kNone); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kNone);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -15,12 +15,14 @@
#include <string> #include <string>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }

View File

@ -15,6 +15,7 @@
#include <string> #include <string>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -25,6 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
ExtractMslOptions(&reader, &options); ExtractMslOptions(&reader, &options);
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL);
fuzzer.SetOptionsMsl(options); fuzzer.SetOptionsMsl(options);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(reader.data(), reader.size()); return fuzzer.Run(reader.data(), reader.size());
} }

View File

@ -15,6 +15,7 @@
#include <string> #include <string>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
@ -25,6 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
ExtractSpirvOptions(&reader, &options); ExtractSpirvOptions(&reader, &options);
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetOptionsSpirv(options); fuzzer.SetOptionsSpirv(options);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(reader.data(), reader.size()); return fuzzer.Run(reader.data(), reader.size());
} }

View File

@ -15,12 +15,14 @@
#include <string> #include <string>
#include "fuzzers/tint_common_fuzzer.h" #include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_init_fuzzer.h"
namespace tint { namespace tint {
namespace fuzzers { namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL); tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
fuzzer.SetDumpInput(GetCliParams().dump_input);
return fuzzer.Run(data, size); return fuzzer.Run(data, size);
} }