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) |
c5980113 | 9 | static char sccsid[] = "@(#)nlist.c 5.8 (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> | |
c5980113 | 16 | #include <string.h> |
4142a2c4 KB |
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]) | |
8fb9f90e | 23 | |
c5980113 | 24 | int |
8fb9f90e | 25 | nlist(name, list) |
c5980113 | 26 | const char *name; |
4142a2c4 | 27 | NLIST *list; |
8fb9f90e | 28 | { |
4142a2c4 KB |
29 | register NLIST *p, *s; |
30 | struct exec ebuf; | |
31 | FILE *fstr, *fsym; | |
32 | NLIST nbuf; | |
76ecedf8 | 33 | off_t strings_offset, symbol_offset, symbol_size, lseek(); |
4142a2c4 KB |
34 | int entries, len, maxlen; |
35 | char sbuf[256]; | |
8fb9f90e | 36 | |
4142a2c4 KB |
37 | entries = -1; |
38 | ||
39 | if (!(fsym = fopen(name, "r"))) | |
329a2d40 | 40 | return(-1); |
4142a2c4 KB |
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 | ||
4142a2c4 KB |
51 | if (!(fstr = fopen(name, "r"))) |
52 | goto done1; | |
4142a2c4 KB |
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; | |
329a2d40 | 73 | } |
8fb9f90e | 74 | |
12fe6f30 | 75 | for (s = &nbuf; symbol_size; symbol_size -= sizeof(NLIST)) { |
4142a2c4 KB |
76 | if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1) |
77 | goto done2; | |
78 | if (!s->_strx || s->n_type&N_STAB) | |
79 | continue; | |
76ecedf8 | 80 | if (fseek(fstr, strings_offset + s->_strx, SEEK_SET)) |
4142a2c4 | 81 | goto done2; |
76ecedf8 | 82 | (void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr); |
4142a2c4 KB |
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; | |
8fb9f90e | 91 | } |
8fb9f90e | 92 | } |
4142a2c4 KB |
93 | done2: (void)fclose(fstr); |
94 | done1: (void)fclose(fsym); | |
95 | return(entries); | |
8fb9f90e | 96 | } |