xref: /csrg-svn/usr.sbin/kvm_mkdb/nlist.c (revision 61838)
146309Sbostic /*-
2*61838Sbostic  * Copyright (c) 1990, 1993
3*61838Sbostic  *	The Regents of the University of California.  All rights reserved.
446309Sbostic  *
546309Sbostic  * %sccs.include.redist.c%
646309Sbostic  */
746309Sbostic 
846309Sbostic #ifndef lint
9*61838Sbostic static char sccsid[] = "@(#)nlist.c	8.1 (Berkeley) 06/06/93";
1046309Sbostic #endif /* not lint */
1146309Sbostic 
1246309Sbostic #include <sys/param.h>
1359022Sbostic 
1446309Sbostic #include <a.out.h>
1546947Sbostic #include <db.h>
1659022Sbostic #include <err.h>
1746396Sbostic #include <errno.h>
1859022Sbostic #include <fcntl.h>
1946309Sbostic #include <kvm.h>
2059022Sbostic #include <limits.h>
2146309Sbostic #include <stdio.h>
2259022Sbostic #include <stdlib.h>
2346396Sbostic #include <string.h>
2459022Sbostic #include <unistd.h>
2546309Sbostic 
2653326Sbostic #include "extern.h"
2753326Sbostic 
2846309Sbostic typedef struct nlist NLIST;
2946309Sbostic #define	_strx	n_un.n_strx
3046309Sbostic #define	_name	n_un.n_name
3146309Sbostic 
3259022Sbostic #define	badfmt(str)	errx(1, "%s: %s: %s", kfile, str, strerror(EFTYPE))
3359022Sbostic 
3453326Sbostic static void badread __P((int, char *));
3553326Sbostic 
3646309Sbostic static char *kfile;
3746309Sbostic 
3853326Sbostic void
create_knlist(name,db)3946309Sbostic create_knlist(name, db)
4046309Sbostic 	char *name;
4146947Sbostic 	DB *db;
4246309Sbostic {
4346396Sbostic 	register int nsyms;
4446309Sbostic 	struct exec ebuf;
4546396Sbostic 	FILE *fp;
4646309Sbostic 	NLIST nbuf;
4746947Sbostic 	DBT data, key;
4846396Sbostic 	int fd, nr, strsize;
4946396Sbostic 	char *strtab, buf[1024];
5046309Sbostic 
5146309Sbostic 	kfile = name;
5246396Sbostic 	if ((fd = open(name, O_RDONLY, 0)) < 0)
5359022Sbostic 		err(1, "%s", name);
5446309Sbostic 
5546396Sbostic 	/* Read in exec structure. */
5659022Sbostic 	nr = read(fd, &ebuf, sizeof(struct exec));
5746396Sbostic 	if (nr != sizeof(struct exec))
5853326Sbostic 		badfmt("no exec header");
5946396Sbostic 
6046396Sbostic 	/* Check magic number and symbol count. */
6146309Sbostic 	if (N_BADMAG(ebuf))
6246309Sbostic 		badfmt("bad magic number");
6346396Sbostic 	if (!ebuf.a_syms)
6446309Sbostic 		badfmt("stripped");
6546309Sbostic 
6646396Sbostic 	/* Seek to string table. */
6746396Sbostic 	if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1)
6846396Sbostic 		badfmt("corrupted string table");
6946309Sbostic 
7046396Sbostic 	/* Read in the size of the symbol table. */
7146396Sbostic 	nr = read(fd, (char *)&strsize, sizeof(strsize));
7246396Sbostic 	if (nr != sizeof(strsize))
7346396Sbostic 		badread(nr, "no symbol table");
7446309Sbostic 
7546396Sbostic 	/* Read in the string table. */
7646396Sbostic 	strsize -= sizeof(strsize);
7759022Sbostic 	if (!(strtab = malloc(strsize)))
7859022Sbostic 		err(1, NULL);
7946396Sbostic 	if ((nr = read(fd, strtab, strsize)) != strsize)
8046396Sbostic 		badread(nr, "corrupted symbol table");
8146396Sbostic 
8246396Sbostic 	/* Seek to symbol table. */
8346396Sbostic 	if (!(fp = fdopen(fd, "r")))
8459022Sbostic 		err(1, "%s", name);
8546396Sbostic 	if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1)
8659022Sbostic 		err(1, "%s", name);
8746396Sbostic 
8846947Sbostic 	data.data = (u_char *)&nbuf;
8946947Sbostic 	data.size = sizeof(NLIST);
9046309Sbostic 
9146396Sbostic 	/* Read each symbol and enter it into the database. */
9246396Sbostic 	nsyms = ebuf.a_syms / sizeof(struct nlist);
9346396Sbostic 	while (nsyms--) {
9446396Sbostic 		if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) {
9546396Sbostic 			if (feof(fp))
9646396Sbostic 				badfmt("corrupted symbol table");
9759022Sbostic 			err(1, "%s", name);
9846396Sbostic 		}
9946309Sbostic 		if (!nbuf._strx || nbuf.n_type&N_STAB)
10046309Sbostic 			continue;
10146309Sbostic 
10246947Sbostic 		key.data = (u_char *)strtab + nbuf._strx - sizeof(long);
10346947Sbostic 		key.size = strlen((char *)key.data);
10459022Sbostic 		if (db->put(db, &key, &data, 0))
10559022Sbostic 			err(1, "record enter");
10646309Sbostic 
10753326Sbostic 		if (strcmp((char *)key.data, VRS_SYM) == 0) {
10854587Sbostic 			long cur_off, voff;
10953326Sbostic #ifndef KERNTEXTOFF
11053326Sbostic #define KERNTEXTOFF KERNBASE
11146309Sbostic #endif
11246309Sbostic 			/*
11353326Sbostic 			 * Calculate offset relative to a normal (non-kernel)
11453326Sbostic 			 * a.out.  KERNTEXTOFF is where the kernel is really
11553326Sbostic 			 * loaded; N_TXTADDR is where a normal file is loaded.
11653326Sbostic 			 * From there, locate file offset in text or data.
11746309Sbostic 			 */
11853326Sbostic 			voff = nbuf.n_value - KERNTEXTOFF + N_TXTADDR(ebuf);
11953326Sbostic 			if ((nbuf.n_type & N_TYPE) == N_TEXT)
12053326Sbostic 				voff += N_TXTOFF(ebuf) - N_TXTADDR(ebuf);
12153326Sbostic 			else
12253326Sbostic 				voff += N_DATOFF(ebuf) - N_DATADDR(ebuf);
12346396Sbostic 			cur_off = ftell(fp);
12453326Sbostic 			if (fseek(fp, voff, SEEK_SET) == -1)
12546309Sbostic 				badfmt("corrupted string table");
12646309Sbostic 
12746309Sbostic 			/*
12846309Sbostic 			 * Read version string up to, and including newline.
12946309Sbostic 			 * This code assumes that a newline terminates the
13046309Sbostic 			 * version line.
13146309Sbostic 			 */
13246396Sbostic 			if (fgets(buf, sizeof(buf), fp) == NULL)
13346309Sbostic 				badfmt("corrupted string table");
13446309Sbostic 
13546947Sbostic 			key.data = (u_char *)VRS_KEY;
13646947Sbostic 			key.size = sizeof(VRS_KEY) - 1;
13746947Sbostic 			data.data = (u_char *)buf;
13846947Sbostic 			data.size = strlen(buf);
13959022Sbostic 			if (db->put(db, &key, &data, 0))
14059022Sbostic 				err(1, "record enter");
14146309Sbostic 
14246309Sbostic 			/* Restore to original values. */
14346947Sbostic 			data.data = (u_char *)&nbuf;
14446947Sbostic 			data.size = sizeof(NLIST);
14546396Sbostic 			if (fseek(fp, cur_off, SEEK_SET) == -1)
14646396Sbostic 				badfmt("corrupted string table");
14746309Sbostic 		}
14846309Sbostic 	}
14946396Sbostic 	(void)fclose(fp);
15046309Sbostic }
15146309Sbostic 
15253326Sbostic static void
badread(nr,p)15346396Sbostic badread(nr, p)
15446396Sbostic 	int nr;
15546396Sbostic 	char *p;
15646396Sbostic {
15746396Sbostic 	if (nr < 0)
15859022Sbostic 		err(1, "%s", kfile);
15946396Sbostic 	badfmt(p);
16046396Sbostic }
161