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 51*ae115bc7Smrj usage(void) 52*ae115bc7Smrj { 53*ae115bc7Smrj (void) fprintf(stderr, "USAGE: symdef file_name symbol\n"); 54*ae115bc7Smrj } 55*ae115bc7Smrj 56*ae115bc7Smrj int 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