180 lines
7.1 KiB
Protocol Buffer
180 lines
7.1 KiB
Protocol Buffer
// Copyright 2023 The Dawn 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.
|
|
|
|
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 lift_string_proto_member(member, count) -%}
|
|
required 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 in by_category["structure"] %}
|
|
required {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
|
{% set count.value = count.value + 1 %}
|
|
{% 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["enum"] %}
|
|
required {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
|
{% set count.value = count.value + 1 %}
|
|
{% elif member.type in by_category["object"] %}
|
|
required {{ lift_object_member(member, count) }} = {{ count.value }};
|
|
{% set count.value = count.value + 1 %}
|
|
{% elif member.type.name.get() == "ObjectId" %}
|
|
required {{ lift_objectid_member(member, count) }} = {{ count.value }};
|
|
{% set count.value = count.value + 1 %}
|
|
{% elif member.type.name.get() == "ObjectHandle" %}
|
|
// Skips object handles while lifting dawn.json to protobuf because
|
|
// ObjectHandles are created and managed in DawnLPMSerializer. Passing
|
|
// arbitrary ObjectHandles from the fuzzer's bytestream isn't the
|
|
// strategy for this fuzzer.
|
|
{% else %}
|
|
required {{ 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 in by_category["structure"] and member.length == "constant" and member.constant_length == 1 %}
|
|
required {{ 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.type.name.get() == "uint8_t" %}
|
|
// Skip over byte arrays in protobuf, handled by DawnLPMSerializer
|
|
// with a hardcoded bytes and length.
|
|
{% 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;
|
|
}
|