Commit | Line | Data |
---|---|---|
bb0cfa24 | 1 | /* |
4142a2c4 KB |
2 | * Copyright (c) 1989 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
269a7923 | 5 | * %sccs.include.redist.c% |
bb0cfa24 DF |
6 | */ |
7 | ||
2ce81398 | 8 | #if defined(LIBC_SCCS) && !defined(lint) |
269a7923 | 9 | static char sccsid[] = "@(#)nlist.c 5.7 (Berkeley) %G%"; |
4142a2c4 | 10 | #endif /* LIBC_SCCS and not lint */ |
329a2d40 | 11 | |
8fb9f90e | 12 | #include <sys/types.h> |
4142a2c4 | 13 | #include <sys/file.h> |
8fb9f90e BJ |
14 | #include <a.out.h> |
15 | #include <stdio.h> | |
4142a2c4 KB |
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]) | |
8fb9f90e | 22 | |
8fb9f90e BJ |
23 | nlist(name, list) |
24 | char *name; | |
4142a2c4 | 25 | NLIST *list; |
8fb9f90e | 26 | { |
4142a2c4 KB |
27 | register NLIST *p, *s; |
28 | struct exec ebuf; | |
29 | FILE *fstr, *fsym; | |
30 | NLIST nbuf; | |
76ecedf8 | 31 | off_t strings_offset, symbol_offset, symbol_size, lseek(); |
4142a2c4 KB |
32 | int entries, len, maxlen; |
33 | char sbuf[256]; | |
8fb9f90e | 34 | |
4142a2c4 KB |
35 | entries = -1; |
36 | ||
37 | if (!(fsym = fopen(name, "r"))) | |
329a2d40 | 38 | return(-1); |
4142a2c4 KB |
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 | ||
4142a2c4 KB |
49 | if (!(fstr = fopen(name, "r"))) |
50 | goto done1; | |
4142a2c4 KB |
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; | |
329a2d40 | 71 | } |
8fb9f90e | 72 | |
12fe6f30 | 73 | for (s = &nbuf; symbol_size; symbol_size -= sizeof(NLIST)) { |
4142a2c4 KB |
74 | if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1) |
75 | goto done2; | |
76 | if (!s->_strx || s->n_type&N_STAB) | |
77 | continue; | |
76ecedf8 | 78 | if (fseek(fstr, strings_offset + s->_strx, SEEK_SET)) |
4142a2c4 | 79 | goto done2; |
76ecedf8 | 80 | (void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr); |
4142a2c4 KB |
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; | |
8fb9f90e | 89 | } |
8fb9f90e | 90 | } |
4142a2c4 KB |
91 | done2: (void)fclose(fstr); |
92 | done1: (void)fclose(fsym); | |
93 | return(entries); | |
8fb9f90e | 94 | } |