[Mesa-dev] [PATCH 2/4] radeon/llvm: Handle ELF formatted binary output from the LLVM backend

Tom Stellard tom at stellard.net
Fri Apr 5 11:54:13 PDT 2013


From: Tom Stellard <thomas.stellard at amd.com>

---
 configure.ac                                    |  2 ++
 src/gallium/drivers/radeon/Makefile.am          |  3 +-
 src/gallium/drivers/radeon/radeon_llvm_emit.cpp | 38 ++++++++++++++++++++++---
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 81d4a3f..9e550e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1776,6 +1776,8 @@ radeon_llvm_check() {
     fi
     AC_MSG_WARN([Please ensure you use the latest llvm tree from git://people.freedesktop.org/~tstellar/llvm master before submitting a bug])
     LLVM_COMPONENTS="${LLVM_COMPONENTS} r600 bitreader"
+    AC_CHECK_LIB([elf], [elf_memory] [ELF_LIB=-lelf],
+                                 [AC_MSG_ERROR([radeonsi and r600g require libelf when using LLVM])])
 }
 
 dnl Gallium drivers
diff --git a/src/gallium/drivers/radeon/Makefile.am b/src/gallium/drivers/radeon/Makefile.am
index 140f6c6..f08561a 100644
--- a/src/gallium/drivers/radeon/Makefile.am
+++ b/src/gallium/drivers/radeon/Makefile.am
@@ -32,4 +32,5 @@ libllvmradeon at VERSION@_la_SOURCES = \
 libllvmradeon at VERSION@_la_LIBADD = \
 	$(LIBGALLIUM_LIBS) \
 	$(CLOCK_LIB) \
-	$(LLVM_LIBS)
+	$(LLVM_LIBS) \
+	$(ELF_LIB)
diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.cpp b/src/gallium/drivers/radeon/radeon_llvm_emit.cpp
index 9c5fd78..d2dc035 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;
 }
-- 
1.8.1.5



More information about the mesa-dev mailing list