Path: blob/main_old/src/compiler/fuzz/translator_fuzzer.cpp
1693 views
//1// Copyright 2016 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator.78#include <cstddef>9#include <cstdint>10#include <iostream>11#include <memory>12#include <unordered_map>1314#include "angle_gl.h"15#include "anglebase/no_destructor.h"16#include "compiler/translator/Compiler.h"17#include "compiler/translator/util.h"1819using namespace sh;2021namespace22{2324// Options supported by any output25constexpr ShCompileOptions kCommonOptions =26SH_VALIDATE | SH_VALIDATE_LOOP_INDEXING | SH_INTERMEDIATE_TREE | SH_OBJECT_CODE | SH_VARIABLES |27SH_LINE_DIRECTIVES | SH_SOURCE_PATH | SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3 |28SH_EMULATE_ABS_INT_FUNCTION | SH_ENFORCE_PACKING_RESTRICTIONS | SH_CLAMP_INDIRECT_ARRAY_BOUNDS |29SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH | SH_INIT_GL_POSITION |30SH_INIT_OUTPUT_VARIABLES | SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS |31SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL | SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL |32SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH | SH_EMULATE_ISNAN_FLOAT_FUNCTION |33SH_INITIALIZE_UNINITIALIZED_LOCALS | SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |34SH_CLAMP_POINT_SIZE | SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES |35SH_SKIP_D3D_CONSTANT_REGISTER_ZERO | SH_EMULATE_GL_DRAW_ID | SH_INIT_SHARED_VARIABLES |36SH_FORCE_ATOMIC_VALUE_RESOLUTION | SH_EMULATE_GL_BASE_VERTEX_BASE_INSTANCE |37SH_TAKE_VIDEO_TEXTURE_AS_EXTERNAL_OES | SH_VALIDATE_AST | SH_ADD_BASE_VERTEX_TO_VERTEX_ID |38SH_REMOVE_DYNAMIC_INDEXING_OF_SWIZZLED_VECTOR | SH_DISABLE_ARB_TEXTURE_RECTANGLE |39SH_IGNORE_PRECISION_QUALIFIERS | SH_FORCE_SHADER_PRECISION_HIGHP_TO_MEDIUMP;4041// Options supported by GLSL or ESSL only42constexpr ShCompileOptions kGLSLOrESSLOnlyOptions =43SH_EMULATE_ATAN2_FLOAT_FUNCTION | SH_CLAMP_FRAG_DEPTH | SH_REGENERATE_STRUCT_NAMES |44SH_REWRITE_REPEATED_ASSIGN_TO_SWIZZLED | SH_USE_UNUSED_STANDARD_SHARED_BLOCKS |45SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER;4647#if defined(ANGLE_PLATFORM_APPLE)48// Options supported by GLSL only on mac49constexpr ShCompileOptions kGLSLMacOnlyOptions =50SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR | SH_ADD_AND_TRUE_TO_LOOP_CONDITION |51SH_REWRITE_DO_WHILE_LOOPS | SH_UNFOLD_SHORT_CIRCUIT | SH_REWRITE_ROW_MAJOR_MATRICES;52#endif5354// Options supported by Vulkan GLSL only55constexpr ShCompileOptions kVulkanGLSLOnlyOptions =56SH_ADD_PRE_ROTATION | SH_EMULATE_SEAMFUL_CUBE_MAP_SAMPLING |57SH_ADD_BRESENHAM_LINE_RASTER_EMULATION | SH_EARLY_FRAGMENT_TESTS_OPTIMIZATION |58SH_USE_SPECIALIZATION_CONSTANT | SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE;5960// Options supported by HLSL output only61constexpr ShCompileOptions kHLSLOnlyOptions = SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS |62SH_ALLOW_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER |63SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR;6465struct TranslatorCacheKey66{67bool operator==(const TranslatorCacheKey &other) const68{69return type == other.type && spec == other.spec && output == other.output;70}7172uint32_t type = 0;73uint32_t spec = 0;74uint32_t output = 0;75};76} // anonymous namespace7778namespace std79{8081template <>82struct hash<TranslatorCacheKey>83{84std::size_t operator()(const TranslatorCacheKey &k) const85{86return (hash<uint32_t>()(k.type) << 1) ^ (hash<uint32_t>()(k.spec) >> 1) ^87hash<uint32_t>()(k.output);88}89};90} // namespace std9192struct TCompilerDeleter93{94void operator()(TCompiler *compiler) const { DeleteCompiler(compiler); }95};9697extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)98{99// Reserve some size for future compile options100const size_t kHeaderSize = 128;101102if (size <= kHeaderSize)103{104return 0;105}106107// Make sure the rest of data will be a valid C string so that we don't have to copy it.108if (data[size - 1] != 0)109{110return 0;111}112113uint32_t type = *reinterpret_cast<const uint32_t *>(data);114uint32_t spec = *reinterpret_cast<const uint32_t *>(data + 4);115uint32_t output = *reinterpret_cast<const uint32_t *>(data + 8);116uint64_t options = *reinterpret_cast<const uint64_t *>(data + 12);117118if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER)119{120return 0;121}122123if (spec != SH_GLES2_SPEC && type != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC &&124spec != SH_WEBGL2_SPEC)125{126return 0;127}128129ShShaderOutput shaderOutput = static_cast<ShShaderOutput>(output);130131ShCompileOptions supportedOptions = kCommonOptions;132133if (IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput))134{135supportedOptions |= kGLSLOrESSLOnlyOptions;136#if defined(ANGLE_PLATFORM_APPLE)137supportedOptions |= kGLSLMacOnlyOptions;138#endif139}140else if (IsOutputVulkan(shaderOutput))141{142supportedOptions |= kVulkanGLSLOnlyOptions;143}144else if (IsOutputHLSL(shaderOutput))145{146supportedOptions |= kHLSLOnlyOptions;147}148149// If there are any options not supported with this output, don't attempt to run the translator.150if ((options & ~supportedOptions) != 0)151{152return 0;153}154155std::vector<uint32_t> validOutputs;156validOutputs.push_back(SH_ESSL_OUTPUT);157validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT);158validOutputs.push_back(SH_GLSL_130_OUTPUT);159validOutputs.push_back(SH_GLSL_140_OUTPUT);160validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT);161validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT);162validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT);163validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT);164validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT);165validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT);166validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT);167validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT);168validOutputs.push_back(SH_HLSL_3_0_OUTPUT);169validOutputs.push_back(SH_HLSL_4_1_OUTPUT);170validOutputs.push_back(SH_HLSL_4_0_FL9_3_OUTPUT);171bool found = false;172for (auto valid : validOutputs)173{174found = found || (valid == output);175}176if (!found)177{178return 0;179}180181size -= kHeaderSize;182data += kHeaderSize;183184sh::InitializeGlslang();185if (!sh::Initialize())186{187return 0;188}189190TranslatorCacheKey key;191key.type = type;192key.spec = spec;193key.output = output;194195using UniqueTCompiler = std::unique_ptr<TCompiler, TCompilerDeleter>;196static angle::base::NoDestructor<angle::HashMap<TranslatorCacheKey, UniqueTCompiler>>197translators;198199if (translators->find(key) == translators->end())200{201UniqueTCompiler translator(202ConstructCompiler(type, static_cast<ShShaderSpec>(spec), shaderOutput));203204if (translator == nullptr)205{206return 0;207}208209ShBuiltInResources resources;210sh::InitBuiltInResources(&resources);211212// Enable all the extensions to have more coverage213resources.OES_standard_derivatives = 1;214resources.OES_EGL_image_external = 1;215resources.OES_EGL_image_external_essl3 = 1;216resources.NV_EGL_stream_consumer_external = 1;217resources.ARB_texture_rectangle = 1;218resources.EXT_blend_func_extended = 1;219resources.EXT_draw_buffers = 1;220resources.EXT_frag_depth = 1;221resources.EXT_shader_texture_lod = 1;222resources.EXT_shader_framebuffer_fetch = 1;223resources.NV_shader_framebuffer_fetch = 1;224resources.ARM_shader_framebuffer_fetch = 1;225resources.EXT_YUV_target = 1;226resources.APPLE_clip_distance = 1;227resources.MaxDualSourceDrawBuffers = 1;228resources.EXT_gpu_shader5 = 1;229resources.MaxClipDistances = 1;230resources.EXT_shadow_samplers = 1;231resources.EXT_clip_cull_distance = 1;232resources.EXT_primitive_bounding_box = 1;233234if (!translator->Init(resources))235{236return 0;237}238239(*translators)[key] = std::move(translator);240}241242auto &translator = (*translators)[key];243244const char *shaderStrings[] = {reinterpret_cast<const char *>(data)};245translator->compile(shaderStrings, 1, options);246247return 0;248}249250251