-
Notifications
You must be signed in to change notification settings - Fork 564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Brief guide to writing a spirv-fuzz fuzzer pass #3190
Conversation
|
||
Writing a spirv-fuzz fuzzer pass usually requires two main contributions: | ||
|
||
- A *transformation*, capturing a small semantics-preserving change that can be made to a SPIR-V module. This requires adding a protobuf message representing the transformation, and a corresponding class that implements the `Transformation` interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
++ The transformation class contains the code that "applies" the transformation; i.e. mutates a SPIR-V module.
Writing a spirv-fuzz fuzzer pass usually requires two main contributions: | ||
|
||
- A *transformation*, capturing a small semantics-preserving change that can be made to a SPIR-V module. This requires adding a protobuf message representing the transformation, and a corresponding class that implements the `Transformation` interface. | ||
- A new *fuzzer pass* class, implementing the `FuzzerPass` interface, that knows how to walk a SPIR-V module and apply the new transformation in a randomized fashion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that walks a SPIR-V module and creates (and applies) transformations in a randomized fashion.
- A new *fuzzer pass* class, implementing the `FuzzerPass` interface, that knows how to walk a SPIR-V module and apply the new transformation in a randomized fashion. | ||
|
||
In some cases, more than one kind of transformation is required for a single fuzzer pass, and in some cases the transformations that a new fuzzer pass requires have already been introduced by existing passes. But the most common case is to introduce a transformation and fuzzer pass together. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that all fuzzer passes record the transformations as they are applied, resulting in a list of transformation protobuf messages. If we take the original SPIR-V module (without any transformations applied), we can re-apply all of the transformations in the list (in the same order) to get to the same transformed SPIR-V module.
Crucially, we can replay a subset of the transformations. Thus, when replaying an individual transformation, the SPIR-V module might be different from when the transformation was created because earlier transformations were not replayed. As we will see, transformations much be designed with this in mind.
- A *transformation*, capturing a small semantics-preserving change that can be made to a SPIR-V module. This requires adding a protobuf message representing the transformation, and a corresponding class that implements the `Transformation` interface. | ||
- A new *fuzzer pass* class, implementing the `FuzzerPass` interface, that knows how to walk a SPIR-V module and apply the new transformation in a randomized fashion. | ||
|
||
In some cases, more than one kind of transformation is required for a single fuzzer pass, and in some cases the transformations that a new fuzzer pass requires have already been introduced by existing passes. But the most common case is to introduce a transformation and fuzzer pass together. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove: "and in some cases the transformations that a new fuzzer pass requires have already been introduced by existing passes."
A fuzzer pass does not really require transformations; it requires stuff in the SPIR-V module. So I think this is just confusing. Perhaps it would be better to replace it with a mini-example.
"In some cases, more than one kind of transformation is required for a single fuzzer pass; e.g. transformation that adds a type declaration, transformation that adds a use of the type declaration."
|
||
Now look at the `TransformationSetSelectionControl` message. If adding your own transformation you need to add a new message for your transformation, and it should be placed alphabetically with respect to other transformations. | ||
|
||
The fields of `TransformationSetSelectionControl` provide just enough information to (a) determine whether a given example of this transformation is actually applicable, and (b) apply the transformation in the case that it is applicable. The details of the transformation message will vary a lot between transformations. In this case, the message has a `block_id` field, specifying a block that must end with `OpSelectionMerge`, and a `selection_control` field, which is the new value for the selection control mask of the `OpSelectionMerge` instruction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(a) and (b) might just be confusing at this stage because we have not really introduced much about why a transformation would not be applicable. This will also be covered when discussing the transformation class anyway. Could say:
The fields of TransformationSetSelectionControl
provide the information needed to find the OpSelectionMerge
instruction and to change it. As explained earlier, the SPIR-V module may have changed, which is why we say that we must find the instruction. The details of the transformation message will vary...
|
||
## Adding a new fuzzer pass class | ||
|
||
A *fuzzer pass* traverses a SPIR-V module looking for places to apply a certain kind of transformation, and randomly decides at which of these points to actually apply the transformation. It might be necessary to apply other transformations in order to apply a given transformation (for example, if a transformation requires a certain type to be present in the module, said type can be added if not already present via another transformation). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A fuzzer pass traverses a SPIR-V module looking for locations where a certain kind of transformation could be applied, and randomly decides at which of these points to create and apply an instance of the transformation.
Roll third_party/glslang/ c12493f..56364b6 (7 commits) KhronosGroup/glslang@c12493f...56364b6 $ git log c12493f..56364b6 --date=short --no-merges --format='%ad %ae %s' 2020-03-01 cepheus Copyright update, mostly to trigger bots again. 2020-03-01 cepheus Fix KhronosGroup#2095: correct the indentation. 2020-02-28 cepheus Fix KhronosGroup#1461: set the SPIRV-Tools' optimizer's target environment. 2020-02-28 cepheus Fix KhronosGroup#2091, remove incorrect assert for division by 0.0. 2020-02-28 wangli28 Add vcpkg installation instructions 2020-02-28 sk Fix for KhronosGroup#2075: removed DefaultTBuiltInResource from glslang_c_interface.cpp 2020-02-22 rex.xu Fix an issue of SPV generation for imageAtomicStore. Roll third_party/googletest/ 23b2a3b1c..e588eb1ff (3 commits) google/googletest@23b2a3b...e588eb1 $ git log 23b2a3b1c..e588eb1ff --date=short --no-merges --format='%ad %ae %s' 2020-02-27 absl-team Googletest export 2020-02-25 absl-team Googletest export 2020-02-19 absl-team Googletest export Roll third_party/re2/ 793b4e85e..f734980e7 (7 commits) google/re2@793b4e8...f734980 $ git log 793b4e85e..f734980e7 --date=short --no-merges --format='%ad %ae %s' 2020-03-01 junyer Bump SONAME to reflect the ABI break. 2020-02-28 junyer Add macOS and Xcode jobs to the Travis CI matrix. 2020-02-26 junyer Don't break the RE2 object when compiling the reverse Prog fails. 2020-02-26 junyer Revert "Refuse to rewrite when MaxSubmatch() is too large." 2020-02-25 junyer Fall back to NFA execution when compiling the reverse Prog failed. 2020-02-25 junyer Refuse to rewrite when MaxSubmatch() is too large. 2020-02-20 junyer Tweak the comment on RE2::QuoteMeta(). Roll third_party/spirv-cross/ f19fdb94d..9deb6ffbb (6 commits) KhronosGroup/SPIRV-Cross@f19fdb9...9deb6ff $ git log f19fdb94d..9deb6ffbb --date=short --no-merges --format='%ad %ae %s' 2020-03-02 post Add -V alias for --vulkan-semantics. 2020-02-24 post MSL: Add C API for force native arrays. 2020-02-24 post MSL: Add native array test for composite array initialization. 2020-02-24 post MSL: Reintroduce workaround for constant arrays being passed by value. 2020-02-24 post MSL: Reinstate workaround for returning arrays. 2020-02-24 post MSL: Add a workaround path to force native arrays for everything. Roll third_party/spirv-headers/ 5dbc1c3..0a7fc45 (1 commit) KhronosGroup/SPIRV-Headers@5dbc1c3...0a7fc45 $ git log 5dbc1c3..0a7fc45 --date=short --no-merges --format='%ad %ae %s' 2020-02-26 dneto Add grammars, C header, and header generator for vendor and KHR extended instruction sets (KhronosGroup#143) Roll third_party/spirv-tools/ 4a80497..e1688b6 (8 commits) KhronosGroup/SPIRV-Tools@4a80497...e1688b6 $ git log 4a80497..e1688b6 --date=short --no-merges --format='%ad %ae %s' 2020-02-28 dneto Avoid use of Python distutils.dir_util (KhronosGroup#3203) 2020-02-28 rharrison Adding WebGPU specific Workgroup scope rule (KhronosGroup#3204) 2020-02-25 jaebaek Add validation rules for OpenCL.DebugInfo.100 extension (KhronosGroup#3133) 2020-02-25 geofflang Combine extinst-name and extinst-output-base into one arg. (KhronosGroup#3200) 2020-02-23 nicolasweber Fix Wrange-loop-analysis warnings in SPIRV-Tools. (KhronosGroup#3201) 2020-02-21 geofflang Add missing dependencies when generating spvtools_core_tables (KhronosGroup#3199) 2020-02-21 afdx Brief guide to writing a spirv-fuzz fuzzer pass (KhronosGroup#3190) 2020-02-21 47594367+rg3igalia Fix ignored const qualifier warning in static_cast (KhronosGroup#3197) Created with: roll-dep third_party/effcee third_party/glslang third_party/googletest third_party/re2 third_party/spirv-cross third_party/spirv-headers third_party/spirv-tools
No description provided.