[Libomptarget] Replace libelf with LLVM's Elf libraries
authorJoseph Huber <jhuber6@vols.utk.edu>
Fri, 5 Aug 2022 18:32:42 +0000 (14:32 -0400)
committerJoseph Huber <jhuber6@vols.utk.edu>
Wed, 7 Sep 2022 17:38:51 +0000 (12:38 -0500)
This patch replaces the dependency on `libelf` with LLVM's ELF support.
With this patch the user no-longer needs to have `libelf` on their
system to build and configure OpenMP offloading. The replacement is
mostly mechanical, with the exception of the hash table support which
was added in D131309.

Depends on D131309

Reviewed By: JonChesterfield, saiislam

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

openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake
openmp/libomptarget/plugins/CMakeLists.txt
openmp/libomptarget/plugins/amdgpu/CMakeLists.txt
openmp/libomptarget/plugins/amdgpu/impl/system.cpp
openmp/libomptarget/plugins/amdgpu/src/rtl.cpp
openmp/libomptarget/plugins/cuda/CMakeLists.txt
openmp/libomptarget/plugins/generic-elf-64bit/src/rtl.cpp
openmp/libomptarget/plugins/ve/CMakeLists.txt

index 1f2a506..60aa9e4 100644 (file)
@@ -11,7 +11,6 @@
 # Try to detect in the system several dependencies required by the different
 # components of libomptarget. These are the dependencies we have:
 #
-# libelf : required by some targets to handle the ELF files at runtime.
 # libffi : required to launch target kernels given function and argument
 #          pointers.
 # CUDA : required to control offloading to NVIDIA GPUs.
@@ -50,46 +49,6 @@ else()
 endif()
 
 ################################################################################
-# Looking for libelf...
-################################################################################
-
-find_path (
-  LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR
-  NAMES
-    libelf.h
-  PATHS
-    /usr/include
-    /usr/local/include
-    /opt/local/include
-    /sw/include
-    ENV CPATH
-  PATH_SUFFIXES
-    libelf)
-
-find_library (
-  LIBOMPTARGET_DEP_LIBELF_LIBRARIES
-  NAMES
-    elf
-  PATHS
-    /usr/lib
-    /usr/local/lib
-    /opt/local/lib
-    /sw/lib
-    ENV LIBRARY_PATH
-    ENV LD_LIBRARY_PATH)
-
-set(LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR})
-find_package_handle_standard_args(
-  LIBOMPTARGET_DEP_LIBELF
-  DEFAULT_MSG
-  LIBOMPTARGET_DEP_LIBELF_LIBRARIES
-  LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS)
-
-mark_as_advanced(
-  LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS
-  LIBOMPTARGET_DEP_LIBELF_LIBRARIES)
-
-################################################################################
 # Looking for libffi...
 ################################################################################
 find_package(PkgConfig)
index d433340..8ec24b5 100644 (file)
@@ -19,66 +19,59 @@ add_subdirectory(common)
 # - tmachine_libname: machine name to be appended to the plugin library name.
 macro(build_generic_elf64 tmachine tmachine_name tmachine_libname tmachine_triple elf_machine_id)
 if(CMAKE_SYSTEM_PROCESSOR MATCHES "${tmachine}$")
-  if(LIBOMPTARGET_DEP_LIBELF_FOUND)
-    if(LIBOMPTARGET_DEP_LIBFFI_FOUND)
+  if(LIBOMPTARGET_DEP_LIBFFI_FOUND)
 
-      libomptarget_say("Building ${tmachine_name} offloading plugin.")
+    libomptarget_say("Building ${tmachine_name} offloading plugin.")
 
-      # Define macro to be used as prefix of the runtime messages for this target.
-      add_definitions("-DTARGET_NAME=${tmachine_name}")
+    # Define macro to be used as prefix of the runtime messages for this target.
+    add_definitions("-DTARGET_NAME=${tmachine_name}")
 
-      # Define macro with the ELF ID for this target.
-      add_definitions("-DTARGET_ELF_ID=${elf_machine_id}")
+    # Define macro with the ELF ID for this target.
+    add_definitions("-DTARGET_ELF_ID=${elf_machine_id}")
 
