1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 1998 by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31 #include "libelf.h" 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <string.h> 35 #include <nlist.h> 36 #include "syms.h" 37 #include "gelf.h" 38 39 #undef n_name /* This undef is to handle a #define in syms.h */ 40 /* which conflicts with the member nlist->n_name */ 41 /* as defined in nlist.h */ 42 43 44 #define SPACE 100 /* number of symbols read at a time */ 45 #define ISELF (strncmp(magic_buf, ELFMAG, SELFMAG) == 0) 46 47 48 int 49 end_elf_job(int fd, Elf * elfdes) 50 { 51 (void) elf_end(elfdes); 52 (void) close(fd); 53 return (-1); 54 } 55 56 57 int 58 _elf_nlist(int fd, struct nlist * list) 59 { 60 Elf *elfdes; /* ELF descriptor */ 61 GElf_Ehdr ehdr; /* ELF Ehdr */ 62 GElf_Shdr s_buf; /* buffer storing section header */ 63 Elf_Data *symdata; /* buffer points to symbol table */ 64 Elf_Scn *secidx = 0; /* index of the section header table */ 65 GElf_Sym sym; /* buffer storing one symbol information */ 66 unsigned strtab; /* index of symbol name in string table */ 67 long count; /* number of symbols */ 68 long ii; /* loop control */ 69 70 if (elf_version(EV_CURRENT) == EV_NONE) { 71 (void) close(fd); 72 return (-1); 73 } 74 elfdes = elf_begin(fd, ELF_C_READ, (Elf *)0); 75 if (gelf_getehdr(elfdes, &ehdr) == 0) 76 return (end_elf_job(fd, elfdes)); 77 78 while ((secidx = elf_nextscn(elfdes, secidx)) != 0) { 79 if ((gelf_getshdr(secidx, &s_buf)) == 0) 80 return (end_elf_job(fd, elfdes)); 81 if (s_buf.sh_type != SHT_SYMTAB) /* not symbol table */ 82 continue; 83 symdata = elf_getdata(secidx, (Elf_Data *)0); 84 if (symdata == 0) 85 return (end_elf_job(fd, elfdes)); 86 if (symdata->d_size == 0) 87 break; 88 strtab = s_buf.sh_link; 89 count = symdata->d_size / s_buf.sh_entsize; 90 for (ii = 1; ii < count; ++ii) { 91 struct nlist *p; 92 register char *name; 93 /* LINTED */ 94 (void) gelf_getsym(symdata, (int)ii, &sym); 95 name = elf_strptr(elfdes, strtab, (size_t)sym.st_name); 96 if (name == 0) 97 continue; 98 for (p = list; p->n_name && p->n_name[0]; ++p) { 99 if (strcmp(p->n_name, name)) 100 continue; 101 p->n_value = (long)sym.st_value; 102 p->n_type = GELF_ST_TYPE(sym.st_info); 103 p->n_scnum = sym.st_shndx; 104 break; 105 } 106 } 107 break; 108 /* 109 * Currently there is only one symbol table section 110 * in an object file, but this restriction may be 111 * relaxed in the future. 112 */ 113 } 114 (void) elf_end(elfdes); 115 (void) close(fd); 116 return (0); 117 } 118 119 int 120 nlist(const char * name, struct nlist * list) 121 { 122 register struct nlist *p; 123 char magic_buf[EI_NIDENT]; 124 int fd; 125 126 for (p = list; p->n_name && p->n_name[0]; p++) { /* n_name can be ptr */ 127 p->n_type = 0; 128 p->n_value = 0L; 129 p->n_scnum = 0; 130 p->n_sclass = 0; 131 p->n_numaux = 0; 132 } 133 134 if ((fd = open(name, 0)) < 0) 135 return (-1); 136 if (read(fd, magic_buf, EI_NIDENT) == -1) { 137 (void) close(fd); 138 return (-1); 139 } 140 141 if (lseek(fd, 0L, 0) == -1L) { /* rewind to beginning of object file */ 142 (void) close(fd); 143 return (-1); 144 } 145 146 #ifndef _LP64 147 if (ISELF && (magic_buf[EI_CLASS] == ELFCLASS32)) 148 #else 149 if (ISELF) /* 64-bit case handles both Elf32 and Elf64 */ 150 #endif 151 return (_elf_nlist(fd, list)); 152 else { 153 (void) close(fd); 154 return (-1); 155 } 156 } 157