1: /* 2: * Copyright (c) 1989 The Regents of the University of California. 3: * All rights reserved. 4: * 5: * Redistribution and use in source and binary forms are permitted 6: * provided that: (1) source distributions retain this entire copyright 7: * notice and comment, and (2) distributions including binaries display 8: * the following acknowledgement: ``This product includes software 9: * developed by the University of California, Berkeley and its contributors'' 10: * in the documentation or other materials provided with the distribution 11: * and in all advertising materials mentioning features or use of this 12: * software. Neither the name of the University nor the names of its 13: * contributors may be used to endorse or promote products derived 14: * from this software without specific prior written permission. 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 18: */ 19: 20: #if defined(LIBC_SCCS) && !defined(lint) 21: static char sccsid[] = "@(#)nlist.c 5.7.1 (2.11BSD GTE) 12/31/93"; 22: #endif 23: 24: #include <sys/types.h> 25: #include <sys/file.h> 26: #include <a.out.h> 27: #include <stdio.h> 28: 29: typedef struct nlist NLIST; 30: #define _strx n_un.n_strx 31: #define _name n_un.n_name 32: #define ISVALID(p) (p->_name && p->_name[0]) 33: 34: nlist(name, list) 35: char *name; 36: NLIST *list; 37: { 38: register NLIST *p, *s; 39: struct xexec ebuf; 40: FILE *fstr, *fsym; 41: NLIST nbuf; 42: off_t strings_offset, symbol_offset, symbol_size, lseek(); 43: int entries, len, maxlen; 44: char sbuf[128]; 45: 46: entries = -1; 47: 48: if (!(fsym = fopen(name, "r"))) 49: return(-1); 50: if (fread((char *)&ebuf, 1, sizeof(ebuf), fsym) < sizeof (ebuf.e) || 51: N_BADMAG(ebuf.e)) 52: goto done1; 53: 54: symbol_offset = N_SYMOFF(ebuf); 55: symbol_size = ebuf.e.a_syms; 56: strings_offset = N_STROFF(ebuf); 57: if (fseek(fsym, symbol_offset, L_SET)) 58: goto done1; 59: 60: if (!(fstr = fopen(name, "r"))) 61: goto done1; 62: 63: /* 64: * clean out any left-over information for all valid entries. 65: * Type and value defined to be 0 if not found; historical 66: * versions cleared other and desc as well. Also figure out 67: * the largest string length so don't read any more of the 68: * string table than we have to. 69: */ 70: for (p = list, entries = maxlen = 0; ISVALID(p); ++p, ++entries) { 71: p->n_type = 0; 72: p->n_ovly = 0; 73: p->n_value = 0; 74: if ((len = strlen(p->_name)) > maxlen) 75: maxlen = len; 76: } 77: if (++maxlen > sizeof(sbuf)) { /* for the NULL */ 78: (void)fprintf(stderr, "nlist: sym 2 big\n"); 79: entries = -1; 80: goto done2; 81: } 82: 83: for (s = &nbuf; symbol_size; symbol_size -= sizeof(NLIST)) { 84: if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1) 85: goto done2; 86: if (!s->_strx) 87: continue; 88: if (fseek(fstr, strings_offset + s->_strx, L_SET)) 89: goto done2; 90: (void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr); 91: for (p = list; ISVALID(p); p++) 92: if (!strcmp(p->_name, sbuf)) { 93: p->n_value = s->n_value; 94: p->n_type = s->n_type; 95: p->n_ovly = s->n_ovly; 96: if (!--entries) 97: goto done2; 98: } 99: } 100: done2: (void)fclose(fstr); 101: done1: (void)fclose(fsym); 102: return(entries); 103: }