aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2013-04-04 13:02:51 -0700
committerTom Stellard <[email protected]>2013-04-15 10:54:29 -0700
commit9277b04c02de1e7a89b65839d8f4f717163ab4b1 (patch)
tree19d9fd511f8b376879a40bbb660707847979953c /src
parent7782d19cdccfd8cefebec7e665aff27463b00ec1 (diff)
radeon/llvm: Handle ELF formatted binary output from the LLVM backend
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeon/LLVM_REVISION.txt2
-rw-r--r--src/gallium/drivers/radeon/Makefile.am3
-rw-r--r--src/gallium/drivers/radeon/radeon_llvm_emit.cpp38
3 files changed, 37 insertions, 6 deletions
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, &section_str_index);
+
+ while ((section = elf_nextscn(elf, section))) {
+ const char *name;
+ Elf_Data *section_data = NULL;
+ GElf_Shdr section_header;
+ if (gelf_getshdr(section, &section_header) != &section_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;
}