xref: /original-bsd/lib/libc/gen/nlist.c (revision c7ce21e7)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #if defined(LIBC_SCCS) && !defined(lint)
8 static char sccsid[] = "@(#)nlist.c	5.2 (Berkeley) 03/09/86";
9 #endif LIBC_SCCS and not lint
10 
11 #include <sys/types.h>
12 #include <a.out.h>
13 #include <stdio.h>
14 
15 /*
16  * nlist - retreive attributes from name list (string table version)
17  */
18 nlist(name, list)
19 	char *name;
20 	struct nlist *list;
21 {
22 	register struct nlist *p, *q;
23 	register char *s1, *s2;
24 	register n, m;
25 	int maxlen, nreq;
26 	FILE *f;
27 	FILE *sf;
28 	off_t sa;		/* symbol address */
29 	off_t ss;		/* start of strings */
30 	struct exec buf;
31 	struct nlist space[BUFSIZ/sizeof (struct nlist)];
32 
33 	maxlen = 0;
34 	for (q = list, nreq = 0; q->n_un.n_name && q->n_un.n_name[0]; q++, nreq++) {
35 		q->n_type = 0;
36 		q->n_value = 0;
37 		q->n_desc = 0;
38 		q->n_other = 0;
39 		n = strlen(q->n_un.n_name);
40 		if (n > maxlen)
41 			maxlen = n;
42 	}
43 	f = fopen(name, "r");
44 	if (f == NULL)
45 		return (-1);
46 	fread((char *)&buf, sizeof buf, 1, f);
47 	if (N_BADMAG(buf)) {
48 		fclose(f);
49 		return (-1);
50 	}
51 	sf = fopen(name, "r");
52 	if (sf == NULL) {
53 		/* ??? */
54 		fclose(f);
55 		return(-1);
56 	}
57 	sa = N_SYMOFF(buf);
58 	ss = sa + buf.a_syms;
59 	n = buf.a_syms;
60 	fseek(f, sa, 0);
61 	while (n) {
62 		m = sizeof (space);
63 		if (n < m)
64 			m = n;
65 		if (fread((char *)space, m, 1, f) != 1)
66 			break;
67 		n -= m;
68 		for (q = space; (m -= sizeof(struct nlist)) >= 0; q++) {
69 			char nambuf[BUFSIZ];
70 
71 			if (q->n_un.n_strx == 0 || q->n_type & N_STAB)
72 				continue;
73 			fseek(sf, ss+q->n_un.n_strx, 0);
74 			fread(nambuf, maxlen+1, 1, sf);
75 			for (p = list; p->n_un.n_name && p->n_un.n_name[0]; p++) {
76 				s1 = p->n_un.n_name;
77 				s2 = nambuf;
78 				while (*s1) {
79 					if (*s1++ != *s2++)
80 						goto cont;
81 				}
82 				if (*s2)
83 					goto cont;
84 				p->n_value = q->n_value;
85 				p->n_type = q->n_type;
86 				p->n_desc = q->n_desc;
87 				p->n_other = q->n_other;
88 				if (--nreq == 0)
89 					goto alldone;
90 				break;
91 		cont:		;
92 			}
93 		}
94 	}
95 alldone:
96 	fclose(f);
97 	fclose(sf);
98 	return (nreq);
99 }
100