diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/radeon/Makefile.sources | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_elf_util.c | 90 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_elf_util.h | 39 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_llvm_emit.c | 53 |
4 files changed, 132 insertions, 51 deletions
diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources index bbfb8ad2fb9..6ebed2cf41e 100644 --- a/src/gallium/drivers/radeon/Makefile.sources +++ b/src/gallium/drivers/radeon/Makefile.sources @@ -1,5 +1,6 @@ C_SOURCES := \ r600_buffer_common.c \ + radeon_elf_util.c \ r600_pipe_common.c \ r600_query.c \ r600_streamout.c \ diff --git a/src/gallium/drivers/radeon/radeon_elf_util.c b/src/gallium/drivers/radeon/radeon_elf_util.c new file mode 100644 index 00000000000..7d929623937 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_elf_util.c @@ -0,0 +1,90 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: Tom Stellard <[email protected]> + * + */ + +#include "radeon_elf_util.h" +#include "r600_pipe_common.h" + +#include "util/u_memory.h" + +#include <gelf.h> +#include <libelf.h> +#include <stdio.h> + +void radeon_elf_read(const char *elf_data, unsigned elf_size, + struct radeon_shader_binary *binary, + unsigned debug) +{ + char *elf_buffer; + Elf *elf; + Elf_Scn *section = NULL; + size_t section_str_index; + + /* One of the libelf implementations + * (http://www.mr511.de/software/english.htm) requires calling + * elf_version() before elf_memory(). + */ + elf_version(EV_CURRENT); + elf_buffer = MALLOC(elf_size); + memcpy(elf_buffer, elf_data, elf_size); + + elf = elf_memory(elf_buffer, elf_size); + + elf_getshdrstrndx(elf, §ion_str_index); + binary->disassembled = 0; + + while ((section = elf_nextscn(elf, section))) { + const char *name; + Elf_Data *section_data = NULL; + GElf_Shdr section_header; + if (gelf_getshdr(section, §ion_header) != §ion_header) { + fprintf(stderr, "Failed to read ELF section header\n"); + return; + } + name = elf_strptr(elf, section_str_index, section_header.sh_name); + if (!strcmp(name, ".text")) { + section_data = elf_getdata(section, section_data); + binary->code_size = section_data->d_size; + binary->code = MALLOC(binary->code_size * sizeof(unsigned char)); + memcpy(binary->code, section_data->d_buf, binary->code_size); + } else if (!strcmp(name, ".AMDGPU.config")) { + section_data = elf_getdata(section, section_data); + binary->config_size = section_data->d_size; + binary->config = MALLOC(binary->config_size * sizeof(unsigned char)); + memcpy(binary->config, section_data->d_buf, binary->config_size); + } else if (debug && !strcmp(name, ".AMDGPU.disasm")) { + binary->disassembled = 1; + section_data = elf_getdata(section, section_data); + fprintf(stderr, "\nShader Disassembly:\n\n"); + fprintf(stderr, "%.*s\n", (int)section_data->d_size, + (char *)section_data->d_buf); + } + } + + if (elf){ + elf_end(elf); + } + FREE(elf_buffer); +} diff --git a/src/gallium/drivers/radeon/radeon_elf_util.h b/src/gallium/drivers/radeon/radeon_elf_util.h new file mode 100644 index 00000000000..60dae42e224 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_elf_util.h @@ -0,0 +1,39 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: Tom Stellard <[email protected]> + * + */ + +#ifndef RADEON_ELF_UTIL_H +#define RADEON_ELF_UTIL_H + +struct radeon_shader_binary; + +/* + * Parse the elf binary stored in \p elf_data and create a + * radeon_shader_binary object. + */ +void radeon_elf_read(const char *elf_data, unsigned elf_size, + struct radeon_shader_binary *binary, unsigned debug); + +#endif /* RADEON_ELF_UTIL_H */ diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.c b/src/gallium/drivers/radeon/radeon_llvm_emit.c index 4e0aaea0ebc..7bcdc2756f0 100644 --- a/src/gallium/drivers/radeon/radeon_llvm_emit.c +++ b/src/gallium/drivers/radeon/radeon_llvm_emit.c @@ -24,7 +24,7 @@ * */ #include "radeon_llvm_emit.h" -#include "r600_pipe_common.h" +#include "radeon_elf_util.h" #include "util/u_memory.h" #include <llvm-c/Target.h> @@ -33,8 +33,6 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <libelf.h> -#include <gelf.h> #define CPU_STRING_LEN 30 #define FS_STRING_LEN 30 @@ -98,10 +96,6 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar unsigned buffer_size; const char *buffer_data; char triple[TRIPLE_STRING_LEN]; - char *elf_buffer; - Elf *elf; - Elf_Scn *section = NULL; - size_t section_str_index; LLVMBool r; init_r600_target(); @@ -133,51 +127,8 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar buffer_size = LLVMGetBufferSize(out_buffer); buffer_data = LLVMGetBufferStart(out_buffer); - /* One of the libelf implementations - * (http://www.mr511.de/software/english.htm) requires calling - * elf_version() before elf_memory(). - */ - elf_version(EV_CURRENT); - elf_buffer = MALLOC(buffer_size); - memcpy(elf_buffer, buffer_data, buffer_size); - - elf = elf_memory(elf_buffer, buffer_size); - - elf_getshdrstrndx(elf, §ion_str_index); - binary->disassembled = 0; - - while ((section = elf_nextscn(elf, section))) { - const char *name; - Elf_Data *section_data = NULL; - GElf_Shdr section_header; - if (gelf_getshdr(section, §ion_header) != §ion_header) { - fprintf(stderr, "Failed to read ELF section header\n"); - return 1; - } - name = elf_strptr(elf, section_str_index, section_header.sh_name); - if (!strcmp(name, ".text")) { - section_data = elf_getdata(section, section_data); - binary->code_size = section_data->d_size; - binary->code = MALLOC(binary->code_size * sizeof(unsigned char)); - memcpy(binary->code, section_data->d_buf, binary->code_size); - } else if (!strcmp(name, ".AMDGPU.config")) { - section_data = elf_getdata(section, section_data); - binary->config_size = section_data->d_size; - binary->config = MALLOC(binary->config_size * sizeof(unsigned char)); - memcpy(binary->config, section_data->d_buf, binary->config_size); - } else if (dump && !strcmp(name, ".AMDGPU.disasm")) { - binary->disassembled = 1; - section_data = elf_getdata(section, section_data); - fprintf(stderr, "\nShader Disassembly:\n\n"); - fprintf(stderr, "%.*s\n", (int)section_data->d_size, - (char *)section_data->d_buf); - } - } + radeon_elf_read(buffer_data, buffer_size, binary, dump); - if (elf){ - elf_end(elf); - } - FREE(elf_buffer); LLVMDisposeMemoryBuffer(out_buffer); LLVMDisposeTargetMachine(tm); return 0; |