blob: 0a2916ceb8aa306b5bd37f5a663f19d0368a6684 [file] [log] [blame]
// 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;
}