forked from OSchip/llvm-project
74 lines
2.0 KiB
C
74 lines
2.0 KiB
C
//===-- 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;
|
|
}
|