-      add_llvm_library("omptarget.rtl.${tmachine_libname}"
-        SHARED
+    add_llvm_library("omptarget.rtl.${tmachine_libname}"
+      SHARED
 
-        ${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/src/rtl.cpp
+      ${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/src/rtl.cpp
 
-        ADDITIONAL_HEADER_DIRS
-        ${LIBOMPTARGET_INCLUDE_DIR}
-        ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR}
-        ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR}
+      ADDITIONAL_HEADER_DIRS
+      ${LIBOMPTARGET_INCLUDE_DIR}
+      ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR}
 
         LINK_LIBS 
         PRIVATE
         elf_common
         ${LIBOMPTARGET_DEP_LIBFFI_LIBRARIES}
-        ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
         ${OPENMP_PTHREAD_LIB}
         "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports"
 
-        NO_INSTALL_RPATH
-      )
-
-      # Install plugin under the lib destination folder.
-      install(TARGETS "omptarget.rtl.${tmachine_libname}"
-        LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}")
-      set_target_properties("omptarget.rtl.${tmachine_libname}" PROPERTIES 
-        INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
-
-      target_include_directories( "omptarget.rtl.${tmachine_libname}" PRIVATE
-        ${LIBOMPTARGET_INCLUDE_DIR}
-        ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR}
-        ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR})
-
-      list(APPEND LIBOMPTARGET_TESTED_PLUGINS
-        "omptarget.rtl.${tmachine_libname}")
-
-      # Report to the parent scope that we are building a plugin.
-      set(LIBOMPTARGET_SYSTEM_TARGETS
-        "${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple} ${tmachine_triple}-oldDriver" PARENT_SCOPE)
-      set(LIBOMPTARGET_SYSTEM_TARGETS
-        "${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple} ${tmachine_triple}-LTO" PARENT_SCOPE)
-      set(LIBOMPTARGET_TESTED_PLUGINS
-        "${LIBOMPTARGET_TESTED_PLUGINS}" PARENT_SCOPE)
-
-    else(LIBOMPTARGET_DEP_LIBFFI_FOUND)
-      libomptarget_say("Not building ${tmachine_name} offloading plugin: libffi dependency not found.")
-    endif(LIBOMPTARGET_DEP_LIBFFI_FOUND)
-  else(LIBOMPTARGET_DEP_LIBELF_FOUND)
-    libomptarget_say("Not building ${tmachine_name} offloading plugin: libelf dependency not found.")
-  endif(LIBOMPTARGET_DEP_LIBELF_FOUND)
+      NO_INSTALL_RPATH
+    )
+
+    # Install plugin under the lib destination folder.
+    install(TARGETS "omptarget.rtl.${tmachine_libname}"
+      LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}")
+    set_target_properties("omptarget.rtl.${tmachine_libname}" PROPERTIES
+      INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
+
+    target_include_directories( "omptarget.rtl.${tmachine_libname}" PRIVATE
+      ${LIBOMPTARGET_INCLUDE_DIR}
+      ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR})
+
+    list(APPEND LIBOMPTARGET_TESTED_PLUGINS
+      "omptarget.rtl.${tmachine_libname}")
+
+    # Report to the parent scope that we are building a plugin.
+    set(LIBOMPTARGET_SYSTEM_TARGETS
+      "${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple} ${tmachine_triple}-oldDriver" PARENT_SCOPE)
+    set(LIBOMPTARGET_SYSTEM_TARGETS
+      "${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple} ${tmachine_triple}-LTO" PARENT_SCOPE)
+    set(LIBOMPTARGET_TESTED_PLUGINS
+      "${LIBOMPTARGET_TESTED_PLUGINS}" PARENT_SCOPE)
+
+  else(LIBOMPTARGET_DEP_LIBFFI_FOUND)
+    libomptarget_say("Not building ${tmachine_name} offloading plugin: libffi dependency not found.")
+  endif(LIBOMPTARGET_DEP_LIBFFI_FOUND)
 else()
   libomptarget_say("Not building ${tmachine_name} offloading plugin: machine not found in the system.")
 endif()
index 9f7247e..3e70dea 100644 (file)
@@ -22,11 +22,6 @@ endif()
 # as of rocm-3.7, hsa is installed with cmake packages and kmt is found via hsa
 find_package(hsa-runtime64 QUIET 1.2.0 HINTS ${CMAKE_INSTALL_PREFIX} PATHS /opt/rocm)
 
