xref: /onnv-gate/usr/src/cmd/boot/symdef/symdef.c (revision 3446:5903aece022d)
1*3446Smrj /*
2*3446Smrj  * CDDL HEADER START
3*3446Smrj  *
4*3446Smrj  * The contents of this file are subject to the terms of the
5*3446Smrj  * Common Development and Distribution License (the "License").
6*3446Smrj  * You may not use this file except in compliance with the License.
7*3446Smrj  *
8*3446Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3446Smrj  * or http://www.opensolaris.org/os/licensing.
10*3446Smrj  * See the License for the specific language governing permissions
11*3446Smrj  * and limitations under the License.
12*3446Smrj  *
13*3446Smrj  * When distributing Covered Code, include this CDDL HEADER in each
14*3446Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3446Smrj  * If applicable, add the following below this CDDL HEADER, with the
16*3446Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
17*3446Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3446Smrj  *
19*3446Smrj  * CDDL HEADER END
20*3446Smrj  */
21*3446Smrj 
22*3446Smrj /*
23*3446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*3446Smrj  * Use is subject to license terms.
25*3446Smrj  */
26*3446Smrj 
27*3446Smrj #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*3446Smrj 
29*3446Smrj #include <stdio.h>
30*3446Smrj #include <string.h>
31*3446Smrj #include <sys/types.h>
32*3446Smrj #include <sys/stat.h>
33*3446Smrj #include <fcntl.h>
34*3446Smrj #include <unistd.h>
35*3446Smrj #include <libelf.h>
36*3446Smrj #include <gelf.h>
37*3446Smrj #include <errno.h>
38*3446Smrj 
39*3446Smrj /*
40*3446Smrj  * symdef is a very simplified version of nm.  It is used by upgrade and
41*3446Smrj  * create_ramdisk in situations where we can't guarantee that nm will be around.
42*3446Smrj  *
43*3446Smrj  * Two arguments are expected: a binary and a symbol name.  If the symbol is
44*3446Smrj  * found in the name table of the binary, 0 is returned.  If it is not found,
45*3446Smrj  * 1 is returned.  If an error occurs, a message is printed to stderr and -1
46*3446Smrj  * is returned.
47*3446Smrj  */
48*3446Smrj 
49*3446Smrj 
50*3446Smrj static void
usage(void)51*3446Smrj usage(void)
52*3446Smrj {
53*3446Smrj 	(void) fprintf(stderr, "USAGE: symdef file_name symbol\n");
54*3446Smrj }
55*3446Smrj 
56*3446Smrj int
main(int argc,char * argv[])57*3446Smrj main(int argc, char *argv[])
58*3446Smrj {
59*3446Smrj 	int	fd = 0;
60*3446Smrj 	int	rv = 1;
61*3446Smrj 	uint_t	cnt, symcnt;
62*3446Smrj 	Elf	*elfp = NULL;
63*3446Smrj 	Elf_Scn	*scn = NULL;
64*3446Smrj 	size_t	shstrndx;
65*3446Smrj 	GElf_Ehdr	ehdr;
66*3446Smrj 	GElf_Shdr	shdr;
67*3446Smrj 	GElf_Sym	sym;
68*3446Smrj 	Elf32_Word	shndx;
69*3446Smrj 	Elf_Data	*symdata, *shndxdata;
70*3446Smrj 
71*3446Smrj 	if (argc != 3) {
72*3446Smrj 		usage();
73*3446Smrj 		return (-1);
74*3446Smrj 	}
75*3446Smrj 
76*3446Smrj 	fd = open(argv[1], O_RDONLY);
77*3446Smrj 	if (fd == -1) {
78*3446Smrj 		(void) fprintf(stderr, "%s\n", strerror(errno));
79*3446Smrj 		rv = -1;
80*3446Smrj 		goto done;
81*3446Smrj 	}
82*3446Smrj 	if (elf_version(EV_CURRENT) == EV_NONE) {
83*3446Smrj 		(void) fprintf(stderr, "Elf library version out of date\n");
84*3446Smrj 		rv = -1;
85*3446Smrj 		goto done;
86*3446Smrj 	}
87*3446Smrj 	elfp = elf_begin(fd, ELF_C_READ, NULL);
88*3446Smrj 	if ((elfp == NULL) || (elf_kind(elfp) != ELF_K_ELF) ||
89*3446Smrj 	    ((gelf_getehdr(elfp, &ehdr)) == NULL) ||
90*3446Smrj 	    (elf_getshstrndx(elfp, &shstrndx) == 0))
91*3446Smrj 		goto done;
92*3446Smrj 
93*3446Smrj 	while ((scn = elf_nextscn(elfp, scn)) != NULL) {
94*3446Smrj 		if ((gelf_getshdr(scn, &shdr) == NULL) ||
95*3446Smrj 		    ((shdr.sh_type != SHT_SYMTAB) &&
96*3446Smrj 		    (shdr.sh_type != SHT_DYNSYM)) ||
97*3446Smrj 		    ((symdata = elf_getdata(scn, NULL)) == NULL))
98*3446Smrj 			continue;
99*3446Smrj 		symcnt = shdr.sh_size / shdr.sh_entsize;
100*3446Smrj 		shndxdata = NULL;
101*3446Smrj 		for (cnt = 0; cnt < symcnt; cnt++) {
102*3446Smrj 			if ((gelf_getsymshndx(symdata, shndxdata, cnt,
103*3446Smrj 			    &sym, &shndx) != NULL) &&
104*3446Smrj 			    (strcmp(argv[2], elf_strptr(elfp, shdr.sh_link,
105*3446Smrj 			    sym.st_name)) == 0)) {
106*3446Smrj 				rv = 0;
107*3446Smrj 				goto done;
108*3446Smrj 			}
109*3446Smrj 		}
110*3446Smrj 	}
111*3446Smrj done:
112*3446Smrj 	if (elfp)
113*3446Smrj 		(void) elf_end(elfp);
114*3446Smrj 	if (fd != -1)
115*3446Smrj 		(void) close(fd);
116*3446Smrj 	return (rv);
117*3446Smrj }
118