| //===-- 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; |
| } |