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