1e245767aSPaul Burton // SPDX-License-Identifier: GPL-2.0
2e245767aSPaul Burton #include <byteswap.h>
3e245767aSPaul Burton #include <elf.h>
4e245767aSPaul Burton #include <endian.h>
5e245767aSPaul Burton #include <inttypes.h>
6e245767aSPaul Burton #include <stdint.h>
7e245767aSPaul Burton #include <stdio.h>
8e245767aSPaul Burton #include <stdlib.h>
9e245767aSPaul Burton #include <string.h>
10e245767aSPaul Burton
11e245767aSPaul Burton #ifdef be32toh
12e245767aSPaul Burton /* If libc provides [bl]e{32,64}toh() then we'll use them */
13e245767aSPaul Burton #elif BYTE_ORDER == LITTLE_ENDIAN
14e245767aSPaul Burton # define be32toh(x) bswap_32(x)
15e245767aSPaul Burton # define le32toh(x) (x)
16e245767aSPaul Burton # define be64toh(x) bswap_64(x)
17e245767aSPaul Burton # define le64toh(x) (x)
18e245767aSPaul Burton #elif BYTE_ORDER == BIG_ENDIAN
19e245767aSPaul Burton # define be32toh(x) (x)
20e245767aSPaul Burton # define le32toh(x) bswap_32(x)
21e245767aSPaul Burton # define be64toh(x) (x)
22e245767aSPaul Burton # define le64toh(x) bswap_64(x)
23e245767aSPaul Burton #endif
24e245767aSPaul Burton
25e245767aSPaul Burton __attribute__((noreturn))
die(const char * msg)26e245767aSPaul Burton static void die(const char *msg)
27e245767aSPaul Burton {
28e245767aSPaul Burton fputs(msg, stderr);
29e245767aSPaul Burton exit(EXIT_FAILURE);
30e245767aSPaul Burton }
31e245767aSPaul Burton
main(int argc,const char * argv[])32e245767aSPaul Burton int main(int argc, const char *argv[])
33e245767aSPaul Burton {
34e245767aSPaul Burton uint64_t entry;
35e245767aSPaul Burton size_t nread;
36e245767aSPaul Burton FILE *file;
37e245767aSPaul Burton union {
38e245767aSPaul Burton Elf32_Ehdr ehdr32;
39e245767aSPaul Burton Elf64_Ehdr ehdr64;
40e245767aSPaul Burton } hdr;
41e245767aSPaul Burton
42e245767aSPaul Burton if (argc != 2)
43e245767aSPaul Burton die("Usage: elf-entry <elf-file>\n");
44e245767aSPaul Burton
45e245767aSPaul Burton file = fopen(argv[1], "r");
46e245767aSPaul Burton if (!file) {
47e245767aSPaul Burton perror("Unable to open input file");
48e245767aSPaul Burton return EXIT_FAILURE;
49e245767aSPaul Burton }
50e245767aSPaul Burton
51e245767aSPaul Burton nread = fread(&hdr, 1, sizeof(hdr), file);
52e245767aSPaul Burton if (nread != sizeof(hdr)) {
53e245767aSPaul Burton perror("Unable to read input file");
54*f33a0b94SKaige Li fclose(file);
55e245767aSPaul Burton return EXIT_FAILURE;
56e245767aSPaul Burton }
57e245767aSPaul Burton
58*f33a0b94SKaige Li if (memcmp(hdr.ehdr32.e_ident, ELFMAG, SELFMAG)) {
59*f33a0b94SKaige Li fclose(file);
60e245767aSPaul Burton die("Input is not an ELF\n");
61*f33a0b94SKaige Li }
62e245767aSPaul Burton
63e245767aSPaul Burton switch (hdr.ehdr32.e_ident[EI_CLASS]) {
64e245767aSPaul Burton case ELFCLASS32:
65e245767aSPaul Burton switch (hdr.ehdr32.e_ident[EI_DATA]) {
66e245767aSPaul Burton case ELFDATA2LSB:
67e245767aSPaul Burton entry = le32toh(hdr.ehdr32.e_entry);
68e245767aSPaul Burton break;
69e245767aSPaul Burton case ELFDATA2MSB:
70e245767aSPaul Burton entry = be32toh(hdr.ehdr32.e_entry);
71e245767aSPaul Burton break;
72e245767aSPaul Burton default:
73*f33a0b94SKaige Li fclose(file);
74e245767aSPaul Burton die("Invalid ELF encoding\n");
75e245767aSPaul Burton }
76e245767aSPaul Burton
77e245767aSPaul Burton /* Sign extend to form a canonical address */
78e245767aSPaul Burton entry = (int64_t)(int32_t)entry;
79e245767aSPaul Burton break;
80e245767aSPaul Burton
81e245767aSPaul Burton case ELFCLASS64:
82e245767aSPaul Burton switch (hdr.ehdr32.e_ident[EI_DATA]) {
83e245767aSPaul Burton case ELFDATA2LSB:
84e245767aSPaul Burton entry = le64toh(hdr.ehdr64.e_entry);
85e245767aSPaul Burton break;
86e245767aSPaul Burton case ELFDATA2MSB:
87e245767aSPaul Burton entry = be64toh(hdr.ehdr64.e_entry);
88e245767aSPaul Burton break;
89e245767aSPaul Burton default:
90*f33a0b94SKaige Li fclose(file);
91e245767aSPaul Burton die("Invalid ELF encoding\n");
92e245767aSPaul Burton }
93e245767aSPaul Burton break;
94e245767aSPaul Burton
95e245767aSPaul Burton default:
96*f33a0b94SKaige Li fclose(file);
97e245767aSPaul Burton die("Invalid ELF class\n");
98e245767aSPaul Burton }
99e245767aSPaul Burton
100e245767aSPaul Burton printf("0x%016" PRIx64 "\n", entry);
101*f33a0b94SKaige Li fclose(file);
102e245767aSPaul Burton return EXIT_SUCCESS;
103e245767aSPaul Burton }
104