[Openmp-commits] [openmp] b5c4fc0 - [NFC][libomptarget] Reduce the dependency on libelf

Vyacheslav Zakharin via Openmp-commits openmp-commits at lists.llvm.org
Wed Jun 16 08:34:46 PDT 2021


Author: Vyacheslav Zakharin
Date: 2021-06-16T08:34:23-07:00
New Revision: b5c4fc0f232b6368bbd7cd8681a6931f2c30ad02

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

LOG: [NFC][libomptarget] Reduce the dependency on libelf

This change-set removes libelf usage from elf_common part of the plugins.
libelf is still used in x86_64 generic plugin code and in some plugins
(e.g. amdgpu) - these will have to be cleaned up in separate checkins.

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

Added: 
    openmp/libomptarget/plugins/common/elf_common/elf_common.cpp

Modified: 
    openmp/libomptarget/plugins/amdgpu/CMakeLists.txt
    openmp/libomptarget/plugins/common/elf_common/CMakeLists.txt
    openmp/libomptarget/plugins/common/elf_common/elf_common.h
    openmp/libomptarget/plugins/remote/server/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/openmp/libomptarget/plugins/amdgpu/CMakeLists.txt b/openmp/libomptarget/plugins/amdgpu/CMakeLists.txt
index 64c436d9d8871..e41b86e21bbfe 100644
--- a/openmp/libomptarget/plugins/amdgpu/CMakeLists.txt
+++ b/openmp/libomptarget/plugins/amdgpu/CMakeLists.txt
@@ -75,7 +75,9 @@ target_link_libraries(
   PRIVATE
   elf_common
   hsa-runtime64::hsa-runtime64
-  pthread dl elf
+  dl
+  ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
+  ${OPENMP_PTHREAD_LIB}
   "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports"
   "-Wl,-z,defs"
   )

diff  --git a/openmp/libomptarget/plugins/common/elf_common/CMakeLists.txt b/openmp/libomptarget/plugins/common/elf_common/CMakeLists.txt
index 7cad0a0a1d1a0..de062b9b5fd6e 100644
--- a/openmp/libomptarget/plugins/common/elf_common/CMakeLists.txt
+++ b/openmp/libomptarget/plugins/common/elf_common/CMakeLists.txt
@@ -10,6 +10,15 @@
 #
 ##===----------------------------------------------------------------------===##
 
-add_library(elf_common INTERFACE)
+add_library(elf_common OBJECT elf_common.cpp)
 