-if(NOT LIBOMPTARGET_DEP_LIBELF_FOUND)
-  libomptarget_say("Not building AMDGPU plugin: LIBELF not found")
-  return()
-endif()
-
 if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(ppc64le)|(aarch64)$" AND CMAKE_SYSTEM_NAME MATCHES "Linux")
   libomptarget_say("Not building AMDGPU plugin: only support AMDGPU in Linux x86_64, ppc64le, or aarch64 hosts")
   return()
@@ -84,7 +79,6 @@ add_llvm_library(omptarget.rtl.amdgpu SHARED
   PRIVATE
   elf_common
   ${LIBOMPTARGET_DEP_LIBRARIES}
-  ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
   ${OPENMP_PTHREAD_LIB}
   "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports"
   ${LDFLAGS_UNDEFINED}
index 5e44237..e8dba47 100644 (file)
@@ -5,7 +5,11 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#include <libelf.h>
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELFObjectFile.h"
 
 #include <cassert>
 #include <sstream>
 
 #include "msgpack.h"
 
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::ELF;
+
 namespace hsa {
 // Wrap HSA iterate API in a shim that allows passing general callables
 template <typename C>
@@ -162,66 +170,62 @@ static bool isImplicit(KernelArgMD::ValueKind value_kind) {
   }
 }
 
-static std::pair<unsigned char *, unsigned char *>
-find_metadata(void *binary, size_t binSize) {
-  std::pair<unsigned char *, unsigned char *> failure = {nullptr, nullptr};
-
-  Elf *e = elf_memory(static_cast<char *>(binary), binSize);
-  if (elf_kind(e) != ELF_K_ELF) {
-    return failure;
+static std::pair<const unsigned char *, const unsigned char *>
+findMetadata(const ELFObjectFile<ELF64LE> &ELFObj) {
+  constexpr std::pair<const unsigned char *, const unsigned char *> Failure = {
+      nullptr, nullptr};
+  const auto &Elf = ELFObj.getELFFile();
+  auto PhdrsOrErr = Elf.program_headers();
+  if (!PhdrsOrErr) {
+    consumeError(PhdrsOrErr.takeError());
+    return Failure;
   }
 
-  size_t numpHdrs;
-  if (elf_getphdrnum(e, &numpHdrs) != 0) {
-    return failure;
-  }
+  for (auto Phdr : *PhdrsOrErr) {
+    if (Phdr.p_type != PT_NOTE)
+      continue;
 
-  Elf64_Phdr *pHdrs = elf64_getphdr(e);
-  for (size_t i = 0; i < numpHdrs; ++i) {
-    Elf64_Phdr pHdr = pHdrs[i];
-
-    // Look for the runtime metadata note
-    if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) {
-      // Iterate over the notes in this segment
-      address ptr = (address)binary + pHdr.p_offset;
-      address segmentEnd = ptr + pHdr.p_filesz;
-
-      while (ptr < segmentEnd) {
-        Elf_Note *note = reinterpret_cast<Elf_Note *>(ptr);
-        address name = (address)&note[1];
-
-        if (note->n_type == 7 || note->n_type == 8) {
-          return failure;
-        } else if (note->n_type == 10 /* NT_AMD_AMDGPU_HSA_METADATA */ &&
-                   note->n_namesz == sizeof "AMD" &&
-                   !memcmp(name, "AMD", note->n_namesz)) {
-          // code object v2 uses yaml metadata, no longer supported
-          return failure;
-        } else if (note->n_type == 32 /* NT_AMDGPU_METADATA */ &&
-                   note->n_namesz == sizeof "AMDGPU" &&
-                   !memcmp(name, "AMDGPU", note->n_namesz)) {
-
-          // n_descsz = 485
-          // value is padded to 4 byte alignment, may want to move end up to
-          // match
-          size_t offset = sizeof(uint32_t) * 3 /* fields */
-                          + sizeof("AMDGPU")   /* name */
-                          + 1 /* padding to 4 byte alignment */;
-
-          // Including the trailing padding means both pointers are 4 bytes
-          // aligned, which may be useful later.
-          unsigned char *metadata_start = (unsigned char *)ptr + offset;
-          unsigned char *metadata_end =
-              metadata_start + core::alignUp(note->n_descsz, 4);
-          return {metadata_start, metadata_end};
-        }
-        ptr += sizeof(*note) + core::alignUp(note->n_namesz, sizeof(int)) +
-               core::alignUp(note->n_descsz, sizeof(int));
-      }
+    Error Err = Error::success();
+    for (auto Note : Elf.notes(Phdr, Err)) {
+      if (Note.getType() == 7 || Note.getType() == 8)
+        return Failure;
+
+      // Code object v2 uses yaml metadata and is no longer supported.
+      if (Note.getType() == NT_AMD_HSA_METADATA && Note.getName() == "AMD")
+        return Failure;
+      // Code object v3 should have AMDGPU metadata.
+      if (Note.getType() == NT_AMDGPU_METADATA && Note.getName() != "AMDGPU")
+        return Failure;
+
+      ArrayRef<uint8_t> Desc = Note.getDesc();
+      return {Desc.data(), Desc.data() + Desc.size()};
+    }
+
+    if (Err) {
+      consumeError(std::move(Err));
+      return Failure;
     }
   }
 
-  return failure;
+  return Failure;
+}
+
+static std::pair<const unsigned char *, const unsigned char *>
+find_metadata(void *binary, size_t binSize) {
+  constexpr std::pair<const unsigned char *, const unsigned char *> Failure = {
+      nullptr, nullptr};
+
+  StringRef Buffer = StringRef(static_cast<const char *>(binary), binSize);
+  auto ElfOrErr = ObjectFile::createELFObjectFile(MemoryBufferRef(Buffer, ""),
+                                                  /*InitContent=*/false);
+  if (!ElfOrErr) {
+    consumeError(ElfOrErr.takeError());
+    return Failure;
+  }
+
+  if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(ElfOrErr->get()))
+    return findMetadata(*ELFObj);
+  return Failure;
 }
 
 namespace {
@@ -337,7 +341,7 @@ static hsa_status_t get_code_object_custom_metadata(
   // also, the kernel name is not the same as the symbol name -- so a
   // symbol->name map is needed
 
-  std::pair<unsigned char *, unsigned char *> metadata =
+  std::pair<const unsigned char *, const unsigned char *> metadata =
       find_metadata(binary, binSize);
   if (!metadata.first) {
     return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;
index b0e48d2..da73871 100644 (file)
@@ -23,7 +23,6 @@
 #include <cstdlib>
 #include <cstring>
 #include <functional>
-#include <libelf.h>
 #include <list>
 #include <memory>
 #include <mutex>
@@ -45,6 +44,7 @@
 
 using namespace llvm;
 using namespace llvm::object;
+using namespace llvm::ELF;
 
 // hostrpc interface, FIXME: consider moving to its own include these are
 // statically linked into amdgpu/plugin if present from hostrpc_services.a,
@@ -1563,8 +1563,8 @@ int32_t runRegionLocked(int32_t DeviceId, void *TgtEntryPtr, void **TgtArgs,
 }
 
 bool elfMachineIdIsAmdgcn(__tgt_device_image *Image) {
-  const uint16_t AmdgcnMachineID = 224; // EM_AMDGPU may not be in system elf.h
-  int32_t R = elf_check_machine(Image, AmdgcnMachineID);
+  const uint16_t AmdgcnMachineID = EM_AMDGPU;
+  const int32_t R = elf_check_machine(Image, AmdgcnMachineID);
   if (!R) {
     DP("Supported machine ID not found\n");
   }
@@ -1572,28 +1572,20 @@ bool elfMachineIdIsAmdgcn(__tgt_device_image *Image) {
 }
 
 uint32_t elfEFlags(__tgt_device_image *Image) {
-  char *ImgBegin = (char *)Image->ImageStart;
+  const char *ImgBegin = (char *)Image->ImageStart;
   size_t ImgSize = (char *)Image->ImageEnd - ImgBegin;
 
-  Elf *E = elf_memory(ImgBegin, ImgSize);
-  if (!E) {
-    DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
-    return 0;
-  }
-
-  Elf64_Ehdr *Eh64 = elf64_getehdr(E);
-
-  if (!Eh64) {
-    DP("Unable to get machine ID from ELF file!\n");
-    elf_end(E);
+  StringRef Buffer = StringRef(ImgBegin, ImgSize);
+  auto ElfOrErr = ObjectFile::createELFObjectFile(MemoryBufferRef(Buffer, ""),
+                                                  /*InitContent=*/false);
+  if (!ElfOrErr) {
+    consumeError(ElfOrErr.takeError());
     return 0;
   }
 
-  uint32_t Flags = Eh64->e_flags;
-
-  elf_end(E);
-  DP("ELF Flags: 0x%x\n", Flags);
-  return Flags;
+  if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(ElfOrErr->get()))
+    return ELFObj->getPlatformFlags();
+  return 0;
 }
 
 template <typename T> bool enforceUpperBound(T *Value, T Upper) {
index a589aca..505c093 100644 (file)
@@ -19,9 +19,6 @@ endif()
 if (NOT(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(ppc64le)|(aarch64)$" AND CMAKE_SYSTEM_NAME MATCHES "Linux"))
   libomptarget_say("Not building CUDA offloading plugin: only support CUDA in Linux x86_64, ppc64le, or aarch64 hosts.")
   return()
-elseif (NOT LIBOMPTARGET_DEP_LIBELF_FOUND)
-  libomptarget_say("Not building CUDA offloading plugin: libelf dependency not found.")
-  return()
 endif()
 
 libomptarget_say("Building CUDA offloading plugin.")
@@ -46,14 +43,12 @@ if (LIBOMPTARGET_CAN_LINK_LIBCUDA AND NOT LIBOMPTARGET_FORCE_DLOPEN_LIBCUDA)
 
     ADDITIONAL_HEADER_DIRS
     ${LIBOMPTARGET_INCLUDE_DIR}
-    ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS}
 
     LINK_LIBS
     PRIVATE
     elf_common
     MemoryManager
     ${LIBOMPTARGET_DEP_CUDA_DRIVER_LIBRARIES}
-    ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
     ${OPENMP_PTHREAD_LIB}
     "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports"
     "-Wl,-z,defs"
@@ -71,13 +66,11 @@ else()
 
     ADDITIONAL_HEADER_DIRS
     ${LIBOMPTARGET_INCLUDE_DIR}
-    ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS}
 
     LINK_LIBS
     PRIVATE
     elf_common
     MemoryManager
-    ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
     ${OPENMP_PTHREAD_LIB}
     "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports"
     "-Wl,-z,defs"
@@ -94,7 +87,6 @@ set_target_properties(omptarget.rtl.cuda PROPERTIES
 
 target_include_directories(omptarget.rtl.cuda PRIVATE
   ${LIBOMPTARGET_INCLUDE_DIR}
-  ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS}
 )
 
 # Report to the parent scope that we are building a plugin for CUDA.
index f19e4f0..e899888 100644 (file)
@@ -42,7 +42,7 @@ using namespace llvm::sys;
 #include "elf_common.h"
 
 #define NUMBER_OF_DEVICES 4
-#define OFFLOADSECTIONNAME "omp_offloading_entries"
+#define OFFLOAD_SECTION_NAME "omp_offloading_entries"
 
 /// Array of Dynamic libraries loaded for this target.
 struct DynLibTy {
@@ -141,7 +141,6 @@ __tgt_target_table *__tgt_rtl_load_binary(int32_t DeviceId,
 
   size_t ImageSize = (size_t)Image->ImageEnd - (size_t)Image->ImageStart;
   size_t NumEntries = (size_t)(Image->EntriesEnd - Image->EntriesBegin);
-  DP("Expecting to have %zd entries defined.\n", NumEntries);
 
   // 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
index 5aded32..ef2906f 100644 (file)
@@ -29,14 +29,12 @@ if(${LIBOMPTARGET_DEP_VEO_FOUND})
 
     ADDITIONAL_HEADER_DIRS
     ${LIBOMPTARGET_INCLUDE_DIR}
-    ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR}
     ${LIBOMPTARGET_DEP_VEO_INCLUDE_DIR}
 
     LINK_LIBS
     PRIVATE
     elf_common
     ${LIBOMPTARGET_DEP_LIBFFI_LIBRARIES}
-    ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
     ${additional_libs}
     "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports -Wl,-z,defs"
 
@@ -50,14 +48,12 @@ if(${LIBOMPTARGET_DEP_VEO_FOUND})
 
   target_include_directories("omptarget.rtl.${tmachine_libname}" PRIVATE
     ${LIBOMPTARGET_INCLUDE_DIR}
-    ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR}
     ${LIBOMPTARGET_DEP_VEO_INCLUDE_DIR})
 
   target_link_libraries(
     "omptarget.rtl.${tmachine_libname}"
     elf_common
     ${LIBOMPTARGET_DEP_LIBFFI_LIBRARIES}
-    ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
     ${additional_libs}
     "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports -Wl,-z,defs")