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*51120Storek static char sccsid[] = "@(#)nlist.c 5.5 (Berkeley) 09/12/91"; 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 2446309Sbostic typedef struct nlist NLIST; 2546309Sbostic #define _strx n_un.n_strx 2646309Sbostic #define _name n_un.n_name 2746309Sbostic 2846309Sbostic static char *kfile; 2946309Sbostic 3046309Sbostic create_knlist(name, db) 3146309Sbostic char *name; 3246947Sbostic DB *db; 3346309Sbostic { 3446396Sbostic register int nsyms; 3546309Sbostic struct exec ebuf; 3646396Sbostic FILE *fp; 3746309Sbostic NLIST nbuf; 3846947Sbostic DBT data, key; 3946396Sbostic int fd, nr, strsize; 4046396Sbostic char *strtab, buf[1024]; 4146309Sbostic 4246309Sbostic kfile = name; 4346396Sbostic if ((fd = open(name, O_RDONLY, 0)) < 0) 4446309Sbostic error(name); 4546309Sbostic 4646396Sbostic /* Read in exec structure. */ 4746396Sbostic nr = read(fd, (char *)&ebuf, sizeof(struct exec)); 4846396Sbostic if (nr != sizeof(struct exec)) 4946396Sbostic badfmt(nr, "no exec header"); 5046396Sbostic 5146396Sbostic /* Check magic number and symbol count. */ 5246309Sbostic if (N_BADMAG(ebuf)) 5346309Sbostic badfmt("bad magic number"); 5446396Sbostic if (!ebuf.a_syms) 5546309Sbostic badfmt("stripped"); 5646309Sbostic 5746396Sbostic /* Seek to string table. */ 5846396Sbostic if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1) 5946396Sbostic badfmt("corrupted string table"); 6046309Sbostic 6146396Sbostic /* Read in the size of the symbol table. */ 6246396Sbostic nr = read(fd, (char *)&strsize, sizeof(strsize)); 6346396Sbostic if (nr != sizeof(strsize)) 6446396Sbostic badread(nr, "no symbol table"); 6546309Sbostic 6646396Sbostic /* Read in the string table. */ 6746396Sbostic strsize -= sizeof(strsize); 6846396Sbostic if (!(strtab = (char *)malloc(strsize))) 6946396Sbostic error(name); 7046396Sbostic if ((nr = read(fd, strtab, strsize)) != strsize) 7146396Sbostic badread(nr, "corrupted symbol table"); 7246396Sbostic 7346396Sbostic /* Seek to symbol table. */ 7446396Sbostic if (!(fp = fdopen(fd, "r"))) 7546396Sbostic error(name); 7646396Sbostic if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1) 7746396Sbostic error(name); 7846396Sbostic 7946947Sbostic data.data = (u_char *)&nbuf; 8046947Sbostic data.size = sizeof(NLIST); 8146309Sbostic 8246396Sbostic /* Read each symbol and enter it into the database. */ 8346396Sbostic nsyms = ebuf.a_syms / sizeof(struct nlist); 8446396Sbostic while (nsyms--) { 8546396Sbostic if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) { 8646396Sbostic if (feof(fp)) 8746396Sbostic badfmt("corrupted symbol table"); 8846396Sbostic error(name); 8946396Sbostic } 9046309Sbostic if (!nbuf._strx || nbuf.n_type&N_STAB) 9146309Sbostic continue; 9246309Sbostic 9346947Sbostic key.data = (u_char *)strtab + nbuf._strx - sizeof(long); 9446947Sbostic key.size = strlen((char *)key.data); 9546947Sbostic if ((db->put)(db, &key, &data, 0)) 9646947Sbostic error("put"); 9746309Sbostic 9846947Sbostic if (!strncmp((char *)key.data, VRS_SYM, sizeof(VRS_SYM) - 1)) { 9946396Sbostic off_t cur_off, rel_off, vers_off; 10046396Sbostic 10146309Sbostic /* Offset relative to start of text image in VM. */ 102*51120Storek rel_off = nbuf.n_value & ~KERNBASE; 10346309Sbostic #ifdef tahoe 10446309Sbostic /* 10546309Sbostic * On tahoe, first 0x800 is reserved for communication 10646309Sbostic * with the console processor. 10746309Sbostic */ 108*51120Storek rel_off -= 0x800; 10946309Sbostic #endif 11046309Sbostic /* 11146309Sbostic * When loaded, data is rounded to next page cluster 11246309Sbostic * after text, but not in file. 11346309Sbostic */ 11446309Sbostic rel_off -= CLBYTES - (ebuf.a_text % CLBYTES); 11546309Sbostic vers_off = N_TXTOFF(ebuf) + rel_off; 11646396Sbostic 11746396Sbostic cur_off = ftell(fp); 11846396Sbostic if (fseek(fp, vers_off, SEEK_SET) == -1) 11946309Sbostic badfmt("corrupted string table"); 12046309Sbostic 12146309Sbostic /* 12246309Sbostic * Read version string up to, and including newline. 12346309Sbostic * This code assumes that a newline terminates the 12446309Sbostic * version line. 12546309Sbostic */ 12646396Sbostic if (fgets(buf, sizeof(buf), fp) == NULL) 12746309Sbostic badfmt("corrupted string table"); 12846309Sbostic 12946947Sbostic key.data = (u_char *)VRS_KEY; 13046947Sbostic key.size = sizeof(VRS_KEY) - 1; 13146947Sbostic data.data = (u_char *)buf; 13246947Sbostic data.size = strlen(buf); 13346947Sbostic if ((db->put)(db, &key, &data, 0)) 13446947Sbostic error("put"); 13546309Sbostic 13646309Sbostic /* Restore to original values. */ 13746947Sbostic data.data = (u_char *)&nbuf; 13846947Sbostic data.size = sizeof(NLIST); 13946396Sbostic if (fseek(fp, cur_off, SEEK_SET) == -1) 14046396Sbostic badfmt("corrupted string table"); 14146309Sbostic } 14246309Sbostic } 14346396Sbostic (void)fclose(fp); 14446309Sbostic } 14546309Sbostic 14646396Sbostic badread(nr, p) 14746396Sbostic int nr; 14846396Sbostic char *p; 14946396Sbostic { 15046396Sbostic if (nr < 0) 15146396Sbostic error(kfile); 15246396Sbostic badfmt(p); 15346396Sbostic } 15446396Sbostic 15546309Sbostic badfmt(p) 15646396Sbostic char *p; 15746309Sbostic { 15846309Sbostic (void)fprintf(stderr, 159*51120Storek "kvm_mkdb: %s: %s: %s\n", kfile, p, strerror(EFTYPE)); 16046309Sbostic exit(1); 16146309Sbostic } 162