+llvm_update_compile_flags(elf_common)
+set(LINK_LLVM_LIBS LLVMBinaryFormat LLVMObject LLVMSupport)
+target_link_libraries(elf_common INTERFACE ${LINK_LLVM_LIBS} ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES})
+add_dependencies(elf_common ${LINK_LLVM_LIBS})
+
+# The code uses Debug.h, which requires threads support.
+target_link_libraries(elf_common INTERFACE ${OPENMP_PTHREAD_LIB})
+
+# Expose elf_common.h directory to the users of this library.
 target_include_directories(elf_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

diff  --git a/openmp/libomptarget/plugins/common/elf_common/elf_common.cpp b/openmp/libomptarget/plugins/common/elf_common/elf_common.cpp
new file mode 100644
index 0000000000000..9bbd184490fc7
--- /dev/null
+++ b/openmp/libomptarget/plugins/common/elf_common/elf_common.cpp
@@ -0,0 +1,88 @@
+//===-- elf_common.cpp - Common ELF functionality -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Common ELF functionality for target plugins.
+//
+//===----------------------------------------------------------------------===//
+#include "elf_common.h"
+#include "Debug.h"
+
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#ifndef TARGET_NAME
+#define TARGET_NAME ELF Common
+#endif
+#define DEBUG_PREFIX "TARGET " GETNAME(TARGET_NAME)
+
+using namespace llvm;
+using namespace llvm::ELF;
+using namespace llvm::object;
+
+/// If the given range of bytes [\p BytesBegin, \p BytesEnd) represents
+/// a valid ELF, then invoke \p Callback on the ELFObjectFileBase
+/// created from this range, otherwise, return 0.
+/// If \p Callback is invoked, then return whatever value \p Callback returns.
+template <typename F>
+static int32_t withBytesAsElf(char *BytesBegin, char *BytesEnd, F Callback) {
+  size_t Size = BytesEnd - BytesBegin;
+  StringRef StrBuf(BytesBegin, Size);
+
+  auto Magic = identify_magic(StrBuf);
+  if (Magic != file_magic::elf && Magic != file_magic::elf_relocatable &&
+      Magic != file_magic::elf_executable &&
+      Magic != file_magic::elf_shared_object && Magic != file_magic::elf_core) {
+    DP("Not an ELF image!\n");
+    return 0;
+  }
+
+  std::unique_ptr<MemoryBuffer> MemBuf =
+      MemoryBuffer::getMemBuffer(StrBuf, "", false);
+  Expected<std::unique_ptr<ObjectFile>> BinOrErr =
+      ObjectFile::createELFObjectFile(MemBuf->getMemBufferRef(),
+                                      /*InitContent=*/false);
+  if (!BinOrErr) {
+    DP("Unable to get ELF handle: %s!\n",
+       toString(BinOrErr.takeError()).c_str());
+    return 0;
+  }
+
+  auto *Object = dyn_cast<const ELFObjectFileBase>(BinOrErr->get());
+
+  if (!Object) {
+    DP("Unknown ELF format!\n");
+    return 0;
+  }
+
+  return Callback(Object);
+}
+
+// Check whether an image is valid for execution on target_id
+int32_t elf_check_machine(__tgt_device_image *image, uint16_t target_id) {
+  auto CheckMachine = [target_id](const ELFObjectFileBase *Object) {
+    return target_id == Object->getEMachine();
+  };
+  return withBytesAsElf(reinterpret_cast<char *>(image->ImageStart),
+                        reinterpret_cast<char *>(image->ImageEnd),
+                        CheckMachine);
+}
+
+int32_t elf_is_dynamic(__tgt_device_image *image) {
+  auto CheckDynType = [](const ELFObjectFileBase *Object) {
+    uint16_t Type = Object->getEType();
+    DP("ELF Type: %d\n", Type);
+    return Type == ET_DYN;
+  };
+  return withBytesAsElf(reinterpret_cast<char *>(image->ImageStart),
+                        reinterpret_cast<char *>(image->ImageEnd),
+                        CheckDynType);
+}

diff  --git a/openmp/libomptarget/plugins/common/elf_common/elf_common.h b/openmp/libomptarget/plugins/common/elf_common/elf_common.h
index 75994238b58da..a342c19a42805 100644
--- a/openmp/libomptarget/plugins/common/elf_common/elf_common.h
+++ b/openmp/libomptarget/plugins/common/elf_common/elf_common.h
@@ -1,4 +1,4 @@
-//===-- elf_common.h - Common ELF functionality -------------------*- C -*-===//
+//===-- elf_common.h - Common ELF functionality -----------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,105 +7,21 @@
 //===----------------------------------------------------------------------===//
 //
 // Common ELF functionality for target plugins.
-// Must be included in the plugin source file AFTER omptarget.h has been
-// included and macro DP(...) has been defined.
-// .
 //
 //===----------------------------------------------------------------------===//
 
-#if !(defined(_OMPTARGET_DEBUG_H))
-#error Include elf_common.h in the plugin source AFTER Debug.h has\
- been included.
-#endif
+#ifndef LLVM_OPENMP_LIBOMPTARGET_PLUGINS_COMMON_ELF_COMMON_ELF_COMMON_H
+#define LLVM_OPENMP_LIBOMPTARGET_PLUGINS_COMMON_ELF_COMMON_ELF_COMMON_H
 
-#include <elf.h>
-#include <libelf.h>
+#include "omptargetplugin.h"
+#include <cstdint>
 
-// Check whether an image is valid for execution on target_id
-static inline int32_t elf_check_machine(__tgt_device_image *image,
-                                        uint16_t target_id) {
+/// Return non-zero, if the given \p image is an ELF object, which
+/// e_machine matches \p target_id; return zero otherwise.
+EXTERN int32_t elf_check_machine(__tgt_device_image *image, uint16_t target_id);
 
-  // Is the library version incompatible with the header file?
-  if (elf_version(EV_CURRENT) == EV_NONE) {
-    DP("Incompatible ELF library!\n");
-    return 0;
-  }
+/// Return non-zero, if the given \p image is an ET_DYN ELF object;
+/// return zero otherwise.
+EXTERN int32_t elf_is_dynamic(__tgt_device_image *image);
 
-  char *img_begin = (char *)image->ImageStart;
-  char *img_end = (char *)image->ImageEnd;
-  size_t img_size = img_end - img_begin;
-
-  // Obtain elf handler
-  Elf *e = elf_memory(img_begin, img_size);
-  if (!e) {
-    DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
-    return 0;
-  }
-
-  // Check if ELF is the right kind.
-  if (elf_kind(e) != ELF_K_ELF) {
-    DP("Unexpected ELF type!\n");
-    elf_end(e);
-    return 0;
-  }
-  Elf64_Ehdr *eh64 = elf64_getehdr(e);
-  Elf32_Ehdr *eh32 = elf32_getehdr(e);
-
-  if (!eh64 && !eh32) {
-    DP("Unable to get machine ID from ELF file!\n");
-    elf_end(e);
-    return 0;
-  }
-
-  uint16_t MachineID;
-  if (eh64 && !eh32)
-    MachineID = eh64->e_machine;
-  else if (eh32 && !eh64)
-    MachineID = eh32->e_machine;
-  else {
-    DP("Ambiguous ELF header!\n");
-    elf_end(e);
-    return 0;
-  }
-
-  elf_end(e);
-  return MachineID == target_id;
-}
-
-static inline int32_t elf_is_dynamic(__tgt_device_image *image) {
-
-  char *img_begin = (char *)image->ImageStart;
-  char *img_end = (char *)image->ImageEnd;
-  size_t img_size = img_end - img_begin;
-
-  // Obtain elf handler
-  Elf *e = elf_memory(img_begin, img_size);
-  if (!e) {
-    DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
-    return 0;
-  }
-
-  Elf64_Ehdr *eh64 = elf64_getehdr(e);
-  Elf32_Ehdr *eh32 = elf32_getehdr(e);
-
-  if (!eh64 && !eh32) {
-    DP("Unable to get machine ID from ELF file!\n");
-    elf_end(e);
-    return 0;
-  }
-
-  uint16_t Type;
-  if (eh64 && !eh32)
-    Type = eh64->e_type;
-  else if (eh32 && !eh64)
-    Type = eh32->e_type;
-  else {
-    DP("Ambiguous ELF header!\n");
-    elf_end(e);
-    return 0;
-  }
-
-  elf_end(e);
-  DP("ELF Type: %d\n", Type);
-  return Type == ET_DYN;
-}
+#endif // LLVM_OPENMP_LIBOMPTARGET_PLUGINS_COMMON_ELF_COMMON_ELF_COMMON_H

diff  --git a/openmp/libomptarget/plugins/remote/server/CMakeLists.txt b/openmp/libomptarget/plugins/remote/server/CMakeLists.txt
index 038a7edc05c7d..e1eaecf494a67 100644
--- a/openmp/libomptarget/plugins/remote/server/CMakeLists.txt
+++ b/openmp/libomptarget/plugins/remote/server/CMakeLists.txt
@@ -10,7 +10,6 @@
 #
 ##===----------------------------------------------------------------------===##
 
-include_directories(${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS})
 include_directories(${LIBOMPTARGET_SRC_DIR})
 include_directories(${LIBOMPTARGET_INCLUDE_DIR})
 include_directories(${GRPC_INCLUDE_DIR})
@@ -28,4 +27,4 @@ target_link_libraries(openmp-offloading-server
         grpc++
         protobuf
         ${OPENMP_PTHREAD_LIB}
-        "-ldl" "-lomp" "-fopenmp" "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../../exports" ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES})
+        "-ldl" "-lomp" "-fopenmp" "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../../exports")


        


More information about the Openmp-commits mailing list