Skip to content

Commit b5c4fc0

Browse files
author
Vyacheslav Zakharin
committed
[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
1 parent ce95200 commit b5c4fc0

File tree

5 files changed

+114
-100
lines changed

5 files changed

+114
-100
lines changed

openmp/libomptarget/plugins/amdgpu/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ target_link_libraries(
7575
PRIVATE
7676
elf_common
7777
hsa-runtime64::hsa-runtime64
78-
pthread dl elf
78+
dl
79+
${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
80+
${OPENMP_PTHREAD_LIB}
7981
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports"
8082
"-Wl,-z,defs"
8183
)

openmp/libomptarget/plugins/common/elf_common/CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
#
1111
##===----------------------------------------------------------------------===##
1212

13-
add_library(elf_common INTERFACE)
13+
add_library(elf_common OBJECT elf_common.cpp)
1414

15+
llvm_update_compile_flags(elf_common)
16+
set(LINK_LLVM_LIBS LLVMBinaryFormat LLVMObject LLVMSupport)
17+
target_link_libraries(elf_common INTERFACE ${LINK_LLVM_LIBS} ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES})
18+
add_dependencies(elf_common ${LINK_LLVM_LIBS})
19+
20+
# The code uses Debug.h, which requires threads support.
21+
target_link_libraries(elf_common INTERFACE ${OPENMP_PTHREAD_LIB})
22+
23+
# Expose elf_common.h directory to the users of this library.
1524
target_include_directories(elf_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//===-- elf_common.cpp - Common ELF functionality -------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Common ELF functionality for target plugins.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#include "elf_common.h"
13+
#include "Debug.h"
14+
15+
#include "llvm/BinaryFormat/Magic.h"
16+
#include "llvm/Object/Binary.h"
17+
#include "llvm/Object/ELFObjectFile.h"
18+
#include "llvm/Object/ELFTypes.h"
19+
#include "llvm/Object/ObjectFile.h"
20+
#include "llvm/Support/MemoryBuffer.h"
21+
22+
#ifndef TARGET_NAME
23+
#define TARGET_NAME ELF Common
24+
#endif
25+
#define DEBUG_PREFIX "TARGET " GETNAME(TARGET_NAME)
26+
27+
using namespace llvm;
28+
using namespace llvm::ELF;
29+
using namespace llvm::object;
30+
31+
/// If the given range of bytes [\p BytesBegin, \p BytesEnd) represents
32+
/// a valid ELF, then invoke \p Callback on the ELFObjectFileBase
33+
/// created from this range, otherwise, return 0.
34+
/// If \p Callback is invoked, then return whatever value \p Callback returns.
35+
template <typename F>
36+
static int32_t withBytesAsElf(char *BytesBegin, char *BytesEnd, F Callback) {
37+
size_t Size = BytesEnd - BytesBegin;
38+
StringRef StrBuf(BytesBegin, Size);
39+
40+
auto Magic = identify_magic(StrBuf);
41+
if (Magic != file_magic::elf && Magic != file_magic::elf_relocatable &&
42+
Magic != file_magic::elf_executable &&
43+
Magic != file_magic::elf_shared_object && Magic != file_magic::elf_core) {
44+
DP("Not an ELF image!\n");
45+
return 0;
46+
}
47+
48+
std::unique_ptr<MemoryBuffer> MemBuf =
49+
MemoryBuffer::getMemBuffer(StrBuf, "", false);
50+
Expected<std::unique_ptr<ObjectFile>> BinOrErr =
51+
ObjectFile::createELFObjectFile(MemBuf->getMemBufferRef(),
52+
/*InitContent=*/false);
53+
if (!BinOrErr) {
54+
DP("Unable to get ELF handle: %s!\n",
55+
toString(BinOrErr.takeError()).c_str());
56+
return 0;
57+
}
58+
59+
auto *Object = dyn_cast<const ELFObjectFileBase>(BinOrErr->get());
60+
61+
if (!Object) {
62+
DP("Unknown ELF format!\n");
63+
return 0;
64+
}
65+
66+
return Callback(Object);
67+
}
68+
69+
// Check whether an image is valid for execution on target_id
70+
int32_t elf_check_machine(__tgt_device_image *image, uint16_t target_id) {
71+
auto CheckMachine = [target_id](const ELFObjectFileBase *Object) {
72+
return target_id == Object->getEMachine();
73+
};
74+
return withBytesAsElf(reinterpret_cast<char *>(image->ImageStart),
75+
reinterpret_cast<char *>(image->ImageEnd),
76+
CheckMachine);
77+
}
78+
79+
int32_t elf_is_dynamic(__tgt_device_image *image) {
80+
auto CheckDynType = [](const ELFObjectFileBase *Object) {
81+
uint16_t Type = Object->getEType();
82+
DP("ELF Type: %d\n", Type);
83+
return Type == ET_DYN;
84+
};
85+
return withBytesAsElf(reinterpret_cast<char *>(image->ImageStart),
86+
reinterpret_cast<char *>(image->ImageEnd),
87+
CheckDynType);
88+
}
Lines changed: 12 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- elf_common.h - Common ELF functionality -------------------*- C -*-===//
1+
//===-- elf_common.h - Common ELF functionality -----------------*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,105 +7,21 @@
77
//===----------------------------------------------------------------------===//
88
//
99
// Common ELF functionality for target plugins.
10-
// Must be included in the plugin source file AFTER omptarget.h has been
11-
// included and macro DP(...) has been defined.
12-
// .
1310
//
1411
//===----------------------------------------------------------------------===//
1512

16-
#if !(defined(_OMPTARGET_DEBUG_H))
17-
#error Include elf_common.h in the plugin source AFTER Debug.h has\
18-
been included.
19-
#endif
13+
#ifndef LLVM_OPENMP_LIBOMPTARGET_PLUGINS_COMMON_ELF_COMMON_ELF_COMMON_H
14+
#define LLVM_OPENMP_LIBOMPTARGET_PLUGINS_COMMON_ELF_COMMON_ELF_COMMON_H
2015

21-
#include <elf.h>
22-
#include <libelf.h>
16+
#include "omptargetplugin.h"
17+
#include <cstdint>
2318

24-
// Check whether an image is valid for execution on target_id
25-
static inline int32_t elf_check_machine(__tgt_device_image *image,
26-
uint16_t target_id) {
19+
/// Return non-zero, if the given \p image is an ELF object, which
20+
/// e_machine matches \p target_id; return zero otherwise.
21+
EXTERN int32_t elf_check_machine(__tgt_device_image *image, uint16_t target_id);
2722

28-
// Is the library version incompatible with the header file?
29-
if (elf_version(EV_CURRENT) == EV_NONE) {
30-
DP("Incompatible ELF library!\n");
31-
return 0;
32-
}
23+
/// Return non-zero, if the given \p image is an ET_DYN ELF object;
24+
/// return zero otherwise.
25+
EXTERN int32_t elf_is_dynamic(__tgt_device_image *image);
3326

34-
char *img_begin = (char *)image->ImageStart;
35-
char *img_end = (char *)image->ImageEnd;
36-
size_t img_size = img_end - img_begin;
37-
38-
// Obtain elf handler
39-
Elf *e = elf_memory(img_begin, img_size);
40-
if (!e) {
41-
DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
42-
return 0;
43-
}
44-
45-
// Check if ELF is the right kind.
46-
if (elf_kind(e) != ELF_K_ELF) {
47-
DP("Unexpected ELF type!\n");
48-
elf_end(e);
49-
return 0;
50-
}
51-
Elf64_Ehdr *eh64 = elf64_getehdr(e);
52-
Elf32_Ehdr *eh32 = elf32_getehdr(e);
53-
54-
if (!eh64 && !eh32) {
55-
DP("Unable to get machine ID from ELF file!\n");
56-
elf_end(e);
57-
return 0;
58-
}
59-
60-
uint16_t MachineID;
61-
if (eh64 && !eh32)
62-
MachineID = eh64->e_machine;
63-
else if (eh32 && !eh64)
64-
MachineID = eh32->e_machine;
65-
else {
66-
DP("Ambiguous ELF header!\n");
67-
elf_end(e);
68-
return 0;
69-
}
70-
71-
elf_end(e);
72-
return MachineID == target_id;
73-
}
74-
75-
static inline int32_t elf_is_dynamic(__tgt_device_image *image) {
76-
77-
char *img_begin = (char *)image->ImageStart;
78-
char *img_end = (char *)image->ImageEnd;
79-
size_t img_size = img_end - img_begin;
80-
81-
// Obtain elf handler
82-
Elf *e = elf_memory(img_begin, img_size);
83-
if (!e) {
84-
DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
85-
return 0;
86-
}
87-
88-
Elf64_Ehdr *eh64 = elf64_getehdr(e);
89-
Elf32_Ehdr *eh32 = elf32_getehdr(e);
90-
91-
if (!eh64 && !eh32) {
92-
DP("Unable to get machine ID from ELF file!\n");
93-
elf_end(e);
94-
return 0;
95-
}
96-
97-
uint16_t Type;
98-
if (eh64 && !eh32)
99-
Type = eh64->e_type;
100-
else if (eh32 && !eh64)
101-
Type = eh32->e_type;
102-
else {
103-
DP("Ambiguous ELF header!\n");
104-
elf_end(e);
105-
return 0;
106-
}
107-
108-
elf_end(e);
109-
DP("ELF Type: %d\n", Type);
110-
return Type == ET_DYN;
111-
}
27+
#endif // LLVM_OPENMP_LIBOMPTARGET_PLUGINS_COMMON_ELF_COMMON_ELF_COMMON_H

openmp/libomptarget/plugins/remote/server/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#
1111
##===----------------------------------------------------------------------===##
1212

13-
include_directories(${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS})
1413
include_directories(${LIBOMPTARGET_SRC_DIR})
1514
include_directories(${LIBOMPTARGET_INCLUDE_DIR})
1615
include_directories(${GRPC_INCLUDE_DIR})
@@ -28,4 +27,4 @@ target_link_libraries(openmp-offloading-server
2827
grpc++
2928
protobuf
3029
${OPENMP_PTHREAD_LIB}
31-
"-ldl" "-lomp" "-fopenmp" "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../../exports" ${LIBOMPTARGET_DEP_LIBELF_LIBRARIES})
30+
"-ldl" "-lomp" "-fopenmp" "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../../exports")

0 commit comments

Comments
 (0)