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 <stdio.h>
30*ae115bc7Smrj #include <string.h>
31*ae115bc7Smrj #include <sys/types.h>
32*ae115bc7Smrj #include <sys/stat.h>
33*ae115bc7Smrj #include <fcntl.h>
34*ae115bc7Smrj #include <unistd.h>
35*ae115bc7Smrj #include <libelf.h>
36*ae115bc7Smrj #include <gelf.h>
37*ae115bc7Smrj #include <errno.h>
38*ae115bc7Smrj
39*ae115bc7Smrj /*
40*ae115bc7Smrj * symdef is a very simplified version of nm. It is used by upgrade and
41*ae115bc7Smrj * create_ramdisk in situations where we can't guarantee that nm will be around.
42*ae115bc7Smrj *
43*ae115bc7Smrj * Two arguments are expected: a binary and a symbol name. If the symbol is
44*ae115bc7Smrj * found in the name table of the binary, 0 is returned. If it is not found,
45*ae115bc7Smrj * 1 is returned. If an error occurs, a message is printed to stderr and -1
46*ae115bc7Smrj * is returned.
47*ae115bc7Smrj */
48*ae115bc7Smrj
49*ae115bc7Smrj
50*ae115bc7Smrj static void
usage(void)51*ae115bc7Smrj usage(void)
52*ae115bc7Smrj {
53*ae115bc7Smrj (void) fprintf(stderr, "USAGE: symdef file_name symbol\n");
54*ae115bc7Smrj }
55*ae115bc7Smrj
56*ae115bc7Smrj int
main(int argc,char * argv[])57*ae115bc7Smrj main(int argc, char *argv[])
58*ae115bc7Smrj {
59*ae115bc7Smrj int fd = 0;
60*ae115bc7Smrj int rv = 1;
61*ae115bc7Smrj uint_t cnt, symcnt;
62*ae115bc7Smrj Elf *elfp = NULL;
63*ae115bc7Smrj Elf_Scn *scn = NULL;
64*ae115bc7Smrj size_t shstrndx;
65*ae115bc7Smrj GElf_Ehdr ehdr;
66*ae115bc7Smrj GElf_Shdr shdr;
67*ae115bc7Smrj GElf_Sym sym;
68*ae115bc7Smrj Elf32_Word shndx;
69*ae115bc7Smrj Elf_Data *symdata, *shndxdata;
70*ae115bc7Smrj
71*ae115bc7Smrj if (argc != 3) {
72*ae115bc7Smrj usage();
73*ae115bc7Smrj return (-1);
74*ae115bc7Smrj }
75*ae115bc7Smrj
76*ae115bc7Smrj fd = open(argv[1], O_RDONLY);
77*ae115bc7Smrj if (fd == -1) {
78*ae115bc7Smrj (void) fprintf(stderr, "%s\n", strerror(errno));
79*ae115bc7Smrj rv = -1;
80*ae115bc7Smrj goto done;
81*ae115bc7Smrj }
82*ae115bc7Smrj if (elf_version(EV_CURRENT) == EV_NONE) {
83*ae115bc7Smrj (void) fprintf(stderr, "Elf library version out of date\n");
84*ae115bc7Smrj rv = -1;
85*ae115bc7Smrj goto done;
86*ae115bc7Smrj }
87*ae115bc7Smrj elfp = elf_begin(fd, ELF_C_READ, NULL);
88*ae115bc7Smrj if ((elfp == NULL) || (elf_kind(elfp) != ELF_K_ELF) ||
89*ae115bc7Smrj ((gelf_getehdr(elfp, &ehdr)) == NULL) ||
90*ae115bc7Smrj (elf_getshstrndx(elfp, &shstrndx) == 0))
91*ae115bc7Smrj goto done;
92*ae115bc7Smrj
93*ae115bc7Smrj while ((scn = elf_nextscn(elfp, scn)) != NULL) {
94*ae115bc7Smrj if ((gelf_getshdr(scn, &shdr) == NULL) ||
95*ae115bc7Smrj ((shdr.sh_type != SHT_SYMTAB) &&
96*ae115bc7Smrj (shdr.sh_type != SHT_DYNSYM)) ||
97*ae115bc7Smrj ((symdata = elf_getdata(scn, NULL)) == NULL))
98*ae115bc7Smrj continue;
99*ae115bc7Smrj symcnt = shdr.sh_size / shdr.sh_entsize;
100*ae115bc7Smrj shndxdata = NULL;
101*ae115bc7Smrj for (cnt = 0; cnt < symcnt; cnt++) {
102*ae115bc7Smrj if ((gelf_getsymshndx(symdata, shndxdata, cnt,
103*ae115bc7Smrj &sym, &shndx) != NULL) &&
104*ae115bc7Smrj (strcmp(argv[2], elf_strptr(elfp, shdr.sh_link,
105*ae115bc7Smrj sym.st_name)) == 0)) {
106*ae115bc7Smrj rv = 0;
107*ae115bc7Smrj goto done;
108*ae115bc7Smrj }
109*ae115bc7Smrj }
110*ae115bc7Smrj }
111*ae115bc7Smrj done:
112*ae115bc7Smrj if (elfp)
113*ae115bc7Smrj (void) elf_end(elfp);
114*ae115bc7Smrj if (fd != -1)
115*ae115bc7Smrj (void) close(fd);
116*ae115bc7Smrj return (rv);
117*ae115bc7Smrj }
118