xref: /titanic_41/usr/src/tools/elfextract/elfextract.c (revision 843e19887f64dde75055cf8842fc4db2171eff45)
1ae115bc7Smrj /*
2ae115bc7Smrj  * CDDL HEADER START
3ae115bc7Smrj  *
4ae115bc7Smrj  * The contents of this file are subject to the terms of the
5ae115bc7Smrj  * Common Development and Distribution License (the "License").
6ae115bc7Smrj  * You may not use this file except in compliance with the License.
7ae115bc7Smrj  *
8ae115bc7Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9ae115bc7Smrj  * or http://www.opensolaris.org/os/licensing.
10ae115bc7Smrj  * See the License for the specific language governing permissions
11ae115bc7Smrj  * and limitations under the License.
12ae115bc7Smrj  *
13ae115bc7Smrj  * When distributing Covered Code, include this CDDL HEADER in each
14ae115bc7Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15ae115bc7Smrj  * If applicable, add the following below this CDDL HEADER, with the
16ae115bc7Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
17ae115bc7Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
18ae115bc7Smrj  *
19ae115bc7Smrj  * CDDL HEADER END
20ae115bc7Smrj  */
21ae115bc7Smrj 
22ae115bc7Smrj /*
23ae115bc7Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24ae115bc7Smrj  * Use is subject to license terms.
25ae115bc7Smrj  */
26ae115bc7Smrj 
27ae115bc7Smrj #pragma ident	"%Z%%M%	%I%	%E% SMI"
28ae115bc7Smrj 
29ae115bc7Smrj #include <stdlib.h>
30ae115bc7Smrj #include <fcntl.h>
31ae115bc7Smrj #include <strings.h>
32ae115bc7Smrj #include <stdio.h>
33ae115bc7Smrj #include <errno.h>
34ae115bc7Smrj #include <sys/types.h>
35ae115bc7Smrj #include <sys/inttypes.h>
36ae115bc7Smrj #include <sys/elf.h>
37ae115bc7Smrj #include <sys/elf_notes.h>
38ae115bc7Smrj #include <sys/mman.h>
39ae115bc7Smrj #include <sys/stat.h>
40ae115bc7Smrj #include <sys/statvfs.h>
41ae115bc7Smrj 
42ae115bc7Smrj static char *pname;
43ae115bc7Smrj static char *fname;
44ae115bc7Smrj static char *image;	/* pointer to the ELF file in memory */
45ae115bc7Smrj 
46ae115bc7Smrj #define	ELFSEEK(offset) ((void *)(image + offset))
47ae115bc7Smrj 
48ae115bc7Smrj /*
49ae115bc7Smrj  * Extract the PT_LOAD bits and format them into a .s
50ae115bc7Smrj  */
51ae115bc7Smrj static void
extract32(Elf32_Ehdr * eh)52ae115bc7Smrj extract32(Elf32_Ehdr *eh)
53ae115bc7Smrj {
54ae115bc7Smrj 	Elf32_Phdr *phdr;
55ae115bc7Smrj 	caddr_t allphdrs;
56ae115bc7Smrj 	int i;
57ae115bc7Smrj 	int c;
58ae115bc7Smrj 	unsigned char *bytes;
59ae115bc7Smrj 	uint_t cnt = 10;
60ae115bc7Smrj 
61ae115bc7Smrj 	allphdrs = NULL;
62ae115bc7Smrj 
63ae115bc7Smrj 	if (eh->e_type != ET_EXEC) {
64ae115bc7Smrj 		(void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n",
65ae115bc7Smrj 		    pname, eh->e_type);
66ae115bc7Smrj 		exit(1);
67ae115bc7Smrj 	}
68ae115bc7Smrj 	if (eh->e_phnum == 0 || eh->e_phoff == 0) {
69ae115bc7Smrj 		(void) fprintf(stderr, "%s: no program headers\n", pname);
70ae115bc7Smrj 		exit(1);
71ae115bc7Smrj 	}
72ae115bc7Smrj 
73ae115bc7Smrj 	/*
74ae115bc7Smrj 	 * Get the program headers.
75ae115bc7Smrj 	 */
76ae115bc7Smrj 	allphdrs = ELFSEEK(eh->e_phoff);
77ae115bc7Smrj 	if (allphdrs == NULL) {
78ae115bc7Smrj 		(void) fprintf(stderr, "%s: Failed to get %d program hdrs\n",
79ae115bc7Smrj 		    pname, eh->e_phnum);
80ae115bc7Smrj 		exit(1);
81ae115bc7Smrj 	}
82ae115bc7Smrj 
83ae115bc7Smrj 	/*
84ae115bc7Smrj 	 * Find the PT_LOAD section
85ae115bc7Smrj 	 */
86ae115bc7Smrj 	for (i = 0; i < eh->e_phnum; i++) {
87ae115bc7Smrj 		/*LINTED [ELF program header alignment]*/
88ae115bc7Smrj 		phdr = (Elf32_Phdr *)(allphdrs + eh->e_phentsize * i);
89ae115bc7Smrj 
90ae115bc7Smrj 		if (phdr->p_type != PT_LOAD)
91ae115bc7Smrj 			continue;
92ae115bc7Smrj 
93ae115bc7Smrj 		if (phdr->p_memsz == 0)
94ae115bc7Smrj 			continue;
95ae115bc7Smrj 
96ae115bc7Smrj 		bytes = ELFSEEK(phdr->p_offset);
97ae115bc7Smrj 		for (c = 0; c < phdr->p_filesz; ++c) {
98ae115bc7Smrj 			if (c % cnt == 0)
99ae115bc7Smrj 				(void) printf("\n	.byte	");
100ae115bc7Smrj 			else
101ae115bc7Smrj 				(void) printf(",");
102ae115bc7Smrj 			(void) printf("0x%x", bytes[c]);
103ae115bc7Smrj 		}
104ae115bc7Smrj 		for (; c < phdr->p_memsz; ++c) {
105ae115bc7Smrj 			if (c % cnt == 0) {
106ae115bc7Smrj 				(void) printf("\n	.byte	");
107ae115bc7Smrj 				cnt = 20;
108ae115bc7Smrj 			} else {
109ae115bc7Smrj 				(void) printf(", ");
110ae115bc7Smrj 			}
111ae115bc7Smrj 			(void) printf("0");
112ae115bc7Smrj 		}
113ae115bc7Smrj 		(void) printf("\n");
114ae115bc7Smrj 		return;
115ae115bc7Smrj 	}
116ae115bc7Smrj 
117ae115bc7Smrj 	(void) fprintf(stderr, "%s: Failed finding PT_LOAD section\n", pname);
118ae115bc7Smrj 	exit(1);
119ae115bc7Smrj }
120ae115bc7Smrj 
121ae115bc7Smrj static void
extract64(Elf64_Ehdr * eh)122ae115bc7Smrj extract64(Elf64_Ehdr *eh)
123ae115bc7Smrj {
124ae115bc7Smrj 	Elf64_Phdr *phdr;
125ae115bc7Smrj 	caddr_t allphdrs;
126ae115bc7Smrj 	int i;
127ae115bc7Smrj 	int c;
128ae115bc7Smrj 	unsigned char *bytes;
129ae115bc7Smrj 	uint_t cnt = 10;
130ae115bc7Smrj 
131ae115bc7Smrj 	allphdrs = NULL;
132ae115bc7Smrj 
133ae115bc7Smrj 	if (eh->e_type != ET_EXEC) {
134ae115bc7Smrj 		(void) fprintf(stderr, "%s: not ET_EXEC, e_type = 0x%x\n",
135ae115bc7Smrj 		    pname, eh->e_type);
136ae115bc7Smrj 		exit(1);
137ae115bc7Smrj 	}
138ae115bc7Smrj 	if (eh->e_phnum == 0 || eh->e_phoff == 0) {
139ae115bc7Smrj 		(void) fprintf(stderr, "%s: no program headers\n", pname);
140ae115bc7Smrj 		exit(1);
141ae115bc7Smrj 	}
142ae115bc7Smrj 
143ae115bc7Smrj 	/*
144ae115bc7Smrj 	 * Get the program headers.
145ae115bc7Smrj 	 */
146ae115bc7Smrj 	allphdrs = ELFSEEK(eh->e_phoff);
147ae115bc7Smrj 	if (allphdrs == NULL) {
148ae115bc7Smrj 		(void) fprintf(stderr, "%s: Failed to get %d program hdrs\n",
149ae115bc7Smrj 		    pname, eh->e_phnum);
150ae115bc7Smrj 		exit(1);
151ae115bc7Smrj 	}
152ae115bc7Smrj 
153ae115bc7Smrj 	/*
154ae115bc7Smrj 	 * Find the PT_LOAD section
155ae115bc7Smrj 	 */
156ae115bc7Smrj 	for (i = 0; i < eh->e_phnum; i++) {
157ae115bc7Smrj 		/*LINTED [ELF program header alignment]*/
158ae115bc7Smrj 		phdr = (Elf64_Phdr *)(allphdrs + eh->e_phentsize * i);
159ae115bc7Smrj 
160ae115bc7Smrj 		if (phdr->p_type != PT_LOAD)
161ae115bc7Smrj 			continue;
162ae115bc7Smrj 
163ae115bc7Smrj 		if (phdr->p_memsz == 0)
164ae115bc7Smrj 			continue;
165ae115bc7Smrj 
166ae115bc7Smrj 		bytes = ELFSEEK(phdr->p_offset);
167ae115bc7Smrj 		for (c = 0; c < phdr->p_filesz; ++c) {
168ae115bc7Smrj 			if (c % cnt == 0)
169ae115bc7Smrj 				(void) printf("\n	.byte	");
170ae115bc7Smrj 			else
171ae115bc7Smrj 				(void) printf(",");
172ae115bc7Smrj 			(void) printf("0x%x", bytes[c]);
173ae115bc7Smrj 		}
174ae115bc7Smrj 		for (; c < phdr->p_memsz; ++c) {
175ae115bc7Smrj 			if (c % cnt == 0) {
176ae115bc7Smrj 				(void) printf("\n	.byte	");
177ae115bc7Smrj 				cnt = 20;
178ae115bc7Smrj 			} else {
179ae115bc7Smrj 				(void) printf(", ");
180ae115bc7Smrj 			}
181ae115bc7Smrj 			(void) printf("0");
182ae115bc7Smrj 		}
183ae115bc7Smrj 		(void) printf("\n");
184ae115bc7Smrj 		return;
185ae115bc7Smrj 	}
186ae115bc7Smrj 
187ae115bc7Smrj 	(void) fprintf(stderr, "%s: Failed finding PT_LOAD section\n", pname);
188ae115bc7Smrj 	exit(1);
189ae115bc7Smrj }
190ae115bc7Smrj 
191ae115bc7Smrj int
main(int argc,char ** argv)192ae115bc7Smrj main(int argc, char **argv)
193ae115bc7Smrj {
194ae115bc7Smrj 	int fd;
195ae115bc7Smrj 	uchar_t *ident;
196ae115bc7Smrj 	void *hdr = NULL;
197ae115bc7Smrj 	struct stat stats;
198ae115bc7Smrj 	ssize_t r;
199*843e1988Sjohnlev 	size_t pgsz;
200ae115bc7Smrj 	uint_t len;
201ae115bc7Smrj 
202ae115bc7Smrj 	/*
203ae115bc7Smrj 	 * we expect one argument -- the elf file
204ae115bc7Smrj 	 */
205ae115bc7Smrj 	if (argc != 2) {
206ae115bc7Smrj 		(void) fprintf(stderr, "usage: %s <unix-elf-file>\n", argv[0]);
207ae115bc7Smrj 		exit(1);
208ae115bc7Smrj 	}
209ae115bc7Smrj 
210ae115bc7Smrj 	pname = strrchr(argv[0], '/');
211ae115bc7Smrj 	if (pname == NULL)
212ae115bc7Smrj 		pname = argv[0];
213ae115bc7Smrj 	else
214ae115bc7Smrj 		++pname;
215ae115bc7Smrj 
216ae115bc7Smrj 	fname = argv[1];
217ae115bc7Smrj 	fd = open(fname, O_RDONLY);
218ae115bc7Smrj 	if (fd < 0) {
219ae115bc7Smrj 		(void) fprintf(stderr, "%s: open(%s, O_RDONLY) failed, %s\n",
220ae115bc7Smrj 		    pname, fname, strerror(errno));
221ae115bc7Smrj 		exit(1);
222ae115bc7Smrj 	}
223ae115bc7Smrj 
224ae115bc7Smrj 	if (stat(fname, &stats) < 0) {
225ae115bc7Smrj 		(void) fprintf(stderr, "%s: stat(%s, ...) failed, %s\n",
226ae115bc7Smrj 		    pname, fname, strerror(errno));
227ae115bc7Smrj 		exit(1);
228ae115bc7Smrj 	}
229ae115bc7Smrj 
230*843e1988Sjohnlev 	pgsz = getpagesize();
231*843e1988Sjohnlev 	len = (stats.st_size + (pgsz - 1)) & (~(pgsz - 1));
232ae115bc7Smrj 
233ae115bc7Smrj 	/*
234ae115bc7Smrj 	 * mmap the file
235ae115bc7Smrj 	 */
236ae115bc7Smrj 	image = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
237ae115bc7Smrj 	if (image == MAP_FAILED) {
238ae115bc7Smrj 		(void) fprintf(stderr, "%s: mmap() of %s failed, %s\n",
239ae115bc7Smrj 		    pname, fname, strerror(errno));
240ae115bc7Smrj 		exit(1);
241ae115bc7Smrj 	}
242ae115bc7Smrj 
243ae115bc7Smrj 	ident = ELFSEEK(0);
244ae115bc7Smrj 	if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 ||
245ae115bc7Smrj 	    ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) {
246ae115bc7Smrj 		(void) fprintf(stderr, "%s: not an ELF file!\n", pname);
247ae115bc7Smrj 		exit(1);
248ae115bc7Smrj 	}
249ae115bc7Smrj 
250ae115bc7Smrj 	if (ident[EI_CLASS] == ELFCLASS32) {
251ae115bc7Smrj 		hdr = ELFSEEK(0);
252ae115bc7Smrj 		extract32(hdr);
253ae115bc7Smrj 	} else if (ident[EI_CLASS] == ELFCLASS64) {
254ae115bc7Smrj 		hdr = ELFSEEK(0);
255ae115bc7Smrj 		extract64(hdr);
256ae115bc7Smrj 	} else {
257ae115bc7Smrj 		(void) fprintf(stderr, "%s: Wrong ELF class 0x%x\n", pname,
258ae115bc7Smrj 		    ident[EI_CLASS]);
259ae115bc7Smrj 		exit(1);
260ae115bc7Smrj 	}
261ae115bc7Smrj 	return (0);
262ae115bc7Smrj }
263