xref: /linux/arch/mips/tools/elf-entry.c (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
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