| // Copyright 2021 The Tint Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef FUZZERS_TINT_SPIRV_TOOLS_FUZZER_MUTATOR_H_ |
| #define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_MUTATOR_H_ |
| |
| #include <cassert> |
| #include <cstdint> |
| #include <string> |
| #include <vector> |
| |
| namespace tint { |
| namespace fuzzers { |
| namespace spvtools_fuzzer { |
| |
| /// This is an interface that is used to define custom mutators based on the |
| /// SPIR-V tools. |
| class Mutator { |
| public: |
| /// The status of the mutation. |
| enum class Status { |
| /// Binary is valid, the limit is not reached - can mutate further. |
| kComplete, |
| |
| /// The binary is valid, the limit of mutations has been reached - |
| /// can't mutate further. |
| kLimitReached, |
| |
| /// The binary is valid, the limit is not reached but the mutator has spent |
| /// too much time without mutating anything - better to restart to make sure |
| /// we can make any progress. |
| kStuck, |
| |
| /// The binary is invalid - this is likely a bug in the mutator - must |
| /// abort. |
| kInvalid |
| }; |
| |
| /// Represents the result of the mutation. The following states are possible: |
| /// - if `IsChanged() == false`, then `GetStatus()` can be either |
| /// `kLimitReached` or `kStuck`. |
| /// - otherwise, any value of `Status` is possible. |
| class Result { |
| public: |
| /// Constructor. |
| /// @param status - the status of the mutation. |
| /// @param is_changed - whether the module was changed during mutation. |
| Result(Status status, bool is_changed); |
| |
| /// @return the status of the mutation. |
| Status GetStatus() const { return status_; } |
| |
| /// @return whether the module was changed during mutation. |
| bool IsChanged() const { return is_changed_; } |
| |
| private: |
| Status status_; |
| bool is_changed_; |
| }; |
| |
| /// Virtual destructor. |
| virtual ~Mutator(); |
| |
| /// Causes the mutator to apply a mutation. This method can be called |
| /// multiple times as long as the previous call didn't return |
| /// `Status::kInvalid`. |
| /// |
| /// @return the status of the mutation (e.g. success, error etc) and whether |
| /// the binary was changed during mutation. |
| virtual Result Mutate() = 0; |
| |
| /// Returns the mutated binary. The returned binary is guaranteed to be valid |
| /// iff the previous call to the `Mutate` method returned didn't return |
| /// `Status::kInvalid`. |
| /// |
| /// @return the mutated SPIR-V binary. It might be identical to the original |
| /// binary if `Result::IsChanged` returns `false`. |
| virtual std::vector<uint32_t> GetBinary() const = 0; |
| |
| /// Returns errors, produced by the mutator. |
| /// |
| /// @param path - the directory to which the errors are printed to. No files |
| /// are created if the `path` is nullptr. |
| /// @param count - the number of the error. Files for this error will be |
| /// prefixed with `count`. |
| virtual void LogErrors(const std::string* path, uint32_t count) const = 0; |
| |
| /// @return errors encountered during the mutation. The returned string is |
| /// if there were no errors during mutation. |
| virtual std::string GetErrors() const = 0; |
| }; |
| |
| } // namespace spvtools_fuzzer |
| } // namespace fuzzers |
| } // namespace tint |
| |
| #endif // FUZZERS_TINT_SPIRV_TOOLS_FUZZER_MUTATOR_H_ |