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