aboutsummaryrefslogtreecommitdiff
path: root/final/libomptarget/plugins/common/elf_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'final/libomptarget/plugins/common/elf_common.c')
-rw-r--r--final/libomptarget/plugins/common/elf_common.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/final/libomptarget/plugins/common/elf_common.c b/final/libomptarget/plugins/common/elf_common.c
new file mode 100644
index 0000000..dd85575
--- /dev/null
+++ b/final/libomptarget/plugins/common/elf_common.c
@@ -0,0 +1,73 @@
+//===-- elf_common.c - Common ELF functionality -------------------*- C -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.txt for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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_H_) && defined(DP))
+#error Include elf_common.c in the plugin source AFTER omptarget.h has been\
+ included and macro DP(...) has been defined.
+#endif
+
+#include <elf.h>
+#include <libelf.h>
+
+// 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) {
+
+ // Is the library version incompatible with the header file?
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ DP("Incompatible ELF library!\n");
+ return 0;
+ }
+
+ 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");
+ 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;
+}