xref: /csrg-svn/usr.sbin/kvm_mkdb/nlist.c (revision 46309)
1*46309Sbostic /*-
2*46309Sbostic  * Copyright (c) 1990 The Regents of the University of California.
3*46309Sbostic  * All rights reserved.
4*46309Sbostic  *
5*46309Sbostic  * %sccs.include.redist.c%
6*46309Sbostic  */
7*46309Sbostic 
8*46309Sbostic #ifndef lint
9*46309Sbostic static char sccsid[] = "@(#)nlist.c	5.1 (Berkeley) 02/06/91";
10*46309Sbostic #endif /* not lint */
11*46309Sbostic 
12*46309Sbostic #include <sys/param.h>
13*46309Sbostic #include <errno.h>
14*46309Sbostic #include <limits.h>
15*46309Sbostic #include <ndbm.h>
16*46309Sbostic #include <a.out.h>
17*46309Sbostic #include <kvm.h>
18*46309Sbostic #include <unistd.h>
19*46309Sbostic #include <stdio.h>
20*46309Sbostic 
21*46309Sbostic typedef struct nlist NLIST;
22*46309Sbostic #define	_strx	n_un.n_strx
23*46309Sbostic #define	_name	n_un.n_name
24*46309Sbostic 
25*46309Sbostic #define	BFLEN		1024
26*46309Sbostic #define	VRS		"_version"
27*46309Sbostic 
28*46309Sbostic static char *kfile;
29*46309Sbostic 
30*46309Sbostic create_knlist(name, db)
31*46309Sbostic 	char *name;
32*46309Sbostic 	DBM *db;
33*46309Sbostic {
34*46309Sbostic 	register char *bp;
35*46309Sbostic 	register int ch, len;
36*46309Sbostic 	struct exec ebuf;
37*46309Sbostic 	FILE *fstr, *fsym;
38*46309Sbostic 	NLIST nbuf;
39*46309Sbostic 	off_t string_off, symbol_off, symbol_size;
40*46309Sbostic 	off_t rel_off, vers_off;
41*46309Sbostic 	datum key, data;
42*46309Sbostic 	char sbuf[BFLEN];
43*46309Sbostic 
44*46309Sbostic 	/* Two pointers, one for symbol table and one for string table. */
45*46309Sbostic 	kfile = name;
46*46309Sbostic 	if ((fsym = fopen(name, "r")) == NULL ||
47*46309Sbostic 	    (fstr = fopen(name, "r")) == NULL)
48*46309Sbostic 		error(name);
49*46309Sbostic 
50*46309Sbostic 	if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1)
51*46309Sbostic 		badfmt("no exec header");
52*46309Sbostic 	if (N_BADMAG(ebuf))
53*46309Sbostic 		badfmt("bad magic number");
54*46309Sbostic 
55*46309Sbostic 	symbol_size = ebuf.a_syms;
56*46309Sbostic 	if (!symbol_size)
57*46309Sbostic 		badfmt("stripped");
58*46309Sbostic 
59*46309Sbostic 	symbol_off = N_SYMOFF(ebuf);
60*46309Sbostic 	string_off = symbol_off + symbol_size;
61*46309Sbostic 
62*46309Sbostic 	if (fseek(fsym, symbol_off, SEEK_SET) == -1)
63*46309Sbostic 		badfmt("corrupted symbol table");
64*46309Sbostic 
65*46309Sbostic 	key.dptr = sbuf;
66*46309Sbostic 	data.dptr = (char *)&nbuf;
67*46309Sbostic 	data.dsize = sizeof(NLIST);
68*46309Sbostic 
69*46309Sbostic 	for (; symbol_size; symbol_size -= sizeof(NLIST)) {
70*46309Sbostic 		if (fread((char *)&nbuf, sizeof (NLIST), 1, fsym) != 1)
71*46309Sbostic 			badfmt("corrupted symbol table");
72*46309Sbostic 		if (!nbuf._strx || nbuf.n_type&N_STAB)
73*46309Sbostic 			continue;
74*46309Sbostic 		if (fseek(fstr, string_off + nbuf._strx, SEEK_SET) == -1)
75*46309Sbostic 			badfmt("corrupted string table");
76*46309Sbostic 
77*46309Sbostic 		/* Read string. */
78*46309Sbostic 		bp = sbuf;
79*46309Sbostic 		for (len = 0; (ch = getc(fstr)) != EOF && ch != '\0';) {
80*46309Sbostic 			if (++len == BFLEN) {
81*46309Sbostic 				(void)fprintf(stderr,
82*46309Sbostic 				    "kvm_mkdb: symbol too long.");
83*46309Sbostic 				break;
84*46309Sbostic 			}
85*46309Sbostic 			*bp++ = ch;
86*46309Sbostic 		}
87*46309Sbostic 		if (len == BFLEN)
88*46309Sbostic 			continue;
89*46309Sbostic 
90*46309Sbostic 		/* Store string. */
91*46309Sbostic 		key.dsize = len;
92*46309Sbostic 		if (dbm_store(db, key, data, DBM_INSERT) < 0)
93*46309Sbostic 			error("dbm_store");
94*46309Sbostic 
95*46309Sbostic 		if (!strncmp(sbuf, VRS, sizeof(VRS) - 1)) {
96*46309Sbostic 			/* Offset relative to start of text image in VM. */
97*46309Sbostic #ifdef hp300
98*46309Sbostic 			rel_off = nbuf.n_value;
99*46309Sbostic #endif
100*46309Sbostic #ifdef tahoe
101*46309Sbostic 			/*
102*46309Sbostic 			 * On tahoe, first 0x800 is reserved for communication
103*46309Sbostic 			 * with the console processor.
104*46309Sbostic 			 */
105*46309Sbostic 			rel_off = ((nbuf.n_value & ~KERNBASE) - 0x800);
106*46309Sbostic #endif
107*46309Sbostic #ifdef vax
108*46309Sbostic 			rel_off = nbuf.n_value & ~KERNBASE;
109*46309Sbostic #endif
110*46309Sbostic 			/*
111*46309Sbostic 			 * When loaded, data is rounded to next page cluster
112*46309Sbostic 			 * after text, but not in file.
113*46309Sbostic 			 */
114*46309Sbostic 			rel_off -= CLBYTES - (ebuf.a_text % CLBYTES);
115*46309Sbostic 			vers_off = N_TXTOFF(ebuf) + rel_off;
116*46309Sbostic 			if (fseek(fstr, vers_off, SEEK_SET) == -1)
117*46309Sbostic 				badfmt("corrupted string table");
118*46309Sbostic 
119*46309Sbostic 			/*
120*46309Sbostic 			 * Read version string up to, and including newline.
121*46309Sbostic 			 * This code assumes that a newline terminates the
122*46309Sbostic 			 * version line.
123*46309Sbostic 			 */
124*46309Sbostic 			if (fgets(sbuf, sizeof(sbuf), fstr) == NULL)
125*46309Sbostic 				badfmt("corrupted string table");
126*46309Sbostic 
127*46309Sbostic 			key.dptr = VERSION;
128*46309Sbostic 			key.dsize = sizeof(VERSION) - 1;
129*46309Sbostic 			data.dptr = sbuf;
130*46309Sbostic 			data.dsize = strlen(sbuf);
131*46309Sbostic 			if (dbm_store(db, key, data, DBM_INSERT) < 0)
132*46309Sbostic 				error("dbm_store");
133*46309Sbostic 
134*46309Sbostic 			/* Restore to original values. */
135*46309Sbostic 			key.dptr = sbuf;
136*46309Sbostic 			data.dptr = (char *)&nbuf;
137*46309Sbostic 			data.dsize = sizeof(NLIST);
138*46309Sbostic 		}
139*46309Sbostic 	}
140*46309Sbostic 	(void)fclose(fstr);
141*46309Sbostic 	(void)fclose(fsym);
142*46309Sbostic }
143*46309Sbostic 
144*46309Sbostic badfmt(p)
145*46309Sbostic {
146*46309Sbostic 	(void)fprintf(stderr,
147*46309Sbostic 	    "symorder: %s: %s: %s\n", kfile, p, strerror(EFTYPE));
148*46309Sbostic 	exit(1);
149*46309Sbostic }
150