mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-24 16:51:06 +00:00
Add library for spirv-fuzz (#2618)
Adds a library for spirv-fuzz, consisting of a Fuzzer class that will transform a module with respect to (a) facts about the module provided via a FactManager class, and (b) a source of random numbers and parameters to control the transformation process provided via a FuzzerContext class. Transformations will be applied via classes that implement a FuzzerPass interface, and both facts and transformations will be represented via protobuf messages. Currently there are no concrete facts, transformations nor fuzzer passes; these will follow.
This commit is contained in:
parent
42abaa099a
commit
fe9f870130
@ -370,6 +370,8 @@ typedef struct spv_optimizer_options_t spv_optimizer_options_t;
|
|||||||
|
|
||||||
typedef struct spv_reducer_options_t spv_reducer_options_t;
|
typedef struct spv_reducer_options_t spv_reducer_options_t;
|
||||||
|
|
||||||
|
typedef struct spv_fuzzer_options_t spv_fuzzer_options_t;
|
||||||
|
|
||||||
// Type Definitions
|
// Type Definitions
|
||||||
|
|
||||||
typedef spv_const_binary_t* spv_const_binary;
|
typedef spv_const_binary_t* spv_const_binary;
|
||||||
@ -385,6 +387,8 @@ typedef spv_optimizer_options_t* spv_optimizer_options;
|
|||||||
typedef const spv_optimizer_options_t* spv_const_optimizer_options;
|
typedef const spv_optimizer_options_t* spv_const_optimizer_options;
|
||||||
typedef spv_reducer_options_t* spv_reducer_options;
|
typedef spv_reducer_options_t* spv_reducer_options;
|
||||||
typedef const spv_reducer_options_t* spv_const_reducer_options;
|
typedef const spv_reducer_options_t* spv_const_reducer_options;
|
||||||
|
typedef spv_fuzzer_options_t* spv_fuzzer_options;
|
||||||
|
typedef const spv_fuzzer_options_t* spv_const_fuzzer_options;
|
||||||
|
|
||||||
// Platform API
|
// Platform API
|
||||||
|
|
||||||
@ -590,6 +594,19 @@ SPIRV_TOOLS_EXPORT void spvReducerOptionsSetStepLimit(
|
|||||||
SPIRV_TOOLS_EXPORT void spvReducerOptionsSetFailOnValidationError(
|
SPIRV_TOOLS_EXPORT void spvReducerOptionsSetFailOnValidationError(
|
||||||
spv_reducer_options options, bool fail_on_validation_error);
|
spv_reducer_options options, bool fail_on_validation_error);
|
||||||
|
|
||||||
|
// Creates a fuzzer options object with default options. Returns a valid
|
||||||
|
// options object. The object remains valid until it is passed into
|
||||||
|
// |spvFuzzerOptionsDestroy|.
|
||||||
|
SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate();
|
||||||
|
|
||||||
|
// Destroys the given fuzzer options object.
|
||||||
|
SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options);
|
||||||
|
|
||||||
|
// Sets the seed with which the random number generator used by the fuzzer
|
||||||
|
// should be initialized.
|
||||||
|
SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed(
|
||||||
|
spv_fuzzer_options options, uint32_t seed);
|
||||||
|
|
||||||
// Encodes the given SPIR-V assembly text to its binary representation. The
|
// Encodes the given SPIR-V assembly text to its binary representation. The
|
||||||
// length parameter specifies the number of bytes for text. Encoded binary will
|
// length parameter specifies the number of bytes for text. Encoded binary will
|
||||||
// be stored into *binary. Any error will be written into *diagnostic if
|
// be stored into *binary. Any error will be written into *diagnostic if
|
||||||
|
@ -191,6 +191,26 @@ class ReducerOptions {
|
|||||||
spv_reducer_options options_;
|
spv_reducer_options options_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A C++ wrapper around a fuzzer options object.
|
||||||
|
class FuzzerOptions {
|
||||||
|
public:
|
||||||
|
FuzzerOptions() : options_(spvFuzzerOptionsCreate()) {}
|
||||||
|
~FuzzerOptions() { spvFuzzerOptionsDestroy(options_); }
|
||||||
|
|
||||||
|
// Allow implicit conversion to the underlying object.
|
||||||
|
operator spv_fuzzer_options() const { // NOLINT(google-explicit-constructor)
|
||||||
|
return options_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See spvFuzzerOptionsSetRandomSeed.
|
||||||
|
void set_random_seed(uint32_t seed) {
|
||||||
|
spvFuzzerOptionsSetRandomSeed(options_, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
spv_fuzzer_options options_;
|
||||||
|
};
|
||||||
|
|
||||||
// C++ interface for SPIRV-Tools functionalities. It wraps the context
|
// C++ interface for SPIRV-Tools functionalities. It wraps the context
|
||||||
// (including target environment and the corresponding SPIR-V grammar) and
|
// (including target environment and the corresponding SPIR-V grammar) and
|
||||||
// provides methods for assembling, disassembling, and validating.
|
// provides methods for assembling, disassembling, and validating.
|
||||||
|
@ -198,6 +198,7 @@ set_source_files_properties(
|
|||||||
|
|
||||||
add_subdirectory(opt)
|
add_subdirectory(opt)
|
||||||
add_subdirectory(reduce)
|
add_subdirectory(reduce)
|
||||||
|
add_subdirectory(fuzz)
|
||||||
add_subdirectory(link)
|
add_subdirectory(link)
|
||||||
|
|
||||||
set(SPIRV_SOURCES
|
set(SPIRV_SOURCES
|
||||||
@ -233,6 +234,7 @@ set(SPIRV_SOURCES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_constant.h
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_constant.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_definition.h
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_definition.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.h
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_fuzzer_options.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.h
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.h
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.h
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.h
|
||||||
@ -260,6 +262,7 @@ set(SPIRV_SOURCES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/print.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/print.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/software_version.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/software_version.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_fuzzer_options.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.cpp
|
||||||
|
90
source/fuzz/CMakeLists.txt
Normal file
90
source/fuzz/CMakeLists.txt
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Copyright (c) 2019 Google LLC
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
if(SPIRV_BUILD_FUZZER)
|
||||||
|
set(PROTOBUF_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/protobufs/spvtoolsfuzz.proto)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT protobufs/spvtoolsfuzz.pb.cc protobufs/spvtoolsfuzz.pb.h
|
||||||
|
COMMAND protobuf::protoc
|
||||||
|
-I=${CMAKE_CURRENT_SOURCE_DIR}/protobufs
|
||||||
|
--cpp_out=protobufs
|
||||||
|
${PROTOBUF_SOURCE}
|
||||||
|
DEPENDS ${PROTOBUF_SOURCE}
|
||||||
|
COMMENT "Generate protobuf sources from proto definition file."
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SPIRV_TOOLS_FUZZ_SOURCES
|
||||||
|
fact_manager.h
|
||||||
|
fuzzer.h
|
||||||
|
fuzzer_context.h
|
||||||
|
fuzzer_pass.h
|
||||||
|
protobufs/spirvfuzz_protobufs.h
|
||||||
|
pseudo_random_generator.h
|
||||||
|
random_generator.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.h
|
||||||
|
|
||||||
|
fact_manager.cpp
|
||||||
|
fuzzer.cpp
|
||||||
|
fuzzer_context.cpp
|
||||||
|
fuzzer_pass.cpp
|
||||||
|
pseudo_random_generator.cpp
|
||||||
|
random_generator.cpp
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
# Enable parallel builds across four cores for this lib
|
||||||
|
add_definitions(/MP4)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
spvtools_pch(SPIRV_TOOLS_FUZZ_SOURCES pch_source_fuzz)
|
||||||
|
|
||||||
|
add_library(SPIRV-Tools-fuzz ${SPIRV_TOOLS_FUZZ_SOURCES})
|
||||||
|
|
||||||
|
spvtools_default_compile_options(SPIRV-Tools-fuzz)
|
||||||
|
target_compile_definitions(SPIRV-Tools-fuzz PUBLIC -DGOOGLE_PROTOBUF_NO_RTTI -DGOOGLE_PROTOBUF_USE_UNALIGNED=0)
|
||||||
|
|
||||||
|
# Compilation of the auto-generated protobuf source file will yield warnings,
|
||||||
|
# which we have no control over and thus wish to ignore.
|
||||||
|
if(${COMPILER_IS_LIKE_GNU})
|
||||||
|
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.cc PROPERTIES COMPILE_FLAGS -w)
|
||||||
|
endif()
|
||||||
|
if(MSVC)
|
||||||
|
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/protobufs/spvtoolsfuzz.pb.cc PROPERTIES COMPILE_FLAGS /w)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(SPIRV-Tools-fuzz
|
||||||
|
PUBLIC ${spirv-tools_SOURCE_DIR}/include
|
||||||
|
PUBLIC ${SPIRV_HEADER_INCLUDE_DIR}
|
||||||
|
PRIVATE ${spirv-tools_BINARY_DIR}
|
||||||
|
PRIVATE ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
# The fuzzer reuses a lot of functionality from the SPIRV-Tools library.
|
||||||
|
target_link_libraries(SPIRV-Tools-fuzz
|
||||||
|
PUBLIC ${SPIRV_TOOLS}
|
||||||
|
PUBLIC SPIRV-Tools-opt
|
||||||
|
PUBLIC protobuf::libprotobuf)
|
||||||
|
|
||||||
|
set_property(TARGET SPIRV-Tools-fuzz PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||||
|
spvtools_check_symbol_exports(SPIRV-Tools-fuzz)
|
||||||
|
|
||||||
|
if(ENABLE_SPIRV_TOOLS_INSTALL)
|
||||||
|
install(TARGETS SPIRV-Tools-fuzz
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif(ENABLE_SPIRV_TOOLS_INSTALL)
|
||||||
|
|
||||||
|
endif(SPIRV_BUILD_FUZZER)
|
46
source/fuzz/fact_manager.cpp
Normal file
46
source/fuzz/fact_manager.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 <utility>
|
||||||
|
|
||||||
|
#include "source/fuzz/fact_manager.h"
|
||||||
|
#include "source/opt/ir_context.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
FactManager::FactManager() = default;
|
||||||
|
|
||||||
|
FactManager::~FactManager() = default;
|
||||||
|
|
||||||
|
bool FactManager::AddFacts(const protobufs::FactSequence& initial_facts,
|
||||||
|
opt::IRContext* context) {
|
||||||
|
for (auto& fact : initial_facts.fact()) {
|
||||||
|
if (!AddFact(fact, context)) {
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2621) Provide
|
||||||
|
// information about the fact that could not be added.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FactManager::AddFact(const spvtools::fuzz::protobufs::Fact&,
|
||||||
|
spvtools::opt::IRContext*) {
|
||||||
|
assert(0 && "No facts are yet supported.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
53
source/fuzz/fact_manager.h
Normal file
53
source/fuzz/fact_manager.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_FACT_MANAGER_H_
|
||||||
|
#define SOURCE_FUZZ_FACT_MANAGER_H_
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||||
|
#include "source/opt/constants.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// Keeps track of facts about the module being transformed on which the fuzzing
|
||||||
|
// process can depend. Some initial facts can be provided, for example about
|
||||||
|
// guarantees on the values of inputs to SPIR-V entry points. Transformations
|
||||||
|
// may then rely on these facts, can add further facts that they establish.
|
||||||
|
// Facts are intended to be simple properties that either cannot be deduced from
|
||||||
|
// the module (such as properties that are guaranteed to hold for entry point
|
||||||
|
// inputs), or that are established by transformations, likely to be useful for
|
||||||
|
// future transformations, and not completely trivial to deduce straight from
|
||||||
|
// the module.
|
||||||
|
class FactManager {
|
||||||
|
public:
|
||||||
|
FactManager();
|
||||||
|
|
||||||
|
~FactManager();
|
||||||
|
|
||||||
|
// Adds all the facts from |facts|, checking them for validity with respect to
|
||||||
|
// |context|. Returns true if and only if all facts are valid.
|
||||||
|
bool AddFacts(const protobufs::FactSequence& facts, opt::IRContext* context);
|
||||||
|
|
||||||
|
// Adds |fact| to the fact manager, checking it for validity with respect to
|
||||||
|
// |context|. Returns true if and only if the fact is valid.
|
||||||
|
bool AddFact(const protobufs::Fact& fact, opt::IRContext* context);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // #define SOURCE_FUZZ_FACT_MANAGER_H_
|
109
source/fuzz/fuzzer.cpp
Normal file
109
source/fuzz/fuzzer.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 "source/fuzz/fuzzer.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "source/fuzz/fact_manager.h"
|
||||||
|
#include "source/fuzz/fuzzer_context.h"
|
||||||
|
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||||
|
#include "source/fuzz/pseudo_random_generator.h"
|
||||||
|
#include "source/opt/build_module.h"
|
||||||
|
#include "source/spirv_fuzzer_options.h"
|
||||||
|
#include "source/util/make_unique.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const uint32_t kIdBoundGap = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Fuzzer::Impl {
|
||||||
|
explicit Impl(spv_target_env env) : target_env(env) {}
|
||||||
|
|
||||||
|
const spv_target_env target_env; // Target environment.
|
||||||
|
MessageConsumer consumer; // Message consumer.
|
||||||
|
};
|
||||||
|
|
||||||
|
Fuzzer::Fuzzer(spv_target_env env) : impl_(MakeUnique<Impl>(env)) {}
|
||||||
|
|
||||||
|
Fuzzer::~Fuzzer() = default;
|
||||||
|
|
||||||
|
void Fuzzer::SetMessageConsumer(MessageConsumer c) {
|
||||||
|
impl_->consumer = std::move(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
Fuzzer::FuzzerResultStatus Fuzzer::Run(
|
||||||
|
const std::vector<uint32_t>& binary_in,
|
||||||
|
const protobufs::FactSequence& initial_facts,
|
||||||
|
std::vector<uint32_t>* binary_out, protobufs::TransformationSequence*,
|
||||||
|
spv_const_fuzzer_options options) const {
|
||||||
|
// Check compatibility between the library version being linked with and the
|
||||||
|
// header files being used.
|
||||||
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
|
|
||||||
|
spvtools::SpirvTools tools(impl_->target_env);
|
||||||
|
if (!tools.IsValid()) {
|
||||||
|
impl_->consumer(SPV_MSG_ERROR, nullptr, {},
|
||||||
|
"Failed to create SPIRV-Tools interface; stopping.");
|
||||||
|
return Fuzzer::FuzzerResultStatus::kFailedToCreateSpirvToolsInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial binary should be valid.
|
||||||
|
if (!tools.Validate(&binary_in[0], binary_in.size())) {
|
||||||
|
impl_->consumer(SPV_MSG_ERROR, nullptr, {},
|
||||||
|
"Initial binary is invalid; stopping.");
|
||||||
|
return Fuzzer::FuzzerResultStatus::kInitialBinaryInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the module from the input binary.
|
||||||
|
std::unique_ptr<opt::IRContext> ir_context = BuildModule(
|
||||||
|
impl_->target_env, impl_->consumer, binary_in.data(), binary_in.size());
|
||||||
|
assert(ir_context);
|
||||||
|
|
||||||
|
// Make a PRNG, either from a given seed or from a random device.
|
||||||
|
PseudoRandomGenerator random_generator(
|
||||||
|
options->has_random_seed ? options->random_seed
|
||||||
|
: (uint32_t)std::random_device()());
|
||||||
|
|
||||||
|
// The fuzzer will introduce new ids into the module. The module's id bound
|
||||||
|
// gives the smallest id that can be used for this purpose. We add an offset
|
||||||
|
// to this so that there is a sizeable gap between the ids used in the
|
||||||
|
// original module and the ids used for fuzzing, as a readability aid.
|
||||||
|
//
|
||||||
|
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/2541) consider the
|
||||||
|
// case where the maximum id bound is reached.
|
||||||
|
auto minimum_fresh_id = ir_context->module()->id_bound() + kIdBoundGap;
|
||||||
|
FuzzerContext fuzzer_context(&random_generator, minimum_fresh_id);
|
||||||
|
|
||||||
|
FactManager fact_manager;
|
||||||
|
if (!fact_manager.AddFacts(initial_facts, ir_context.get())) {
|
||||||
|
return Fuzzer::FuzzerResultStatus::kInitialFactsInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fuzzer passes will be created and applied here and will populate the
|
||||||
|
// output sequence of transformations. Currently there are no passes.
|
||||||
|
// TODO(afd) Implement fuzzer passes and invoke them here.
|
||||||
|
|
||||||
|
// Encode the module as a binary.
|
||||||
|
ir_context->module()->ToBinary(binary_out, false);
|
||||||
|
|
||||||
|
return Fuzzer::FuzzerResultStatus::kComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
74
source/fuzz/fuzzer.h
Normal file
74
source/fuzz/fuzzer.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_FUZZER_H_
|
||||||
|
#define SOURCE_FUZZ_FUZZER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||||
|
#include "spirv-tools/libspirv.hpp"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// Transforms a SPIR-V module into a semantically equivalent SPIR-V module by
|
||||||
|
// running a number of randomized fuzzer passes.
|
||||||
|
class Fuzzer {
|
||||||
|
public:
|
||||||
|
// Possible statuses that can result from running the fuzzer.
|
||||||
|
enum class FuzzerResultStatus {
|
||||||
|
kComplete,
|
||||||
|
kFailedToCreateSpirvToolsInterface,
|
||||||
|
kInitialBinaryInvalid,
|
||||||
|
kInitialFactsInvalid,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constructs a fuzzer from the given target environment.
|
||||||
|
explicit Fuzzer(spv_target_env env);
|
||||||
|
|
||||||
|
// Disables copy/move constructor/assignment operations.
|
||||||
|
Fuzzer(const Fuzzer&) = delete;
|
||||||
|
Fuzzer(Fuzzer&&) = delete;
|
||||||
|
Fuzzer& operator=(const Fuzzer&) = delete;
|
||||||
|
Fuzzer& operator=(Fuzzer&&) = delete;
|
||||||
|
|
||||||
|
~Fuzzer();
|
||||||
|
|
||||||
|
// Sets the message consumer to the given |consumer|. The |consumer| will be
|
||||||
|
// invoked once for each message communicated from the library.
|
||||||
|
void SetMessageConsumer(MessageConsumer consumer);
|
||||||
|
|
||||||
|
// Transforms |binary_in| to |binary_out| by running a number of randomized
|
||||||
|
// fuzzer passes, controlled via |options|. Initial facts about the input
|
||||||
|
// binary and the context in which it will execute are provided via
|
||||||
|
// |initial_facts|. The transformation sequence that was applied is returned
|
||||||
|
// via |transformation_sequence_out|.
|
||||||
|
FuzzerResultStatus Run(
|
||||||
|
const std::vector<uint32_t>& binary_in,
|
||||||
|
const protobufs::FactSequence& initial_facts,
|
||||||
|
std::vector<uint32_t>* binary_out,
|
||||||
|
protobufs::TransformationSequence* transformation_sequence_out,
|
||||||
|
spv_const_fuzzer_options options) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl; // Opaque struct for holding internal data.
|
||||||
|
std::unique_ptr<Impl> impl_; // Unique pointer to internal data.
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_FUZZER_H_
|
33
source/fuzz/fuzzer_context.cpp
Normal file
33
source/fuzz/fuzzer_context.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 "source/fuzz/fuzzer_context.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
|
||||||
|
uint32_t min_fresh_id)
|
||||||
|
: random_generator_(random_generator), next_fresh_id_(min_fresh_id) {}
|
||||||
|
|
||||||
|
FuzzerContext::~FuzzerContext() = default;
|
||||||
|
|
||||||
|
uint32_t FuzzerContext::GetFreshId() { return next_fresh_id_++; }
|
||||||
|
|
||||||
|
RandomGenerator* FuzzerContext::GetRandomGenerator() {
|
||||||
|
return random_generator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
52
source/fuzz/fuzzer_context.h
Normal file
52
source/fuzz/fuzzer_context.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_FUZZER_CONTEXT_H_
|
||||||
|
#define SOURCE_FUZZ_FUZZER_CONTEXT_H_
|
||||||
|
|
||||||
|
#include "source/fuzz/random_generator.h"
|
||||||
|
#include "source/opt/function.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// Encapsulates all parameters that control the fuzzing process, such as the
|
||||||
|
// source of randomness and the probabilities with which transformations are
|
||||||
|
// applied.
|
||||||
|
class FuzzerContext {
|
||||||
|
public:
|
||||||
|
// Constructs a fuzzer context with a given random generator and the minimum
|
||||||
|
// value that can be used for fresh ids.
|
||||||
|
FuzzerContext(RandomGenerator* random_generator, uint32_t min_fresh_id);
|
||||||
|
|
||||||
|
~FuzzerContext();
|
||||||
|
|
||||||
|
// Provides the random generator used to control fuzzing.
|
||||||
|
RandomGenerator* GetRandomGenerator();
|
||||||
|
|
||||||
|
// Yields an id that is guaranteed not to be used in the module being fuzzed,
|
||||||
|
// or to have been issued before.
|
||||||
|
uint32_t GetFreshId();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The source of randomness.
|
||||||
|
RandomGenerator* random_generator_;
|
||||||
|
// The next fresh id to be issued.
|
||||||
|
uint32_t next_fresh_id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_FUZZER_CONTEXT_H_
|
31
source/fuzz/fuzzer_pass.cpp
Normal file
31
source/fuzz/fuzzer_pass.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 "source/fuzz/fuzzer_pass.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
FuzzerPass::FuzzerPass(opt::IRContext* ir_context, FactManager* fact_manager,
|
||||||
|
FuzzerContext* fuzzer_context,
|
||||||
|
protobufs::TransformationSequence* transformations)
|
||||||
|
: ir_context_(ir_context),
|
||||||
|
fact_manager_(fact_manager),
|
||||||
|
fuzzer_context_(fuzzer_context),
|
||||||
|
transformations_(transformations) {}
|
||||||
|
|
||||||
|
FuzzerPass::~FuzzerPass() = default;
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
61
source/fuzz/fuzzer_pass.h
Normal file
61
source/fuzz/fuzzer_pass.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_FUZZER_PASS_H_
|
||||||
|
#define SOURCE_FUZZ_FUZZER_PASS_H_
|
||||||
|
|
||||||
|
#include "source/fuzz/fact_manager.h"
|
||||||
|
#include "source/fuzz/fuzzer_context.h"
|
||||||
|
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// Interface for applying a pass of transformations to a module.
|
||||||
|
class FuzzerPass {
|
||||||
|
public:
|
||||||
|
FuzzerPass(opt::IRContext* ir_context, FactManager* fact_manager,
|
||||||
|
FuzzerContext* fuzzer_context,
|
||||||
|
protobufs::TransformationSequence* transformations);
|
||||||
|
|
||||||
|
virtual ~FuzzerPass();
|
||||||
|
|
||||||
|
// Applies the pass to the module |ir_context_|, assuming and updating
|
||||||
|
// facts from |fact_manager_|, and using |fuzzer_context_| to guide the
|
||||||
|
// process. Appends to |transformations_| all transformations that were
|
||||||
|
// applied during the pass.
|
||||||
|
virtual void Apply() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
opt::IRContext* GetIRContext() const { return ir_context_; }
|
||||||
|
|
||||||
|
FactManager* GetFactManager() const { return fact_manager_; }
|
||||||
|
|
||||||
|
FuzzerContext* GetFuzzerContext() const { return fuzzer_context_; }
|
||||||
|
|
||||||
|
protobufs::TransformationSequence* GetTransformations() const {
|
||||||
|
return transformations_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
opt::IRContext* ir_context_;
|
||||||
|
FactManager* fact_manager_;
|
||||||
|
FuzzerContext* fuzzer_context_;
|
||||||
|
protobufs::TransformationSequence* transformations_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // #define SOURCE_FUZZ_FUZZER_PASS_H_
|
52
source/fuzz/protobufs/spirvfuzz_protobufs.h
Normal file
52
source/fuzz/protobufs/spirvfuzz_protobufs.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_SPIRVFUZZ_PROTOBUFS_H_
|
||||||
|
#define SOURCE_FUZZ_SPIRVFUZZ_PROTOBUFS_H_
|
||||||
|
|
||||||
|
// This header file serves to act as a barrier between the protobuf header
|
||||||
|
// files and files that include them. It uses compiler pragmas to disable
|
||||||
|
// diagnostics, in order to ignore warnings generated during the processing
|
||||||
|
// of these header files without having to compromise on freedom from warnings
|
||||||
|
// in the rest of the project.
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wconversion"
|
||||||
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The following should be the only place in the project where protobuf files
|
||||||
|
// are directly included. This is so that they can be compiled in a manner
|
||||||
|
// where warnings are ignored.
|
||||||
|
|
||||||
|
#include "google/protobuf/util/json_util.h"
|
||||||
|
#include "source/fuzz/protobufs/spvtoolsfuzz.pb.h"
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_SPIRVFUZZ_PROTOBUFS_H_
|
38
source/fuzz/protobufs/spvtoolsfuzz.proto
Normal file
38
source/fuzz/protobufs/spvtoolsfuzz.proto
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// This file is specifically named spvtools_fuzz.proto so that the string
|
||||||
|
// 'spvtools_fuzz' appears in the names of global-scope symbols that protoc
|
||||||
|
// generates when targeting C++. This is to reduce the potential for name
|
||||||
|
// clashes with other globally-scoped symbols.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package spvtools.fuzz.protobufs;
|
||||||
|
|
||||||
|
message FactSequence {
|
||||||
|
repeated Fact fact = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Fact {
|
||||||
|
// Currently there are no facts.
|
||||||
|
}
|
||||||
|
|
||||||
|
message TransformationSequence {
|
||||||
|
repeated Transformation transformation = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Transformation {
|
||||||
|
// Currently there are no transformations.
|
||||||
|
}
|
47
source/fuzz/pseudo_random_generator.cpp
Normal file
47
source/fuzz/pseudo_random_generator.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 <cassert>
|
||||||
|
|
||||||
|
#include "source/fuzz/pseudo_random_generator.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
PseudoRandomGenerator::PseudoRandomGenerator(uint32_t seed) : mt_(seed) {}
|
||||||
|
|
||||||
|
PseudoRandomGenerator::~PseudoRandomGenerator() = default;
|
||||||
|
|
||||||
|
uint32_t PseudoRandomGenerator::RandomUint32(uint32_t bound) {
|
||||||
|
assert(bound > 0 && "Bound must be positive");
|
||||||
|
return static_cast<uint32_t>(
|
||||||
|
std::uniform_int_distribution<>(0, bound - 1)(mt_));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PseudoRandomGenerator::RandomBool() {
|
||||||
|
return static_cast<bool>(std::uniform_int_distribution<>(0, 1)(mt_));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PseudoRandomGenerator::RandomPercentage() {
|
||||||
|
// We use 101 because we want a result in the closed interval [0, 100], and
|
||||||
|
// RandomUint32 is not inclusive of its bound.
|
||||||
|
return RandomUint32(101);
|
||||||
|
}
|
||||||
|
|
||||||
|
double PseudoRandomGenerator::RandomDouble() {
|
||||||
|
return std::uniform_real_distribution<double>(0.0, 1.0)(mt_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
47
source/fuzz/pseudo_random_generator.h
Normal file
47
source/fuzz/pseudo_random_generator.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_PSEUDO_RANDOM_GENERATOR_H_
|
||||||
|
#define SOURCE_FUZZ_PSEUDO_RANDOM_GENERATOR_H_
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
#include "source/fuzz/random_generator.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
// Generates random data from a pseudo-random number generator.
|
||||||
|
class PseudoRandomGenerator : public RandomGenerator {
|
||||||
|
public:
|
||||||
|
explicit PseudoRandomGenerator(uint32_t seed);
|
||||||
|
|
||||||
|
~PseudoRandomGenerator() override;
|
||||||
|
|
||||||
|
uint32_t RandomUint32(uint32_t bound) override;
|
||||||
|
|
||||||
|
uint32_t RandomPercentage() override;
|
||||||
|
|
||||||
|
bool RandomBool() override;
|
||||||
|
|
||||||
|
double RandomDouble() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mt19937 mt_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_PSEUDO_RANDOM_GENERATOR_H_
|
25
source/fuzz/random_generator.cpp
Normal file
25
source/fuzz/random_generator.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 "source/fuzz/random_generator.h"
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
RandomGenerator::RandomGenerator() = default;
|
||||||
|
|
||||||
|
RandomGenerator::~RandomGenerator() = default;
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
45
source/fuzz/random_generator.h
Normal file
45
source/fuzz/random_generator.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_FUZZ_RANDOM_GENERATOR_H_
|
||||||
|
#define SOURCE_FUZZ_RANDOM_GENERATOR_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace spvtools {
|
||||||
|
namespace fuzz {
|
||||||
|
|
||||||
|
class RandomGenerator {
|
||||||
|
public:
|
||||||
|
RandomGenerator();
|
||||||
|
|
||||||
|
virtual ~RandomGenerator();
|
||||||
|
|
||||||
|
// Returns a value in the half-open interval [0, bound).
|
||||||
|
virtual uint32_t RandomUint32(uint32_t bound) = 0;
|
||||||
|
|
||||||
|
// Returns a value in the closed interval [0, 100].
|
||||||
|
virtual uint32_t RandomPercentage() = 0;
|
||||||
|
|
||||||
|
// Returns a boolean.
|
||||||
|
virtual bool RandomBool() = 0;
|
||||||
|
|
||||||
|
// Returns a double in the closed interval [0, 1]
|
||||||
|
virtual double RandomDouble() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fuzz
|
||||||
|
} // namespace spvtools
|
||||||
|
|
||||||
|
#endif // SOURCE_FUZZ_RANDOM_GENERATOR_H_
|
31
source/spirv_fuzzer_options.cpp
Normal file
31
source/spirv_fuzzer_options.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 "source/spirv_fuzzer_options.h"
|
||||||
|
|
||||||
|
spv_fuzzer_options_t::spv_fuzzer_options_t() = default;
|
||||||
|
|
||||||
|
SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate() {
|
||||||
|
return new spv_fuzzer_options_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options) {
|
||||||
|
delete options;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed(
|
||||||
|
spv_fuzzer_options options, uint32_t seed) {
|
||||||
|
options->has_random_seed = true;
|
||||||
|
options->random_seed = seed;
|
||||||
|
}
|
33
source/spirv_fuzzer_options.h
Normal file
33
source/spirv_fuzzer_options.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2019 Google LLC
|
||||||
|
//
|
||||||
|
// 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 SOURCE_SPIRV_FUZZER_OPTIONS_H_
|
||||||
|
#define SOURCE_SPIRV_FUZZER_OPTIONS_H_
|
||||||
|
|
||||||
|
#include "spirv-tools/libspirv.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
// Manages command line options passed to the SPIR-V Fuzzer. New struct
|
||||||
|
// members may be added for any new option.
|
||||||
|
struct spv_fuzzer_options_t {
|
||||||
|
spv_fuzzer_options_t();
|
||||||
|
|
||||||
|
// See spvFuzzerOptionsSetRandomSeed.
|
||||||
|
bool has_random_seed = false;
|
||||||
|
uint32_t random_seed = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SOURCE_SPIRV_FUZZER_OPTIONS_H_
|
@ -56,6 +56,13 @@ def check_library(library):
|
|||||||
# _ZN : something in a namespace
|
# _ZN : something in a namespace
|
||||||
# _Z[0-9]+spv[A-Z_] : C++ symbol starting with spv[A-Z_]
|
# _Z[0-9]+spv[A-Z_] : C++ symbol starting with spv[A-Z_]
|
||||||
symbol_ok_pattern = re.compile(r'^(spv[A-Z]|_ZN|_Z[0-9]+spv[A-Z_])')
|
symbol_ok_pattern = re.compile(r'^(spv[A-Z]|_ZN|_Z[0-9]+spv[A-Z_])')
|
||||||
|
|
||||||
|
# In addition, the following pattern whitelists global functions that are added
|
||||||
|
# by the protobuf compiler:
|
||||||
|
# - AddDescriptors_spvtoolsfuzz_2eproto()
|
||||||
|
# - InitDefaults_spvtoolsfuzz_2eproto()
|
||||||
|
symbol_whitelist_pattern = re.compile(r'_Z[0-9]+(InitDefaults|AddDescriptors)_spvtoolsfuzz_2eprotov')
|
||||||
|
|
||||||
seen = set()
|
seen = set()
|
||||||
result = 0
|
result = 0
|
||||||
for line in command_output(['objdump', '-t', library], '.').split('\n'):
|
for line in command_output(['objdump', '-t', library], '.').split('\n'):
|
||||||
@ -65,7 +72,7 @@ def check_library(library):
|
|||||||
if symbol not in seen:
|
if symbol not in seen:
|
||||||
seen.add(symbol)
|
seen.add(symbol)
|
||||||
#print("look at '{}'".format(symbol))
|
#print("look at '{}'".format(symbol))
|
||||||
if not symbol_ok_pattern.match(symbol):
|
if not (symbol_whitelist_pattern.match(symbol) or symbol_ok_pattern.match(symbol)):
|
||||||
print('{}: error: Unescaped exported symbol: {}'.format(PROG, symbol))
|
print('{}: error: Unescaped exported symbol: {}'.format(PROG, symbol))
|
||||||
result = 1
|
result = 1
|
||||||
return result
|
return result
|
||||||
|
Loading…
Reference in New Issue
Block a user