[OpenMP][libomptarget] Allow overriding function that gets ELF symbol info
authorKevin Sala <kevin.sala@bsc.es>
Wed, 23 Nov 2022 21:15:14 +0000 (22:15 +0100)
committerKevin Sala <kevin.sala@bsc.es>
Sat, 3 Dec 2022 20:51:09 +0000 (21:51 +0100)
The OpenMP target's NextGen plugins retrieve symbol information in the ELF image
(i.e., address and size) through the ELF section and ELF symbol objects. However,
the images of CUDA programs compute the address differently from the images of
AMDGPU programs:

  - Address for CUDA symbols: image begin + section's offset + symbol's st_value
  - Address for AMDGPU symbols: image + begin + symbol's st_value

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

openmp/libomptarget/plugins-nextgen/common/PluginInterface/GlobalHandler.cpp
openmp/libomptarget/plugins-nextgen/common/PluginInterface/GlobalHandler.h

index 14e0532..79e2ba5 100644 (file)
@@ -46,6 +46,21 @@ GenericGlobalHandlerTy::getOrCreateELFObjectFile(const GenericDeviceTy &Device,
   return &Result.first->second;
 }
 
+Error GenericGlobalHandlerTy::getGlobalMetadataFromELF(
+    const DeviceImageTy &Image, const ELF64LE::Sym &Symbol,
+    const ELF64LE::Shdr &Section, GlobalTy &ImageGlobal) {
+
+  // The global's address is computed as the image begin + the ELF section
+  // offset + the ELF symbol value.
+  ImageGlobal.setPtr((char *)Image.getStart() + Section.sh_offset +
+                     Symbol.st_value);
+
+  // Set the global's size.
+  ImageGlobal.setSize(Symbol.st_size);
+
+  return Plugin::success();
+}
+
 Error GenericGlobalHandlerTy::moveGlobalBetweenDeviceAndHost(
     GenericDeviceTy &Device, DeviceImageTy &Image, const GlobalTy &HostGlobal,
     bool Device2Host) {
@@ -111,19 +126,14 @@ Error GenericGlobalHandlerTy::getGlobalMetadataFromImage(
                          ImageGlobal.getName().data());
 
   // Get the section to which the symbol belongs.
-  auto SymSecOrErr = ELFObj->getELFFile().getSection((*SymOrErr)->st_shndx);
-  if (!SymSecOrErr)
+  auto SecOrErr = ELFObj->getELFFile().getSection((*SymOrErr)->st_shndx);
+  if (!SecOrErr)
     return Plugin::error("Failed to get ELF section from global '%s': %s",
                          ImageGlobal.getName().data(),
-                         toString(SymOrErr.takeError()).data());
+                         toString(SecOrErr.takeError()).data());
 
-  // Save the global symbol's address and size. The address of the global is the
-  // image base address + the section offset + the symbol value.
-  ImageGlobal.setPtr((char *)Image.getStart() + (*SymSecOrErr)->sh_offset +
-                     (*SymOrErr)->st_value);
-  ImageGlobal.setSize((*SymOrErr)->st_size);
-
-  return Plugin::success();
+  // Setup the global symbol's address and size.
+  return getGlobalMetadataFromELF(Image, **SymOrErr, **SecOrErr, ImageGlobal);
 }
 
 Error GenericGlobalHandlerTy::readGlobalFromImage(GenericDeviceTy &Device,
index e93ade0..77eb6e3 100644 (file)
@@ -96,6 +96,12 @@ class GenericGlobalHandlerTy {
   const ELF64LEObjectFile *
   getOrCreateELFObjectFile(const GenericDeviceTy &Device, DeviceImageTy &Image);
 
+  /// Extract the global's information from the ELF image, section, and symbol.
+  virtual Error getGlobalMetadataFromELF(const DeviceImageTy &Image,
+                                         const ELF64LE::Sym &Symbol,
+                                         const ELF64LE::Shdr &Section,
+                                         GlobalTy &ImageGlobal);
+
   /// Actually move memory between host and device. See readGlobalFromDevice and
   /// writeGlobalToDevice for the interface description.
   Error moveGlobalBetweenDeviceAndHost(GenericDeviceTy &Device,