Refactor fuzzer transform generation
Also splits out various utility classes from tint_common_fuzzer and uses consistent naming for utility classes. BUG=tint:1106 Change-Id: Ic343741eea799366850c46834865d50885554a84 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/65301 Auto-Submit: Ryan Harrison <rharrison@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
0e193ac03e
commit
c57642cbd5
|
@ -66,10 +66,12 @@ if (build_with_chromium) {
|
||||||
]
|
]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
|
"data_builder.h",
|
||||||
"random_generator.cc",
|
"random_generator.cc",
|
||||||
"random_generator.h",
|
"random_generator.h",
|
||||||
"tint_common_fuzzer.cc",
|
"tint_common_fuzzer.cc",
|
||||||
"tint_common_fuzzer.h",
|
"tint_common_fuzzer.h",
|
||||||
|
"transform_builder.h",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +81,8 @@ if (build_with_chromium) {
|
||||||
sources = [
|
sources = [
|
||||||
"cli.cc",
|
"cli.cc",
|
||||||
"cli.h",
|
"cli.h",
|
||||||
"tint_init_fuzzer.cc",
|
"fuzzer_init.cc",
|
||||||
"tint_init_fuzzer.h",
|
"fuzzer_init.h",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if (tint_build_wgsl_reader) {
|
if (tint_build_wgsl_reader) {
|
||||||
|
|
|
@ -17,12 +17,14 @@ function(add_tint_fuzzer NAME)
|
||||||
${NAME}.cc
|
${NAME}.cc
|
||||||
cli.cc
|
cli.cc
|
||||||
cli.h
|
cli.h
|
||||||
|
data_builder.h
|
||||||
|
fuzzer_init.cc
|
||||||
|
fuzzer_init.h
|
||||||
random_generator.cc
|
random_generator.cc
|
||||||
random_generator.h
|
random_generator.h
|
||||||
tint_common_fuzzer.cc
|
tint_common_fuzzer.cc
|
||||||
tint_common_fuzzer.h
|
tint_common_fuzzer.h
|
||||||
tint_init_fuzzer.cc
|
transform_builder.h
|
||||||
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})
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
// 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_DATA_BUILDER_H_
|
||||||
|
#define FUZZERS_DATA_BUILDER_H_
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
/// Builder for generic pseudo-random data using a data buffer as seed
|
||||||
|
class DataBuilder {
|
||||||
|
public:
|
||||||
|
/// @brief Initialize random number generations
|
||||||
|
/// @param data - pointer to a data buffer to use as a seed
|
||||||
|
/// @param size - size of data buffer
|
||||||
|
explicit DataBuilder(const uint8_t* data, size_t size)
|
||||||
|
: generator_(data, size) {}
|
||||||
|
|
||||||
|
~DataBuilder() {}
|
||||||
|
|
||||||
|
/// Generate pseudo-random data of a specific type
|
||||||
|
/// @tparam T - type of data to produce
|
||||||
|
/// @returns pseudo-random data of type T
|
||||||
|
template <typename T>
|
||||||
|
T build() {
|
||||||
|
return BuildImpl<T>::impl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate pseudo-random data of a specific type in a vector
|
||||||
|
/// @tparam T - data type held vector
|
||||||
|
/// @returns pseudo-random data of type std::vector<T>
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> vector() {
|
||||||
|
auto count = build<uint8_t>();
|
||||||
|
std::vector<T> out(count);
|
||||||
|
for (uint8_t i = 0; i < count; i++) {
|
||||||
|
out[i] = build<T>();
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate complex pseudo-random data of a specific type in a vector
|
||||||
|
/// @tparam T - data type held vector
|
||||||
|
/// @tparam Callback - callback that takes in a DataBuilder* and returns a T
|
||||||
|
/// @param generate - callback for generating each instance of T
|
||||||
|
/// @returns pseudo-random data of type std::vector<T>
|
||||||
|
template <typename T, typename Callback>
|
||||||
|
std::vector<T> vector(Callback generate) {
|
||||||
|
auto count = build<uint8_t>();
|
||||||
|
std::vector<T> out(count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
out[i] = generate(this);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate an pseudo-random entry to a enum class.
|
||||||
|
/// Assumes enum is tightly packed starting at 0.
|
||||||
|
/// @tparam T - type of enum class
|
||||||
|
/// @param count - number of entries in enum class
|
||||||
|
/// @returns a random enum class entry
|
||||||
|
template <typename T>
|
||||||
|
T enum_class(uint32_t count) {
|
||||||
|
return static_cast<T>(generator_.Get4Bytes() % count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RandomGenerator generator_;
|
||||||
|
|
||||||
|
/// Get N bytes of pseudo-random data
|
||||||
|
/// @param out - pointer to location to save data
|
||||||
|
/// @param n - number of bytes to get
|
||||||
|
void build(void* out, size_t n) {
|
||||||
|
assert(out != nullptr && "|out| cannot be nullptr");
|
||||||
|
assert(n > 0 && "|n| must be > 0");
|
||||||
|
|
||||||
|
generator_.GetNBytes(reinterpret_cast<uint8_t*>(out), n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation of ::build<T>()
|
||||||
|
/// @tparam T - type of data to produce
|
||||||
|
template <typename T>
|
||||||
|
struct BuildImpl {
|
||||||
|
/// Generate a pseudo-random variable of type T
|
||||||
|
/// @param b - data builder to use
|
||||||
|
/// @returns a variable of type T filled with pseudo-random data
|
||||||
|
static T impl(DataBuilder* b) {
|
||||||
|
T out{};
|
||||||
|
b->build(&out, sizeof(T));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Specialization for std::string
|
||||||
|
template <>
|
||||||
|
struct BuildImpl<std::string> {
|
||||||
|
/// Generate a pseudo-random string
|
||||||
|
/// @param b - data builder to use
|
||||||
|
/// @returns a string filled with pseudo-random data
|
||||||
|
static std::string impl(DataBuilder* b) {
|
||||||
|
auto count = b->build<uint8_t>();
|
||||||
|
if (count == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> source(count);
|
||||||
|
b->build(source.data(), count);
|
||||||
|
return std::string(source.begin(), source.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Specialization for bool
|
||||||
|
template <>
|
||||||
|
struct BuildImpl<bool> {
|
||||||
|
/// Generate a pseudo-random bool
|
||||||
|
/// @param b - data builder to use
|
||||||
|
/// @returns a boolean with even odds of being true or false
|
||||||
|
static bool impl(DataBuilder* b) { return b->generator_.GetBool(); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // FUZZERS_DATA_BUILDER_H_
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/cli.h"
|
#include "fuzzers/cli.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
|
@ -12,8 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#ifndef FUZZERS_TINT_INIT_FUZZER_H_
|
#ifndef FUZZERS_FUZZER_INIT_H_
|
||||||
#define FUZZERS_TINT_INIT_FUZZER_H_
|
#define FUZZERS_FUZZER_INIT_H_
|
||||||
|
|
||||||
#include "fuzzers/cli.h"
|
#include "fuzzers/cli.h"
|
||||||
|
|
||||||
|
@ -26,4 +26,4 @@ const CliParams& GetCliParams();
|
||||||
} // namespace fuzzers
|
} // namespace fuzzers
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // FUZZERS_TINT_INIT_FUZZER_H_
|
#endif // FUZZERS_FUZZER_INIT_H_
|
|
@ -58,6 +58,9 @@ size_t HashBuffer(const uint8_t* data, const size_t size) {
|
||||||
|
|
||||||
RandomGenerator::RandomGenerator(uint64_t seed) : engine_(seed) {}
|
RandomGenerator::RandomGenerator(uint64_t seed) : engine_(seed) {}
|
||||||
|
|
||||||
|
RandomGenerator::RandomGenerator(const uint8_t* data, size_t size)
|
||||||
|
: engine_(RandomGenerator::CalculateSeed(data, size)) {}
|
||||||
|
|
||||||
uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
|
uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
|
||||||
return RandomUInt(&engine_, lower, upper);
|
return RandomUInt(&engine_, lower, upper);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,12 @@ class RandomGenerator {
|
||||||
/// @brief Initializes the internal engine
|
/// @brief Initializes the internal engine
|
||||||
/// @param seed - seed value passed to engine
|
/// @param seed - seed value passed to engine
|
||||||
explicit RandomGenerator(uint64_t seed);
|
explicit RandomGenerator(uint64_t seed);
|
||||||
|
|
||||||
|
/// @brief Wrapper that invokes CalculateSeed for caller
|
||||||
|
/// @param data - data fuzzer to calculate seed from
|
||||||
|
/// @param size - size of data buffer
|
||||||
|
explicit RandomGenerator(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
~RandomGenerator() {}
|
~RandomGenerator() {}
|
||||||
|
|
||||||
/// Get uint32_t value from uniform distribution.
|
/// Get uint32_t value from uniform distribution.
|
||||||
|
|
|
@ -12,41 +12,21 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/random_generator.h"
|
#include "fuzzers/random_generator.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/transform_builder.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
|
|
||||||
struct Config {
|
|
||||||
Config(const uint8_t* data, size_t size) : builder(data, size) {}
|
|
||||||
DataBuilder builder;
|
|
||||||
transform::Manager manager;
|
|
||||||
transform::DataMap inputs;
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddPlatformIndependentPasses(Config* config) {
|
|
||||||
GenerateFirstIndexOffsetInputs(&config->builder, &config->inputs);
|
|
||||||
GenerateBindingRemapperInputs(&config->builder, &config->inputs);
|
|
||||||
GenerateSingleEntryPointInputs(&config->builder, &config->inputs);
|
|
||||||
GenerateVertexPullingInputs(&config->builder, &config->inputs);
|
|
||||||
|
|
||||||
config->manager.Add<transform::Robustness>();
|
|
||||||
config->manager.Add<transform::FirstIndexOffset>();
|
|
||||||
config->manager.Add<transform::BindingRemapper>();
|
|
||||||
config->manager.Add<transform::Renamer>();
|
|
||||||
config->manager.Add<tint::transform::SingleEntryPoint>();
|
|
||||||
config->manager.Add<tint::transform::VertexPulling>();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
{
|
{
|
||||||
Config config(data, size);
|
TransformBuilder tb(data, size);
|
||||||
AddPlatformIndependentPasses(&config);
|
tb.AddPlatformIndependentPasses();
|
||||||
|
|
||||||
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
|
||||||
fuzzer.SetTransformManager(&(config.manager), std::move(config.inputs));
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
fuzzer.Run(data, size);
|
fuzzer.Run(data, size);
|
||||||
|
@ -54,11 +34,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
|
||||||
#if TINT_BUILD_HLSL_WRITER
|
#if TINT_BUILD_HLSL_WRITER
|
||||||
{
|
{
|
||||||
Config config(data, size);
|
TransformBuilder tb(data, size);
|
||||||
AddPlatformIndependentPasses(&config);
|
tb.AddPlatformIndependentPasses();
|
||||||
|
|
||||||
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL);
|
||||||
fuzzer.SetTransformManager(&config.manager, std::move(config.inputs));
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
fuzzer.Run(data, size);
|
fuzzer.Run(data, size);
|
||||||
|
@ -67,11 +47,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
|
||||||
#if TINT_BUILD_MSL_WRITER
|
#if TINT_BUILD_MSL_WRITER
|
||||||
{
|
{
|
||||||
Config config(data, size);
|
TransformBuilder tb(data, size);
|
||||||
AddPlatformIndependentPasses(&config);
|
tb.AddPlatformIndependentPasses();
|
||||||
|
|
||||||
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL);
|
||||||
fuzzer.SetTransformManager(&config.manager, std::move(config.inputs));
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
fuzzer.Run(data, size);
|
fuzzer.Run(data, size);
|
||||||
|
@ -79,11 +59,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
#endif // TINT_BUILD_MSL_WRITER
|
#endif // TINT_BUILD_MSL_WRITER
|
||||||
#if TINT_BUILD_SPV_WRITER
|
#if TINT_BUILD_SPV_WRITER
|
||||||
{
|
{
|
||||||
Config config(data, size);
|
TransformBuilder tb(data, size);
|
||||||
AddPlatformIndependentPasses(&config);
|
tb.AddPlatformIndependentPasses();
|
||||||
|
|
||||||
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
|
||||||
fuzzer.SetTransformManager(&config.manager, std::move(config.inputs));
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
fuzzer.Run(data, size);
|
fuzzer.Run(data, size);
|
||||||
|
|
|
@ -115,7 +115,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
|
||||||
CommonFuzzer fuzzer(InputFormat::kWGSL, target.output_format);
|
CommonFuzzer fuzzer(InputFormat::kWGSL, target.output_format);
|
||||||
fuzzer.EnableInspector();
|
fuzzer.EnableInspector();
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
fuzzer.SetTransformManager(&transform_manager, &transform_inputs);
|
||||||
|
|
||||||
fuzzer.Run(data, size);
|
fuzzer.Run(data, size);
|
||||||
if (fuzzer.HasErrors()) {
|
if (fuzzer.HasErrors()) {
|
||||||
|
|
|
@ -12,23 +12,19 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/transform_builder.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) {
|
||||||
transform::Manager transform_manager;
|
TransformBuilder tb(data, size);
|
||||||
transform::DataMap transform_inputs;
|
tb.AddTransform<transform::BindingRemapper>();
|
||||||
DataBuilder b(data, size);
|
|
||||||
|
|
||||||
GenerateBindingRemapperInputs(&b, &transform_inputs);
|
|
||||||
|
|
||||||
transform_manager.Add<tint::transform::BindingRemapper>();
|
|
||||||
|
|
||||||
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
return fuzzer.Run(data, size);
|
return fuzzer.Run(data, size);
|
||||||
|
|
|
@ -52,26 +52,6 @@ namespace {
|
||||||
FatalError(diagnostics);
|
FatalError(diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
transform::VertexAttributeDescriptor GenerateVertexAttributeDescriptor(
|
|
||||||
DataBuilder* b) {
|
|
||||||
transform::VertexAttributeDescriptor desc{};
|
|
||||||
desc.format = b->enum_class<transform::VertexFormat>(
|
|
||||||
static_cast<uint8_t>(transform::VertexFormat::kLastEntry) + 1);
|
|
||||||
desc.offset = b->build<uint32_t>();
|
|
||||||
desc.shader_location = b->build<uint32_t>();
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform::VertexBufferLayoutDescriptor GenerateVertexBufferLayoutDescriptor(
|
|
||||||
DataBuilder* b) {
|
|
||||||
transform::VertexBufferLayoutDescriptor desc;
|
|
||||||
desc.array_stride = b->build<uint32_t>();
|
|
||||||
desc.step_mode = b->enum_class<transform::VertexStepMode>(
|
|
||||||
static_cast<uint8_t>(transform::VertexStepMode::kLastEntry) + 1);
|
|
||||||
desc.attributes = b->vector(GenerateVertexAttributeDescriptor);
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SPIRVToolsValidationCheck(const tint::Program& program,
|
bool SPIRVToolsValidationCheck(const tint::Program& program,
|
||||||
const std::vector<uint32_t>& spirv) {
|
const std::vector<uint32_t>& spirv) {
|
||||||
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
|
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
|
||||||
|
@ -94,76 +74,6 @@ bool SPIRVToolsValidationCheck(const tint::Program& program,
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
DataBuilder::DataBuilder(const uint8_t* data, size_t size)
|
|
||||||
: generator_(RandomGenerator::CalculateSeed(data, size)) {}
|
|
||||||
|
|
||||||
std::string DataBuilder::string() {
|
|
||||||
auto count = build<uint8_t>();
|
|
||||||
if (count == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::vector<uint8_t> source(count);
|
|
||||||
build(source.data(), count);
|
|
||||||
return std::string(source.begin(), source.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataBuilder::build(void* out, size_t n) {
|
|
||||||
assert(out != nullptr && "|out| cannot be nullptr");
|
|
||||||
assert(n > 0 && "|n| must be > 0");
|
|
||||||
|
|
||||||
generator_.GetNBytes(reinterpret_cast<uint8_t*>(out), n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateBindingRemapperInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs) {
|
|
||||||
struct Config {
|
|
||||||
uint8_t old_group;
|
|
||||||
uint8_t old_binding;
|
|
||||||
uint8_t new_group;
|
|
||||||
uint8_t new_binding;
|
|
||||||
ast::Access new_access;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Config> configs = b->vector<Config>();
|
|
||||||
transform::BindingRemapper::BindingPoints binding_points;
|
|
||||||
transform::BindingRemapper::AccessControls accesses;
|
|
||||||
for (const auto& config : configs) {
|
|
||||||
binding_points[{config.old_binding, config.old_group}] = {
|
|
||||||
config.new_binding, config.new_group};
|
|
||||||
accesses[{config.old_binding, config.old_group}] = config.new_access;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputs->Add<transform::BindingRemapper::Remappings>(binding_points, accesses);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateFirstIndexOffsetInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs) {
|
|
||||||
struct Config {
|
|
||||||
uint32_t group;
|
|
||||||
uint32_t binding;
|
|
||||||
};
|
|
||||||
|
|
||||||
Config config = b->build<Config>();
|
|
||||||
inputs->Add<tint::transform::FirstIndexOffset::BindingPoint>(config.binding,
|
|
||||||
config.group);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateSingleEntryPointInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs) {
|
|
||||||
std::string input = b->string();
|
|
||||||
transform::SingleEntryPoint::Config cfg(input);
|
|
||||||
inputs->Add<transform::SingleEntryPoint::Config>(cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateVertexPullingInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs) {
|
|
||||||
transform::VertexPulling::Config cfg;
|
|
||||||
cfg.entry_point_name = b->string();
|
|
||||||
cfg.vertex_state = b->vector(GenerateVertexBufferLayoutDescriptor);
|
|
||||||
cfg.pulling_group = b->build<uint32_t>();
|
|
||||||
inputs->Add<transform::VertexPulling::Config>(cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options) {
|
void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options) {
|
||||||
*options = b->build<writer::spirv::Options>();
|
*options = b->build<writer::spirv::Options>();
|
||||||
}
|
}
|
||||||
|
@ -181,10 +91,7 @@ void GenerateMslOptions(DataBuilder* b, writer::msl::Options* options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonFuzzer::CommonFuzzer(InputFormat input, OutputFormat output)
|
CommonFuzzer::CommonFuzzer(InputFormat input, OutputFormat output)
|
||||||
: input_(input),
|
: input_(input), output_(output) {}
|
||||||
output_(output),
|
|
||||||
transform_manager_(nullptr),
|
|
||||||
inspector_enabled_(false) {}
|
|
||||||
|
|
||||||
CommonFuzzer::~CommonFuzzer() = default;
|
CommonFuzzer::~CommonFuzzer() = default;
|
||||||
|
|
||||||
|
@ -345,7 +252,7 @@ int CommonFuzzer::Run(const uint8_t* data, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform_manager_) {
|
if (transform_manager_) {
|
||||||
auto out = transform_manager_->Run(&program, transform_inputs_);
|
auto out = transform_manager_->Run(&program, *transform_inputs_);
|
||||||
if (!out.program.IsValid()) {
|
if (!out.program.IsValid()) {
|
||||||
// Transforms can produce error messages for bad input.
|
// Transforms can produce error messages for bad input.
|
||||||
// Catch ICEs and errors from non transform systems.
|
// Catch ICEs and errors from non transform systems.
|
||||||
|
|
|
@ -15,71 +15,20 @@
|
||||||
#ifndef FUZZERS_TINT_COMMON_FUZZER_H_
|
#ifndef FUZZERS_TINT_COMMON_FUZZER_H_
|
||||||
#define FUZZERS_TINT_COMMON_FUZZER_H_
|
#define FUZZERS_TINT_COMMON_FUZZER_H_
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "fuzzers/random_generator.h"
|
|
||||||
#include "include/tint/tint.h"
|
#include "include/tint/tint.h"
|
||||||
|
|
||||||
|
#include "fuzzers/data_builder.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
|
|
||||||
class DataBuilder {
|
|
||||||
public:
|
|
||||||
DataBuilder(const uint8_t* data, size_t size);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T build() {
|
|
||||||
T out{};
|
|
||||||
build(&out, sizeof(T));
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string string();
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::vector<T> vector() {
|
|
||||||
auto count = build<uint8_t>();
|
|
||||||
std::vector<T> out(count);
|
|
||||||
for (uint8_t i = 0; i < count; i++) {
|
|
||||||
out[i] = build<T>();
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::vector<T> vector(T (*generate)(DataBuilder*)) {
|
|
||||||
auto count = build<uint8_t>();
|
|
||||||
std::vector<T> out(count);
|
|
||||||
for (uint8_t i = 0; i < count; i++) {
|
|
||||||
out[i] = generate(this);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T enum_class(uint8_t count) {
|
|
||||||
auto val = build<uint8_t>();
|
|
||||||
return static_cast<T>(val % count);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void build(void* out, size_t n);
|
|
||||||
|
|
||||||
RandomGenerator generator_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void GenerateBindingRemapperInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs);
|
|
||||||
void GenerateFirstIndexOffsetInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs);
|
|
||||||
void GenerateSingleEntryPointInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs);
|
|
||||||
void GenerateVertexPullingInputs(DataBuilder* b,
|
|
||||||
tint::transform::DataMap* inputs);
|
|
||||||
void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options);
|
void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options);
|
||||||
void GenerateWgslOptions(DataBuilder* b, writer::wgsl::Options* options);
|
void GenerateWgslOptions(DataBuilder* b, writer::wgsl::Options* options);
|
||||||
void GenerateHlslOptions(DataBuilder* b, writer::hlsl::Options* options);
|
void GenerateHlslOptions(DataBuilder* b, writer::hlsl::Options* options);
|
||||||
|
@ -94,9 +43,10 @@ class CommonFuzzer {
|
||||||
explicit CommonFuzzer(InputFormat input, OutputFormat output);
|
explicit CommonFuzzer(InputFormat input, OutputFormat output);
|
||||||
~CommonFuzzer();
|
~CommonFuzzer();
|
||||||
|
|
||||||
void SetTransformManager(transform::Manager* tm, transform::DataMap inputs) {
|
void SetTransformManager(transform::Manager* tm, transform::DataMap* inputs) {
|
||||||
|
assert((!tm || inputs) && "DataMap must be !nullptr if Manager !nullptr");
|
||||||
transform_manager_ = tm;
|
transform_manager_ = tm;
|
||||||
transform_inputs_ = std::move(inputs);
|
transform_inputs_ = inputs;
|
||||||
}
|
}
|
||||||
void EnableInspector() { inspector_enabled_ = true; }
|
void EnableInspector() { inspector_enabled_ = true; }
|
||||||
|
|
||||||
|
@ -137,9 +87,9 @@ class CommonFuzzer {
|
||||||
private:
|
private:
|
||||||
InputFormat input_;
|
InputFormat input_;
|
||||||
OutputFormat output_;
|
OutputFormat output_;
|
||||||
transform::Manager* transform_manager_;
|
transform::Manager* transform_manager_ = nullptr;
|
||||||
transform::DataMap transform_inputs_;
|
transform::DataMap* transform_inputs_ = nullptr;
|
||||||
bool inspector_enabled_;
|
bool inspector_enabled_ = false;
|
||||||
bool dump_input_ = false;
|
bool dump_input_ = false;
|
||||||
tint::diag::List diagnostics_;
|
tint::diag::List diagnostics_;
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,19 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/transform_builder.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::transform::Manager transform_manager;
|
TransformBuilder tb(data, size);
|
||||||
tint::transform::DataMap transform_inputs;
|
tb.AddTransform<transform::FirstIndexOffset>();
|
||||||
DataBuilder b(data, size);
|
|
||||||
|
|
||||||
GenerateFirstIndexOffsetInputs(&b, &transform_inputs);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
||||||
transform_manager.Add<tint::transform::FirstIndexOffset>();
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
|
|
||||||
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
return fuzzer.Run(data, size);
|
return fuzzer.Run(data, size);
|
||||||
|
|
|
@ -12,21 +12,21 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/transform_builder.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) {
|
||||||
transform::Manager transform_manager;
|
TransformBuilder tb(data, size);
|
||||||
transform::DataMap transform_inputs;
|
tb.AddTransform<transform::Robustness>();
|
||||||
transform_manager.Add<transform::Robustness>();
|
|
||||||
|
|
||||||
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
||||||
fuzzer.EnableInspector();
|
fuzzer.EnableInspector();
|
||||||
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
|
||||||
|
|
||||||
return fuzzer.Run(data, size);
|
return fuzzer.Run(data, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
|
||||||
CommonFuzzer fuzzer(InputFormat::kWGSL, target.output_format);
|
CommonFuzzer fuzzer(InputFormat::kWGSL, target.output_format);
|
||||||
fuzzer.EnableInspector();
|
fuzzer.EnableInspector();
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
fuzzer.SetTransformManager(&transform_manager, &transform_inputs);
|
||||||
|
|
||||||
fuzzer.Run(data, size);
|
fuzzer.Run(data, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -12,22 +12,19 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/transform_builder.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::transform::Manager transform_manager;
|
TransformBuilder tb(data, size);
|
||||||
tint::transform::DataMap transform_inputs;
|
tb.AddTransform<transform::SingleEntryPoint>();
|
||||||
DataBuilder b(data, size);
|
|
||||||
|
|
||||||
GenerateSingleEntryPointInputs(&b, &transform_inputs);
|
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
||||||
transform_manager.Add<tint::transform::SingleEntryPoint>();
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
|
|
||||||
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
return fuzzer.Run(data, size);
|
return fuzzer.Run(data, size);
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -12,22 +12,19 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_init_fuzzer.h"
|
#include "fuzzers/transform_builder.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::transform::Manager transform_manager;
|
TransformBuilder tb(data, size);
|
||||||
tint::transform::DataMap transform_inputs;
|
tb.AddTransform<transform::VertexPulling>();
|
||||||
DataBuilder b(data, size);
|
|
||||||
|
|
||||||
GenerateVertexPullingInputs(&b, &transform_inputs);
|
|
||||||
transform_manager.Add<tint::transform::VertexPulling>();
|
|
||||||
|
|
||||||
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
tint::fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
|
||||||
fuzzer.SetTransformManager(&transform_manager, std::move(transform_inputs));
|
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
|
||||||
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
fuzzer.SetDumpInput(GetCliParams().dump_input);
|
||||||
|
|
||||||
return fuzzer.Run(data, size);
|
return fuzzer.Run(data, size);
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "fuzzers/fuzzer_init.h"
|
||||||
#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 {
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
// 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_TRANSFORM_BUILDER_H_
|
||||||
|
#define FUZZERS_TRANSFORM_BUILDER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "include/tint/tint.h"
|
||||||
|
|
||||||
|
#include "fuzzers/data_builder.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
/// Fuzzer utility class to build inputs for transforms and setup the transform
|
||||||
|
/// manager.
|
||||||
|
class TransformBuilder {
|
||||||
|
public:
|
||||||
|
/// @brief Initialize the data source using a data buffer as a seed
|
||||||
|
/// @param data - pointer to a data buffer to use as a seed
|
||||||
|
/// @param size - size of data buffer
|
||||||
|
explicit TransformBuilder(const uint8_t* data, size_t size)
|
||||||
|
: builder_(data, size) {}
|
||||||
|
~TransformBuilder() {}
|
||||||
|
|
||||||
|
transform::Manager* manager() { return &manager_; }
|
||||||
|
transform::DataMap* data_map() { return &data_map_; }
|
||||||
|
DataBuilder* builder() { return &builder_; }
|
||||||
|
|
||||||
|
/// Adds a transform and needed data to |manager_| and |data_map_|.
|
||||||
|
/// @tparam T - A class that inherits from transform::Transform and has an
|
||||||
|
/// explicit specialization in AddTransformImpl.
|
||||||
|
template <typename T>
|
||||||
|
void AddTransform() {
|
||||||
|
static_assert(std::is_base_of<transform::Transform, T>::value,
|
||||||
|
"T is not a transform::Transform");
|
||||||
|
AddTransformImpl<T>::impl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper that invokes Add*Transform for all of the platform independent
|
||||||
|
/// passes.
|
||||||
|
void AddPlatformIndependentPasses() {
|
||||||
|
AddTransform<transform::Robustness>();
|
||||||
|
AddTransform<transform::FirstIndexOffset>();
|
||||||
|
AddTransform<transform::BindingRemapper>();
|
||||||
|
AddTransform<transform::Renamer>();
|
||||||
|
AddTransform<transform::SingleEntryPoint>();
|
||||||
|
AddTransform<transform::VertexPulling>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DataBuilder builder_;
|
||||||
|
transform::Manager manager_;
|
||||||
|
transform::DataMap data_map_;
|
||||||
|
|
||||||
|
/// Implementation of AddTransform, specialized for each transform that is
|
||||||
|
/// implemented. Default implementation intentionally deleted to cause compile
|
||||||
|
/// error if unimplemented type passed in.
|
||||||
|
/// @tparam T - A fuzzer transform
|
||||||
|
template <typename T>
|
||||||
|
struct AddTransformImpl;
|
||||||
|
|
||||||
|
/// Implementation of AddTransform for transform::Robustness
|
||||||
|
template <>
|
||||||
|
struct AddTransformImpl<transform::Robustness> {
|
||||||
|
/// Add instance of transform::Robustness to TransformBuilder
|
||||||
|
/// @param tb - TransformBuilder to add transform to
|
||||||
|
static void impl(TransformBuilder* tb) {
|
||||||
|
tb->manager()->Add<transform::Robustness>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Implementation of AddTransform for transform::FirstIndexOffset
|
||||||
|
template <>
|
||||||
|
struct AddTransformImpl<transform::FirstIndexOffset> {
|
||||||
|
/// Add instance of transform::FirstIndexOffset to TransformBuilder
|
||||||
|
/// @param tb - TransformBuilder to add transform to
|
||||||
|
static void impl(TransformBuilder* tb) {
|
||||||
|
struct Config {
|
||||||
|
uint32_t group;
|
||||||
|
uint32_t binding;
|
||||||
|
};
|
||||||
|
|
||||||
|
Config config = tb->builder()->build<Config>();
|
||||||
|
|
||||||
|
tb->data_map()->Add<tint::transform::FirstIndexOffset::BindingPoint>(
|
||||||
|
config.binding, config.group);
|
||||||
|
tb->manager()->Add<transform::FirstIndexOffset>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Implementation of AddTransform for transform::BindingRemapper
|
||||||
|
template <>
|
||||||
|
struct AddTransformImpl<transform::BindingRemapper> {
|
||||||
|
/// Add instance of transform::BindingRemapper to TransformBuilder
|
||||||
|
/// @param tb - TransformBuilder to add transform to
|
||||||
|
static void impl(TransformBuilder* tb) {
|
||||||
|
struct Config {
|
||||||
|
uint8_t old_group;
|
||||||
|
uint8_t old_binding;
|
||||||
|
uint8_t new_group;
|
||||||
|
uint8_t new_binding;
|
||||||
|
ast::Access new_access;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Config> configs = tb->builder()->vector<Config>();
|
||||||
|
transform::BindingRemapper::BindingPoints binding_points;
|
||||||
|
transform::BindingRemapper::AccessControls accesses;
|
||||||
|
for (const auto& config : configs) {
|
||||||
|
binding_points[{config.old_binding, config.old_group}] = {
|
||||||
|
config.new_binding, config.new_group};
|
||||||
|
accesses[{config.old_binding, config.old_group}] = config.new_access;
|
||||||
|
}
|
||||||
|
|
||||||
|
tb->data_map()->Add<transform::BindingRemapper::Remappings>(
|
||||||
|
binding_points, accesses, tb->builder()->build<bool>());
|
||||||
|
tb->manager()->Add<transform::BindingRemapper>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Implementation of AddTransform for transform::Renamer
|
||||||
|
template <>
|
||||||
|
struct AddTransformImpl<transform::Renamer> {
|
||||||
|
/// Add instance of transform::Renamer to TransformBuilder
|
||||||
|
/// @param tb - TransformBuilder to add transform to
|
||||||
|
static void impl(TransformBuilder* tb) {
|
||||||
|
tb->manager()->Add<transform::Renamer>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Implementation of AddTransform for transform::SingleEntryPoint
|
||||||
|
template <>
|
||||||
|
struct AddTransformImpl<transform::SingleEntryPoint> {
|
||||||
|
/// Add instance of transform::SingleEntryPoint to TransformBuilder
|
||||||
|
/// @param tb - TransformBuilder to add transform to
|
||||||
|
static void impl(TransformBuilder* tb) {
|
||||||
|
auto input = tb->builder()->build<std::string>();
|
||||||
|
transform::SingleEntryPoint::Config cfg(input);
|
||||||
|
|
||||||
|
tb->data_map()->Add<transform::SingleEntryPoint::Config>(cfg);
|
||||||
|
tb->manager()->Add<transform::SingleEntryPoint>();
|
||||||
|
}
|
||||||
|
}; // struct AddTransformImpl<transform::SingleEntryPoint>
|
||||||
|
|
||||||
|
/// Implementation of AddTransform for transform::VertexPulling
|
||||||
|
template <>
|
||||||
|
struct AddTransformImpl<transform::VertexPulling> {
|
||||||
|
/// Add instance of transform::VertexPulling to TransformBuilder
|
||||||
|
/// @param tb - TransformBuilder to add transform to
|
||||||
|
static void impl(TransformBuilder* tb) {
|
||||||
|
transform::VertexPulling::Config cfg;
|
||||||
|
cfg.entry_point_name = tb->builder()->build<std::string>();
|
||||||
|
cfg.vertex_state =
|
||||||
|
tb->builder()->vector<transform::VertexBufferLayoutDescriptor>(
|
||||||
|
GenerateVertexBufferLayoutDescriptor);
|
||||||
|
cfg.pulling_group = tb->builder()->build<uint32_t>();
|
||||||
|
|
||||||
|
tb->data_map()->Add<transform::VertexPulling::Config>(cfg);
|
||||||
|
tb->manager()->Add<transform::VertexPulling>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Generate an instance of transform::VertexAttributeDescriptor
|
||||||
|
/// @param b - DataBuilder to use
|
||||||
|
static transform::VertexAttributeDescriptor
|
||||||
|
GenerateVertexAttributeDescriptor(DataBuilder* b) {
|
||||||
|
transform::VertexAttributeDescriptor desc{};
|
||||||
|
desc.format = b->enum_class<transform::VertexFormat>(
|
||||||
|
static_cast<uint8_t>(transform::VertexFormat::kLastEntry) + 1);
|
||||||
|
desc.offset = b->build<uint32_t>();
|
||||||
|
desc.shader_location = b->build<uint32_t>();
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate an instance of VertexBufferLayoutDescriptor
|
||||||
|
/// @param b - DataBuilder to use
|
||||||
|
static transform::VertexBufferLayoutDescriptor
|
||||||
|
GenerateVertexBufferLayoutDescriptor(DataBuilder* b) {
|
||||||
|
transform::VertexBufferLayoutDescriptor desc;
|
||||||
|
desc.array_stride = b->build<uint32_t>();
|
||||||
|
desc.step_mode = b->enum_class<transform::VertexStepMode>(
|
||||||
|
static_cast<uint8_t>(transform::VertexStepMode::kLastEntry) + 1);
|
||||||
|
desc.attributes = b->vector<transform::VertexAttributeDescriptor>(
|
||||||
|
GenerateVertexAttributeDescriptor);
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}; // class TransformBuilder
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // FUZZERS_TRANSFORM_BUILDER_H_
|
Loading…
Reference in New Issue