From 4630ede1021d49c610de1274dc9d1006b843e46b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 9 Aug 2017 22:30:28 +0200 Subject: [PATCH] ac: fail shader compilation if libelf is replaced by an incompatible version MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit UE4Editor has this issue. This commit prevents hangs (release build) or assertion failures (debug build). It doesn't fix the editor, but catastrophic scenarios are prevented. Cc: 17.1 17.2 Reviewed-by: Michel Dänzer Reviewed-by: Samuel Pitoiset --- src/amd/common/ac_binary.c | 12 ++++++++++-- src/amd/common/ac_binary.h | 2 +- src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c | 5 ++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/amd/common/ac_binary.c b/src/amd/common/ac_binary.c index 618b5cf8b86..1bf52c78328 100644 --- a/src/amd/common/ac_binary.c +++ b/src/amd/common/ac_binary.c @@ -109,7 +109,7 @@ static void parse_relocs(Elf *elf, Elf_Data *relocs, Elf_Data *symbols, } } -void ac_elf_read(const char *elf_data, unsigned elf_size, +bool ac_elf_read(const char *elf_data, unsigned elf_size, struct ac_shader_binary *binary) { char *elf_buffer; @@ -118,6 +118,7 @@ void ac_elf_read(const char *elf_data, unsigned elf_size, Elf_Data *symbols = NULL, *relocs = NULL; size_t section_str_index; unsigned symbol_sh_link = 0; + bool success = true; /* One of the libelf implementations * (http://www.mr511.de/software/english.htm) requires calling @@ -137,7 +138,8 @@ void ac_elf_read(const char *elf_data, unsigned elf_size, GElf_Shdr section_header; if (gelf_getshdr(section, §ion_header) != §ion_header) { fprintf(stderr, "Failed to read ELF section header\n"); - return; + success = false; + break; } name = elf_strptr(elf, section_str_index, section_header.sh_name); if (!strcmp(name, ".text")) { @@ -148,6 +150,11 @@ void ac_elf_read(const char *elf_data, unsigned elf_size, } else if (!strcmp(name, ".AMDGPU.config")) { section_data = elf_getdata(section, section_data); binary->config_size = section_data->d_size; + if (!binary->config_size) { + fprintf(stderr, ".AMDGPU.config is empty!\n"); + success = false; + break; + } binary->config = MALLOC(binary->config_size * sizeof(unsigned char)); memcpy(binary->config, section_data->d_buf, binary->config_size); } else if (!strcmp(name, ".AMDGPU.disasm")) { @@ -186,6 +193,7 @@ void ac_elf_read(const char *elf_data, unsigned elf_size, binary->global_symbol_count = 1; binary->config_size_per_symbol = binary->config_size; } + return success; } const unsigned char *ac_shader_binary_config_start( diff --git a/src/amd/common/ac_binary.h b/src/amd/common/ac_binary.h index a784a7220cc..45f554e4fe0 100644 --- a/src/amd/common/ac_binary.h +++ b/src/amd/common/ac_binary.h @@ -83,7 +83,7 @@ struct ac_shader_config { * Parse the elf binary stored in \p elf_data and create a * ac_shader_binary object. */ -void ac_elf_read(const char *elf_data, unsigned elf_size, +bool ac_elf_read(const char *elf_data, unsigned elf_size, struct ac_shader_binary *binary); /** diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c index df37267d37d..7a59c90c3e0 100644 --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c @@ -148,7 +148,10 @@ unsigned si_llvm_compile(LLVMModuleRef M, struct ac_shader_binary *binary, buffer_size = LLVMGetBufferSize(out_buffer); buffer_data = LLVMGetBufferStart(out_buffer); - ac_elf_read(buffer_data, buffer_size, binary); + if (!ac_elf_read(buffer_data, buffer_size, binary)) { + fprintf(stderr, "radeonsi: cannot read an ELF shader binary\n"); + diag.retval = 1; + } /* Clean up */ LLVMDisposeMemoryBuffer(out_buffer); -- 2.30.2