ac: fail shader compilation if libelf is replaced by an incompatible version
authorMarek Olšák <marek.olsak@amd.com>
Wed, 9 Aug 2017 20:30:28 +0000 (22:30 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 10 Aug 2017 11:24:23 +0000 (13:24 +0200)
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 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/common/ac_binary.c
src/amd/common/ac_binary.h
src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c

index 618b5cf..1bf52c7 100644 (file)
@@ -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, &section_header) != &section_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(
index a784a72..45f554e 100644 (file)
@@ -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);
 
 /**
index df37267..7a59c90 100644 (file)
@@ -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);