shrinker.h 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Copyright (c) 2019 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef SOURCE_FUZZ_SHRINKER_H_
  15. #define SOURCE_FUZZ_SHRINKER_H_
  16. #include <memory>
  17. #include <vector>
  18. #include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
  19. #include "spirv-tools/libspirv.hpp"
  20. namespace spvtools {
  21. namespace fuzz {
  22. // Shrinks a sequence of transformations that lead to an interesting SPIR-V
  23. // binary to yield a smaller sequence of transformations that still produce an
  24. // interesting binary.
  25. class Shrinker {
  26. public:
  27. // Possible statuses that can result from running the shrinker.
  28. enum ShrinkerResultStatus {
  29. kComplete,
  30. kFailedToCreateSpirvToolsInterface,
  31. kInitialBinaryInvalid,
  32. kInitialBinaryNotInteresting,
  33. kReplayFailed,
  34. kStepLimitReached,
  35. };
  36. // The type for a function that will take a binary, |binary|, and return true
  37. // if and only if the binary is deemed interesting. (The function also takes
  38. // an integer argument, |counter|, that will be incremented each time the
  39. // function is called; this is for debugging purposes).
  40. //
  41. // The notion of "interesting" depends on what properties of the binary or
  42. // tools that process the binary we are trying to maintain during shrinking.
  43. using InterestingnessFunction = std::function<bool(
  44. const std::vector<uint32_t>& binary, uint32_t counter)>;
  45. // Constructs a shrinker from the given target environment.
  46. Shrinker(spv_target_env env, uint32_t step_limit,
  47. bool validate_during_replay);
  48. // Disables copy/move constructor/assignment operations.
  49. Shrinker(const Shrinker&) = delete;
  50. Shrinker(Shrinker&&) = delete;
  51. Shrinker& operator=(const Shrinker&) = delete;
  52. Shrinker& operator=(Shrinker&&) = delete;
  53. ~Shrinker();
  54. // Sets the message consumer to the given |consumer|. The |consumer| will be
  55. // invoked once for each message communicated from the library.
  56. void SetMessageConsumer(MessageConsumer consumer);
  57. // Requires that when |transformation_sequence_in| is applied to |binary_in|
  58. // with initial facts |initial_facts|, the resulting binary is interesting
  59. // according to |interestingness_function|.
  60. //
  61. // Produces, via |transformation_sequence_out|, a subsequence of
  62. // |transformation_sequence_in| that, when applied with initial facts
  63. // |initial_facts|, produces a binary (captured via |binary_out|) that is
  64. // also interesting according to |interestingness_function|.
  65. ShrinkerResultStatus Run(
  66. const std::vector<uint32_t>& binary_in,
  67. const protobufs::FactSequence& initial_facts,
  68. const protobufs::TransformationSequence& transformation_sequence_in,
  69. const InterestingnessFunction& interestingness_function,
  70. std::vector<uint32_t>* binary_out,
  71. protobufs::TransformationSequence* transformation_sequence_out) const;
  72. private:
  73. struct Impl; // Opaque struct for holding internal data.
  74. std::unique_ptr<Impl> impl_; // Unique pointer to internal data.
  75. };
  76. } // namespace fuzz
  77. } // namespace spvtools
  78. #endif // SOURCE_FUZZ_SHRINKER_H_