| // Copyright 2023 The Dawn & Tint Authors |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, this |
| // list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| syntax = "proto2"; |
| package fuzzing; |
| |
| import "third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto"; |
| |
| |
| // These are hardcoded limits for Dawn Object allocations based on type to help |
| // guide the fuzzer towards reusing existing objects. |
| {% for type in by_category["object"] %} |
| {% set type_key = type.name.canonical_case() %} |
| enum {{ type.name.CamelCase() }}Id { |
| {% if type_key in cmd_records["lpm_info"]["limits"] %} |
| {% for n in range(cmd_records["lpm_info"]["limits"][type_key]) %} |
| {{ type.name.SNAKE_CASE() }}_{{ loop.index }} = {{ loop.index }}; |
| {% endfor %} |
| {% else %} |
| {% for n in range(cmd_records["lpm_info"]["limits"]["default"]) %} |
| {{ type.name.SNAKE_CASE() }}_{{ loop.index }} = {{ loop.index }}; |
| {% endfor %} |
| {% endif %} |
| INVALID_{{ type.name.SNAKE_CASE() }} = {{ cmd_records["lpm_info"]["invalid object id"] }}; |
| }; |
| {% endfor %} |
| |
| {% for type in by_category["enum"] %} |
| enum {{as_cppType(type.name)}} { |
| {% for value in type.values %} |
| {{ as_cppType(type.name) }}{{as_cppEnum(value.name)}} = {{ value.value }}; |
| {% endfor %} |
| }; |
| {% endfor %} |
| |
| |
| {% for type in by_category["bitmask"] %} |
| enum {{as_cppType(type.name)}} { |
| {% for value in type.values %} |
| {{ as_cppType(type.name) }}{{as_cppEnum(value.name)}} = {{ value.value }}; |
| {% endfor %} |
| }; |
| {% endfor %} |
| |
| {% macro optionality(member) -%} |
| {%- if member.optional -%} |
| optional |
| {%- else -%} |
| required |
| {%- endif -%} |
| {%- endmacro %} |
| |
| {% macro lift_string_proto_member(member, count) -%} |
| {{ optionality(member) }} string {{ as_protobufNameLPM(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| |
| {%- endmacro %} |
| |
| |
| {% macro lift_float_array_proto_member(member, count) -%} |
| repeated float {{ as_varName(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {%- endmacro %} |
| |
| |
| {% macro lift_object_member(member, count) %} |
| {{ member.type.name.CamelCase() }}Id {{ as_protobufNameLPM(member.name) }} |
| {% endmacro %} |
| |
| |
| {% macro lift_objectid_member(member, count) %} |
| {{ member.id_type.name.CamelCase() }}Id {{ as_protobufNameLPM(member.name) }} |
| {% endmacro %} |
| |
| |
| {% macro lift_varlength_proto_member(member, count) -%} |
| {% if member.type in by_category["object"] %} |
| repeated {{ lift_object_member(member, count) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% elif member.type.name.get() == "object id" %} |
| repeated {{ lift_objectid_member(member, count) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% else %} |
| repeated {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% endif %} |
| {%- endmacro %} |
| |
| |
| {% macro lift_dawn_member_pass_by_value(record, name, member, count) %} |
| {% if member.type.name.get() == "ObjectHandle" or |
| member.type.category == "function pointer" or |
| member.type.name.get() == "void *" %} |
| //* These types should not be serialized using protobuf structures. |
| //* Handled by the serializer. |
| {% elif member.type in by_category["bitmask"] %} |
| repeated {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% elif member.type in by_category["object"] %} |
| {{ optionality(member) }} {{ lift_object_member(member, count) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% elif member.type.name.get() == "ObjectId" %} |
| {{ optionality(member) }} {{ lift_objectid_member(member, count) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% elif member.type in by_category["structure"] or |
| member.type in by_category["enum"] %} |
| {{ optionality(member) }} {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% else %} |
| {{ optionality(member) }} {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% endif %} |
| {% endmacro %} |
| |
| {% macro lift_dawn_member_pass_by_pointer(record, name, member, count) %} |
| {% if member.type.name.get() == "uint8_t" %} |
| //* This types should not be serialized using protobuf structures. |
| //* Handled by the serializer. |
| {% elif member.type in by_category["structure"] and |
| member.length == "constant" and |
| member.constant_length == 1 %} |
| {{ optionality(member) }} {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }}; |
| {% set count.value = count.value + 1 %} |
| {% elif member.type.name.get() == "char" and |
| member.length == 'strlen' %} |
| {{ lift_string_proto_member(member, count) }} |
| {% elif member.type.name.get() == "float" %} |
| {{ lift_float_array_proto_member(member, count) }} |
| {% elif member.length != 'constant' %} |
| {{ lift_varlength_proto_member(member, count) }} |
| {% else %} |
| //* There shouldn't be any other pass-by-pointer types in |
| //* dawn*.json, if any are added we would like to know at compile time |
| {{ unreachable_code() }} |
| {% endif %} |
| {% endmacro %} |
| |
| {% macro lift_proto_members_helper(record, name, members) %} |
| {% set count = namespace(value=1) %} |
| {% for member in members %} |
| {% if member.skip_serialize == True %} |
| // {{ member.name.camelCase()}}.skip_serialize |
| {% elif member.annotation == 'value' %} |
| {{ lift_dawn_member_pass_by_value(record, name, member, count) }} |
| {% elif member.annotation == 'const*' %} |
| {{ lift_dawn_member_pass_by_pointer(record, name, member, count) }} |
| {% endif %} |
| {% endfor %} |
| {% endmacro %} |
| |
| |
| {% for structure in by_category["structure"] %} |
| message {{structure.name.CamelCase()}} { |
| {{ lift_proto_members_helper(structure, structure.name, structure.members) }} |
| } |
| {% endfor %} |
| |
| |
| {% for command in cmd_records["proto_generated_commands"] %} |
| message {{command.name.CamelCase()}} { |
| {{ lift_proto_members_helper(command, command.name, command.members) }} |
| } |
| {% endfor %} |
| |
| message Command { |
| oneof command { |
| {% for command in cmd_records["proto_all_commands"] %} |
| {{command.name.CamelCase()}} {{command.name.camelCase()}} = {{ loop.index }}; |
| {% endfor %} |
| } |
| } |
| |
| message Program { |
| repeated Command commands = 1; |
| } |