1 //===-- elf_common.c - Common ELF functionality -------------------*- C -*-===// 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 // Must be included in the plugin source file AFTER omptarget.h has been 11 // included and macro DP(...) has been defined. 12 // . 13 // 14 //===----------------------------------------------------------------------===// 15 16 #if !(defined(_OMPTARGET_H_) && defined(DP)) 17 #error Include elf_common.c in the plugin source AFTER omptarget.h has been\ 18 included and macro DP(...) has been defined. 19 #endif 20 21 #include <elf.h> 22 #include <libelf.h> 23 24 // Check whether an image is valid for execution on target_id elf_check_machine(__tgt_device_image * image,uint16_t target_id)25static inline int32_t elf_check_machine(__tgt_device_image *image, 26 uint16_t target_id) { 27 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 } 33 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 elf_is_dynamic(__tgt_device_image * image)75static 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 } 112