1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)nlist.c 5.8 (Berkeley) 02/23/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/types.h> 13 #include <sys/file.h> 14 #include <a.out.h> 15 #include <stdio.h> 16 #include <string.h> 17 #include <unistd.h> 18 19 typedef struct nlist NLIST; 20 #define _strx n_un.n_strx 21 #define _name n_un.n_name 22 #define ISVALID(p) (p->_name && p->_name[0]) 23 24 int 25 nlist(name, list) 26 const char *name; 27 NLIST *list; 28 { 29 register NLIST *p, *s; 30 struct exec ebuf; 31 FILE *fstr, *fsym; 32 NLIST nbuf; 33 off_t strings_offset, symbol_offset, symbol_size, lseek(); 34 int entries, len, maxlen; 35 char sbuf[256]; 36 37 entries = -1; 38 39 if (!(fsym = fopen(name, "r"))) 40 return(-1); 41 if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1 || 42 N_BADMAG(ebuf)) 43 goto done1; 44 45 symbol_offset = N_SYMOFF(ebuf); 46 symbol_size = ebuf.a_syms; 47 strings_offset = symbol_offset + symbol_size; 48 if (fseek(fsym, symbol_offset, SEEK_SET)) 49 goto done1; 50 51 if (!(fstr = fopen(name, "r"))) 52 goto done1; 53 54 /* 55 * clean out any left-over information for all valid entries. 56 * Type and value defined to be 0 if not found; historical 57 * versions cleared other and desc as well. Also figure out 58 * the largest string length so don't read any more of the 59 * string table than we have to. 60 */ 61 for (p = list, entries = maxlen = 0; ISVALID(p); ++p, ++entries) { 62 p->n_type = 0; 63 p->n_other = 0; 64 p->n_desc = 0; 65 p->n_value = 0; 66 if ((len = strlen(p->_name)) > maxlen) 67 maxlen = len; 68 } 69 if (++maxlen > sizeof(sbuf)) { /* for the NULL */ 70 (void)fprintf(stderr, "nlist: symbol too large.\n"); 71 entries = -1; 72 goto done2; 73 } 74 75 for (s = &nbuf; symbol_size; symbol_size -= sizeof(NLIST)) { 76 if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1) 77 goto done2; 78 if (!s->_strx || s->n_type&N_STAB) 79 continue; 80 if (fseek(fstr, strings_offset + s->_strx, SEEK_SET)) 81 goto done2; 82 (void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr); 83 for (p = list; ISVALID(p); p++) 84 if (!strcmp(p->_name, sbuf)) { 85 p->n_value = s->n_value; 86 p->n_type = s->n_type; 87 p->n_desc = s->n_desc; 88 p->n_other = s->n_other; 89 if (!--entries) 90 goto done2; 91 } 92 } 93 done2: (void)fclose(fstr); 94 done1: (void)fclose(fsym); 95 return(entries); 96 } 97