forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
//===-- elf_common.h - Common ELF functionality -------------------*- C -*-===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// 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_DEBUG_H))
 | 
						|
#error Include elf_common.h in the plugin source AFTER Debug.h has\
 | 
						|
 been included.
 | 
						|
#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");
 | 
						|
    elf_end(e);
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
static inline int32_t elf_is_dynamic(__tgt_device_image *image) {
 | 
						|
 | 
						|
  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;
 | 
						|
  }
 | 
						|
 | 
						|
  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 Type;
 | 
						|
  if (eh64 && !eh32)
 | 
						|
    Type = eh64->e_type;
 | 
						|
  else if (eh32 && !eh64)
 | 
						|
    Type = eh32->e_type;
 | 
						|
  else {
 | 
						|
    DP("Ambiguous ELF header!\n");
 | 
						|
    elf_end(e);
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  elf_end(e);
 | 
						|
  DP("ELF Type: %d\n", Type);
 | 
						|
  return Type == ET_DYN;
 | 
						|
}
 |