radeon/llvm: Handle ELF formatted binary output from the LLVM backend
authorTom Stellard <thomas.stellard@amd.com>
Thu, 4 Apr 2013 20:02:51 +0000 (13:02 -0700)
committerTom Stellard <thomas.stellard@amd.com>
Mon, 15 Apr 2013 17:54:29 +0000 (10:54 -0700)
configure.ac
src/gallium/drivers/radeon/LLVM_REVISION.txt
src/gallium/drivers/radeon/Makefile.am
src/gallium/drivers/radeon/radeon_llvm_emit.cpp

index 55ebb0756264be9a985fe66921db59ee3b03d65a..e56513291510e8d97f68513022280b818f797269 100644 (file)
@@ -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 \
index e5e7b653fb7d225aa32f7fcc294aef38fa535641..f086d34bbcaaeedbf88856944ef020b812430bcc 100644 (file)
@@ -1 +1 @@
-@179164
+@179544
index 4a39514bec3ad5c94b30c390ebbf6cca2f8d4013..6522598b8b7e6afbfb6966364ccf2d13faa8bc1e 100644 (file)
@@ -41,6 +41,7 @@ libllvmradeon@VERSION@_la_SOURCES = \
 libllvmradeon@VERSION@_la_LIBADD = \
        $(LIBGALLIUM_LIBS) \
        $(CLOCK_LIB) \
-       $(LLVM_LIBS)
+       $(LLVM_LIBS) \
+       $(ELF_LIB)
 
 endif
index 9c5fd78f1e15783d3ffc80e92f14fc7dbb20602f..d2dc035dc6bc539657c1edf34b2639eef7c09c8f 100644 (file)
@@ -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;
 }