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