18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <elf.h> 38c2ecf20Sopenharmony_ci#include <inttypes.h> 48c2ecf20Sopenharmony_ci#include <stdint.h> 58c2ecf20Sopenharmony_ci#include <stdio.h> 68c2ecf20Sopenharmony_ci#include <stdlib.h> 78c2ecf20Sopenharmony_ci#include <string.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci__attribute__((noreturn)) 108c2ecf20Sopenharmony_cistatic void die(const char *msg) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci fputs(msg, stderr); 138c2ecf20Sopenharmony_ci exit(EXIT_FAILURE); 148c2ecf20Sopenharmony_ci} 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ciint main(int argc, const char *argv[]) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci uint64_t entry; 198c2ecf20Sopenharmony_ci size_t nread; 208c2ecf20Sopenharmony_ci FILE *file; 218c2ecf20Sopenharmony_ci union { 228c2ecf20Sopenharmony_ci Elf32_Ehdr ehdr32; 238c2ecf20Sopenharmony_ci Elf64_Ehdr ehdr64; 248c2ecf20Sopenharmony_ci } hdr; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci if (argc != 2) 278c2ecf20Sopenharmony_ci die("Usage: elf-entry <elf-file>\n"); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci file = fopen(argv[1], "r"); 308c2ecf20Sopenharmony_ci if (!file) { 318c2ecf20Sopenharmony_ci perror("Unable to open input file"); 328c2ecf20Sopenharmony_ci return EXIT_FAILURE; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci nread = fread(&hdr, 1, sizeof(hdr), file); 368c2ecf20Sopenharmony_ci if (nread != sizeof(hdr)) { 378c2ecf20Sopenharmony_ci fclose(file); 388c2ecf20Sopenharmony_ci perror("Unable to read input file"); 398c2ecf20Sopenharmony_ci return EXIT_FAILURE; 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (memcmp(hdr.ehdr32.e_ident, ELFMAG, SELFMAG)) { 438c2ecf20Sopenharmony_ci fclose(file); 448c2ecf20Sopenharmony_ci die("Input is not an ELF\n"); 458c2ecf20Sopenharmony_ci } 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci switch (hdr.ehdr32.e_ident[EI_CLASS]) { 488c2ecf20Sopenharmony_ci case ELFCLASS32: 498c2ecf20Sopenharmony_ci /* Sign extend to form a canonical address */ 508c2ecf20Sopenharmony_ci entry = (int64_t)(int32_t)hdr.ehdr32.e_entry; 518c2ecf20Sopenharmony_ci break; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci case ELFCLASS64: 548c2ecf20Sopenharmony_ci entry = hdr.ehdr64.e_entry; 558c2ecf20Sopenharmony_ci break; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci default: 588c2ecf20Sopenharmony_ci fclose(file); 598c2ecf20Sopenharmony_ci die("Invalid ELF class\n"); 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci fclose(file); 638c2ecf20Sopenharmony_ci printf("0x%016" PRIx64 "\n", entry); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return EXIT_SUCCESS; 668c2ecf20Sopenharmony_ci} 67