diff options
author | Tom Stellard <[email protected]> | 2013-04-04 13:02:51 -0700 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2013-04-15 10:54:29 -0700 |
commit | 9277b04c02de1e7a89b65839d8f4f717163ab4b1 (patch) | |
tree | 19d9fd511f8b376879a40bbb660707847979953c | |
parent | 7782d19cdccfd8cefebec7e665aff27463b00ec1 (diff) |
radeon/llvm: Handle ELF formatted binary output from the LLVM backend
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/LLVM_REVISION.txt | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/Makefile.am | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_llvm_emit.cpp | 38 |
4 files changed, 40 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac index 55ebb075626..e5651329151 100644 --- a/configure.ac +++ b/configure.ac @@ -1781,6 +1781,8 @@ radeon_llvm_check() { fi LLVM_COMPONENTS="${LLVM_COMPONENTS} r600 bitreader" NEED_RADEON_LLVM=yes + AC_CHECK_LIB([elf], [elf_memory], [ELF_LIB=-lelf], + [AC_MSG_ERROR([radeonsi and r600g require libelf when using LLVM])]) } dnl Gallium drivers @@ -1999,6 +2001,7 @@ AM_CONDITIONAL(HAVE_MESA_LLVM, test x$MESA_LLVM = x1) AM_CONDITIONAL(LLVM_NEEDS_FNORTTI, test $LLVM_VERSION_INT -ge 302) AC_SUBST([GALLIUM_MAKE_DIRS]) +AC_SUBST([ELF_LIB]) AM_CONDITIONAL(NEED_LIBPROGRAM, test "x$with_gallium_drivers" != x -o \ "x$enable_xlib_glx" = xyes -o \ diff --git a/src/gallium/drivers/radeon/LLVM_REVISION.txt b/src/gallium/drivers/radeon/LLVM_REVISION.txt index e5e7b653fb7..f086d34bbca 100644 --- a/src/gallium/drivers/radeon/LLVM_REVISION.txt +++ b/src/gallium/drivers/radeon/LLVM_REVISION.txt @@ -1 +1 @@ -@179164 +@179544 diff --git a/src/gallium/drivers/radeon/Makefile.am b/src/gallium/drivers/radeon/Makefile.am index 4a39514bec3..6522598b8b7 100644 --- a/src/gallium/drivers/radeon/Makefile.am +++ b/src/gallium/drivers/radeon/Makefile.am @@ -41,6 +41,7 @@ libllvmradeon@VERSION@_la_SOURCES = \ libllvmradeon@VERSION@_la_LIBADD = \ $(LIBGALLIUM_LIBS) \ $(CLOCK_LIB) \ - $(LLVM_LIBS) + $(LLVM_LIBS) \ + $(ELF_LIB) endif diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.cpp b/src/gallium/drivers/radeon/radeon_llvm_emit.cpp index 9c5fd78f1e1..d2dc035dc6b 100644 --- a/src/gallium/drivers/radeon/radeon_llvm_emit.cpp +++ b/src/gallium/drivers/radeon/radeon_llvm_emit.cpp @@ -52,6 +52,8 @@ #include <iostream> #include <stdlib.h> #include <stdio.h> +#include <libelf.h> +#include <gelf.h> using namespace llvm; @@ -154,10 +156,38 @@ radeon_llvm_compile(LLVMModuleRef M, struct radeon_llvm_binary *binary, out.flush(); std::string &data = oStream.str(); - - binary->code = (unsigned char*)malloc(data.length() * sizeof(unsigned char)); - memcpy(binary->code, data.c_str(), data.length() * sizeof(unsigned char)); - binary->code_size = data.length(); + char *elf_buffer; + + elf_buffer = (char*)malloc(data.length()); + memcpy(elf_buffer, data.c_str(), data.length()); + + Elf *elf = elf_memory(elf_buffer, data.length()); + Elf_Scn *section = NULL; + size_t section_str_index; + + elf_getshdrstrndx(elf, §ion_str_index); + + 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 = (unsigned char*)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 = (unsigned char*)malloc(binary->config_size * sizeof(unsigned char)); + memcpy(binary->config, section_data->d_buf, binary->config_size); + } + } return 0; } |