[Openmp-commits] [openmp] 30efb45 - [Libomptarget] Remove use of ELF link_address in x86_64 plugin

Joseph Huber via Openmp-commits openmp-commits at lists.llvm.org
Wed Aug 24 08:46:36 PDT 2022


Author: Joseph Huber
Date: 2022-08-24T10:46:20-05:00
New Revision: 30efb459e0a50139dab287c77bc975aadb18cd1d

URL: https://github.com/llvm/llvm-project/commit/30efb459e0a50139dab287c77bc975aadb18cd1d
DIFF: https://github.com/llvm/llvm-project/commit/30efb459e0a50139dab287c77bc975aadb18cd1d.diff

LOG: [Libomptarget] Remove use of ELF link_address in x86_64 plugin

We use the offloading entires array to determine the relative names and
addressed of device-side kernel functions. The x86_64 plugin previously
derived the device-side entry table by first identifying the
`omp_offloading_entries` section offset in the loaded elf. Then we would
use the base offset of the loaded dyanmic library to identify the
entries array within the loaded image. This relied on some more
unconventional methods which prevented us from using the LLVM dynamic
library loader for this plugin. This patch simplifies this by instead
copying the host-side entry and replacing its address with the
device-side address looked up through `dlsym`.

Reviewed By: JonChesterfield

Differential Revision: https://reviews.llvm.org/D131516

Added: 
    

Modified: 
    openmp/libomptarget/plugins/generic-elf-64bit/src/rtl.cpp

Removed: 
    


################################################################################
diff  --git a/openmp/libomptarget/plugins/generic-elf-64bit/src/rtl.cpp b/openmp/libomptarget/plugins/generic-elf-64bit/src/rtl.cpp
index 98b138b47d3a6..0013db35089f3 100644
--- a/openmp/libomptarget/plugins/generic-elf-64bit/src/rtl.cpp
+++ b/openmp/libomptarget/plugins/generic-elf-64bit/src/rtl.cpp
@@ -10,6 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/SmallVector.h"
+
 #include <cassert>
 #include <cstdio>
 #include <cstdlib>
@@ -25,6 +27,8 @@
 #include "Debug.h"
 #include "omptargetplugin.h"
 
+using namespace llvm;
+
 #ifndef TARGET_NAME
 #define TARGET_NAME Generic ELF - 64bit
 #endif
