146309Sbostic /*- 246309Sbostic * Copyright (c) 1990 The Regents of the University of California. 346309Sbostic * All rights reserved. 446309Sbostic * 546309Sbostic * %sccs.include.redist.c% 646309Sbostic */ 746309Sbostic 846309Sbostic #ifndef lint 9*53326Sbostic static char sccsid[] = "@(#)nlist.c 5.6 (Berkeley) 05/04/92"; 1046309Sbostic #endif /* not lint */ 1146309Sbostic 1246309Sbostic #include <sys/param.h> 1346396Sbostic #include <fcntl.h> 1446309Sbostic #include <limits.h> 1546309Sbostic #include <a.out.h> 1646947Sbostic #include <db.h> 1746396Sbostic #include <errno.h> 1846396Sbostic #include <unistd.h> 1946309Sbostic #include <kvm.h> 2046309Sbostic #include <stdio.h> 2146396Sbostic #include <string.h> 2246396Sbostic #include <stdlib.h> 2346309Sbostic 24*53326Sbostic #include "extern.h" 25*53326Sbostic 2646309Sbostic typedef struct nlist NLIST; 2746309Sbostic #define _strx n_un.n_strx 2846309Sbostic #define _name n_un.n_name 2946309Sbostic 30*53326Sbostic static void badread __P((int, char *)); 31*53326Sbostic static void badfmt __P((char *)); 32*53326Sbostic 3346309Sbostic static char *kfile; 3446309Sbostic 35*53326Sbostic void 3646309Sbostic create_knlist(name, db) 3746309Sbostic char *name; 3846947Sbostic DB *db; 3946309Sbostic { 4046396Sbostic register int nsyms; 4146309Sbostic struct exec ebuf; 4246396Sbostic FILE *fp; 4346309Sbostic NLIST nbuf; 4446947Sbostic DBT data, key; 4546396Sbostic int fd, nr, strsize; 4646396Sbostic char *strtab, buf[1024]; 4746309Sbostic 4846309Sbostic kfile = name; 4946396Sbostic if ((fd = open(name, O_RDONLY, 0)) < 0) 5046309Sbostic error(name); 5146309Sbostic 5246396Sbostic /* Read in exec structure. */ 5346396Sbostic nr = read(fd, (char *)&ebuf, sizeof(struct exec)); 5446396Sbostic if (nr != sizeof(struct exec)) 55*53326Sbostic badfmt("no exec header"); 5646396Sbostic 5746396Sbostic /* Check magic number and symbol count. */ 5846309Sbostic if (N_BADMAG(ebuf)) 5946309Sbostic badfmt("bad magic number"); 6046396Sbostic if (!ebuf.a_syms) 6146309Sbostic badfmt("stripped"); 6246309Sbostic 6346396Sbostic /* Seek to string table. */ 6446396Sbostic if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1) 6546396Sbostic badfmt("corrupted string table"); 6646309Sbostic 6746396Sbostic /* Read in the size of the symbol table. */ 6846396Sbostic nr = read(fd, (char *)&strsize, sizeof(strsize)); 6946396Sbostic if (nr != sizeof(strsize)) 7046396Sbostic badread(nr, "no symbol table"); 7146309Sbostic 7246396Sbostic /* Read in the string table. */ 7346396Sbostic strsize -= sizeof(strsize); 7446396Sbostic if (!(strtab = (char *)malloc(strsize))) 7546396Sbostic error(name); 7646396Sbostic if ((nr = read(fd, strtab, strsize)) != strsize) 7746396Sbostic badread(nr, "corrupted symbol table"); 7846396Sbostic 7946396Sbostic /* Seek to symbol table. */ 8046396Sbostic if (!(fp = fdopen(fd, "r"))) 8146396Sbostic error(name); 8246396Sbostic if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1) 8346396Sbostic error(name); 8446396Sbostic 8546947Sbostic data.data = (u_char *)&nbuf; 8646947Sbostic data.size = sizeof(NLIST); 8746309Sbostic 8846396Sbostic /* Read each symbol and enter it into the database. */ 8946396Sbostic nsyms = ebuf.a_syms / sizeof(struct nlist); 9046396Sbostic while (nsyms--) { 9146396Sbostic if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) { 9246396Sbostic if (feof(fp)) 9346396Sbostic badfmt("corrupted symbol table"); 9446396Sbostic error(name); 9546396Sbostic } 9646309Sbostic if (!nbuf._strx || nbuf.n_type&N_STAB) 9746309Sbostic continue; 9846309Sbostic 9946947Sbostic key.data = (u_char *)strtab + nbuf._strx - sizeof(long); 10046947Sbostic key.size = strlen((char *)key.data); 10146947Sbostic if ((db->put)(db, &key, &data, 0)) 10246947Sbostic error("put"); 10346309Sbostic 104*53326Sbostic if (strcmp((char *)key.data, VRS_SYM) == 0) { 105*53326Sbostic off_t cur_off, voff; 106*53326Sbostic #ifndef KERNTEXTOFF 107*53326Sbostic #define KERNTEXTOFF KERNBASE 10846309Sbostic #endif 10946309Sbostic /* 110*53326Sbostic * Calculate offset relative to a normal (non-kernel) 111*53326Sbostic * a.out. KERNTEXTOFF is where the kernel is really 112*53326Sbostic * loaded; N_TXTADDR is where a normal file is loaded. 113*53326Sbostic * From there, locate file offset in text or data. 11446309Sbostic */ 115*53326Sbostic voff = nbuf.n_value - KERNTEXTOFF + N_TXTADDR(ebuf); 116*53326Sbostic if ((nbuf.n_type & N_TYPE) == N_TEXT) 117*53326Sbostic voff += N_TXTOFF(ebuf) - N_TXTADDR(ebuf); 118*53326Sbostic else 119*53326Sbostic voff += N_DATOFF(ebuf) - N_DATADDR(ebuf); 12046396Sbostic cur_off = ftell(fp); 121*53326Sbostic if (fseek(fp, voff, SEEK_SET) == -1) 12246309Sbostic badfmt("corrupted string table"); 12346309Sbostic 12446309Sbostic /* 12546309Sbostic * Read version string up to, and including newline. 12646309Sbostic * This code assumes that a newline terminates the 12746309Sbostic * version line. 12846309Sbostic */ 12946396Sbostic if (fgets(buf, sizeof(buf), fp) == NULL) 13046309Sbostic badfmt("corrupted string table"); 13146309Sbostic 13246947Sbostic key.data = (u_char *)VRS_KEY; 13346947Sbostic key.size = sizeof(VRS_KEY) - 1; 13446947Sbostic data.data = (u_char *)buf; 13546947Sbostic data.size = strlen(buf); 13646947Sbostic if ((db->put)(db, &key, &data, 0)) 13746947Sbostic error("put"); 13846309Sbostic 13946309Sbostic /* Restore to original values. */ 14046947Sbostic data.data = (u_char *)&nbuf; 14146947Sbostic data.size = sizeof(NLIST); 14246396Sbostic if (fseek(fp, cur_off, SEEK_SET) == -1) 14346396Sbostic badfmt("corrupted string table"); 14446309Sbostic } 14546309Sbostic } 14646396Sbostic (void)fclose(fp); 14746309Sbostic } 14846309Sbostic 149*53326Sbostic static void 15046396Sbostic badread(nr, p) 15146396Sbostic int nr; 15246396Sbostic char *p; 15346396Sbostic { 15446396Sbostic if (nr < 0) 15546396Sbostic error(kfile); 15646396Sbostic badfmt(p); 15746396Sbostic } 15846396Sbostic 159*53326Sbostic static void 16046309Sbostic badfmt(p) 16146396Sbostic char *p; 16246309Sbostic { 16346309Sbostic (void)fprintf(stderr, 16451120Storek "kvm_mkdb: %s: %s: %s\n", kfile, p, strerror(EFTYPE)); 16546309Sbostic exit(1); 16646309Sbostic } 167