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