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