@@ -48,6 +52,7 @@ struct DynLibTy {
 /// Keep entries table per device.
 struct FuncOrGblEntryTy {
   __tgt_target_table Table;
+  SmallVector<__tgt_offload_entry> Entries;
 };
 
 /// Class containing all the device information.
@@ -58,15 +63,16 @@ class RTLDeviceInfoTy {
   std::list<DynLibTy> DynLibs;
 
   // Record entry point associated with device.
-  void createOffloadTable(int32_t DeviceId, __tgt_offload_entry *Begin,
-                          __tgt_offload_entry *End) {
+  void createOffloadTable(int32_t DeviceId,
+                          SmallVector<__tgt_offload_entry> &&Entries) {
     assert(DeviceId < (int32_t)FuncGblEntries.size() &&
            "Unexpected device id!");
     FuncGblEntries[DeviceId].emplace_back();
     FuncOrGblEntryTy &E = FuncGblEntries[DeviceId].back();
 
-    E.Table.EntriesBegin = Begin;
-    E.Table.EntriesEnd = End;
+    E.Entries = Entries;
+    E.Table.EntriesBegin = E.Entries.begin();
+    E.Table.EntriesEnd = E.Entries.end();
   }
 
   // Return true if the entry is associated with device.
@@ -138,55 +144,6 @@ __tgt_target_table *__tgt_rtl_load_binary(int32_t DeviceId,
   size_t NumEntries = (size_t)(Image->EntriesEnd - Image->EntriesBegin);
   DP("Expecting to have %zd entries defined.\n", NumEntries);
 
-  // Is the library version incompatible with the header file?
-  if (elf_version(EV_CURRENT) == EV_NONE) {
-    DP("Incompatible ELF library!\n");
-    return NULL;
-  }
-
-  // Obtain elf handler
-  Elf *E = elf_memory((char *)Image->ImageStart, ImageSize);
-  if (!E) {
-    DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
-    return NULL;
-  }
-
-  if (elf_kind(E) != ELF_K_ELF) {
-    DP("Invalid Elf kind!\n");
-    elf_end(E);
-    return NULL;
-  }
-
-  // Find the entries section offset
-  Elf_Scn *Section = 0;
-  Elf64_Off EntriesOffset = 0;
-
-  size_t Shstrndx;
-
-  if (elf_getshdrstrndx(E, &Shstrndx)) {
-    DP("Unable to get ELF strings index!\n");
-    elf_end(E);
-    return NULL;
-  }
-
-  while ((Section = elf_nextscn(E, Section))) {
-    GElf_Shdr Hdr;
-    gelf_getshdr(Section, &Hdr);
-
-    if (!strcmp(elf_strptr(E, Shstrndx, Hdr.sh_name), OFFLOADSECTIONNAME)) {
-      EntriesOffset = Hdr.sh_addr;
-      break;
-    }
-  }
-
-  if (!EntriesOffset) {
-    DP("Entries Section Offset Not Found\n");
-    elf_end(E);
-    return NULL;
-  }
-
-  DP("Offset of entries section is (" DPxMOD ").\n", DPxPTR(EntriesOffset));
-
   // load dynamic library and get the entry points. We use the dl library
   // to do the loading of the library, but we could do it directly to avoid the
   // dump to the temporary file.
@@ -196,17 +153,13 @@ __tgt_target_table *__tgt_rtl_load_binary(int32_t DeviceId,
   char TmpName[] = "/tmp/tmpfile_XXXXXX";
   int TmpFd = mkstemp(TmpName);
 
-  if (TmpFd == -1) {
-    elf_end(E);
-    return NULL;
-  }
+  if (TmpFd == -1)
+    return nullptr;
 
   FILE *Ftmp = fdopen(TmpFd, "wb");
 
-  if (!Ftmp) {
-    elf_end(E);
-    return NULL;
-  }
+  if (!Ftmp)
+    return nullptr;
 
   fwrite(Image->ImageStart, ImageSize, 1, Ftmp);
   fclose(Ftmp);
@@ -215,38 +168,32 @@ __tgt_target_table *__tgt_rtl_load_binary(int32_t DeviceId,
 
   if (!Lib.Handle) {
     DP("Target library loading error: %s\n", dlerror());
-    elf_end(E);
     return NULL;
   }
 
   DeviceInfo.DynLibs.push_back(Lib);
 
-  struct link_map *LibInfo = (struct link_map *)Lib.Handle;
+  __tgt_offload_entry *HostBegin = Image->EntriesBegin;
+  __tgt_offload_entry *HostEnd = Image->EntriesEnd;
 
-  // The place where the entries info is loaded is the library base address
-  // plus the offset determined from the ELF file.
-  Elf64_Addr EntriesAddr = LibInfo->l_addr + EntriesOffset;
+  // Create a new offloading entry list using the device symbol address.
+  SmallVector<__tgt_offload_entry> Entries;
+  for (__tgt_offload_entry *E = HostBegin; E != HostEnd; ++E) {
+    if (!E->addr)
+      return nullptr;
 
-  DP("Pointer to first entry to be loaded is (" DPxMOD ").\n",
-     DPxPTR(EntriesAddr));
+    __tgt_offload_entry Entry = *E;
 
-  // Table of pointers to all the entries in the target.
-  __tgt_offload_entry *EntriesTable = (__tgt_offload_entry *)EntriesAddr;
+    void *DevAddr = dlsym(Lib.Handle, E->name);
+    Entry.addr = DevAddr;
 
-  __tgt_offload_entry *EntriesBegin = &EntriesTable[0];
-  __tgt_offload_entry *EntriesEnd = EntriesBegin + NumEntries;
+    DP("Entry point " DPxMOD " maps to global %s (" DPxMOD ")\n",
+       DPxPTR(E - HostBegin), E->name, DPxPTR(DevAddr));
 
-  if (!EntriesBegin) {
-    DP("Can't obtain entries begin\n");
-    elf_end(E);
-    return NULL;
+    Entries.emplace_back(Entry);
   }
 
-  DP("Entries table range is (" DPxMOD ")->(" DPxMOD ")\n",
-     DPxPTR(EntriesBegin), DPxPTR(EntriesEnd));
-  DeviceInfo.createOffloadTable(DeviceId, EntriesBegin, EntriesEnd);
-
-  elf_end(E);
+  DeviceInfo.createOffloadTable(DeviceId, std::move(Entries));
 
   return DeviceInfo.getOffloadEntriesTable(DeviceId);
 }


        


More information about the Openmp-commits mailing list