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