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*46947Sbostic static char sccsid[] = "@(#)nlist.c 5.3 (Berkeley) 03/03/91"; 1046309Sbostic #endif /* not lint */ 1146309Sbostic 1246309Sbostic #include <sys/param.h> 13*46947Sbostic #include <sys/user.h> 1446396Sbostic #include <fcntl.h> 1546309Sbostic #include <limits.h> 1646309Sbostic #include <a.out.h> 17*46947Sbostic #include <db.h> 1846396Sbostic #include <errno.h> 1946396Sbostic #include <unistd.h> 2046309Sbostic #include <kvm.h> 2146309Sbostic #include <stdio.h> 2246396Sbostic #include <string.h> 2346396Sbostic #include <stdlib.h> 2446309Sbostic 2546309Sbostic typedef struct nlist NLIST; 2646309Sbostic #define _strx n_un.n_strx 2746309Sbostic #define _name n_un.n_name 2846309Sbostic 2946309Sbostic static char *kfile; 3046309Sbostic 3146309Sbostic create_knlist(name, db) 3246309Sbostic char *name; 33*46947Sbostic DB *db; 3446309Sbostic { 3546396Sbostic register int nsyms; 3646309Sbostic struct exec ebuf; 3746396Sbostic FILE *fp; 3846309Sbostic NLIST nbuf; 39*46947Sbostic DBT data, key; 4046396Sbostic int fd, nr, strsize; 4146396Sbostic char *strtab, buf[1024]; 4246309Sbostic 4346309Sbostic kfile = name; 4446396Sbostic if ((fd = open(name, O_RDONLY, 0)) < 0) 4546309Sbostic error(name); 4646309Sbostic 4746396Sbostic /* Read in exec structure. */ 4846396Sbostic nr = read(fd, (char *)&ebuf, sizeof(struct exec)); 4946396Sbostic if (nr != sizeof(struct exec)) 5046396Sbostic badfmt(nr, "no exec header"); 5146396Sbostic 5246396Sbostic /* Check magic number and symbol count. */ 5346309Sbostic if (N_BADMAG(ebuf)) 5446309Sbostic badfmt("bad magic number"); 5546396Sbostic if (!ebuf.a_syms) 5646309Sbostic badfmt("stripped"); 5746309Sbostic 5846396Sbostic /* Seek to string table. */ 5946396Sbostic if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1) 6046396Sbostic badfmt("corrupted string table"); 6146309Sbostic 6246396Sbostic /* Read in the size of the symbol table. */ 6346396Sbostic nr = read(fd, (char *)&strsize, sizeof(strsize)); 6446396Sbostic if (nr != sizeof(strsize)) 6546396Sbostic badread(nr, "no symbol table"); 6646309Sbostic 6746396Sbostic /* Read in the string table. */ 6846396Sbostic strsize -= sizeof(strsize); 6946396Sbostic if (!(strtab = (char *)malloc(strsize))) 7046396Sbostic error(name); 7146396Sbostic if ((nr = read(fd, strtab, strsize)) != strsize) 7246396Sbostic badread(nr, "corrupted symbol table"); 7346396Sbostic 7446396Sbostic /* Seek to symbol table. */ 7546396Sbostic if (!(fp = fdopen(fd, "r"))) 7646396Sbostic error(name); 7746396Sbostic if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1) 7846396Sbostic error(name); 7946396Sbostic 80*46947Sbostic data.data = (u_char *)&nbuf; 81*46947Sbostic data.size = sizeof(NLIST); 8246309Sbostic 8346396Sbostic /* Read each symbol and enter it into the database. */ 8446396Sbostic nsyms = ebuf.a_syms / sizeof(struct nlist); 8546396Sbostic while (nsyms--) { 8646396Sbostic if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) { 8746396Sbostic if (feof(fp)) 8846396Sbostic badfmt("corrupted symbol table"); 8946396Sbostic error(name); 9046396Sbostic } 9146309Sbostic if (!nbuf._strx || nbuf.n_type&N_STAB) 9246309Sbostic continue; 9346309Sbostic 94*46947Sbostic key.data = (u_char *)strtab + nbuf._strx - sizeof(long); 95*46947Sbostic key.size = strlen((char *)key.data); 96*46947Sbostic if ((db->put)(db, &key, &data, 0)) 97*46947Sbostic error("put"); 9846309Sbostic 99*46947Sbostic if (!strncmp((char *)key.data, VRS_SYM, sizeof(VRS_SYM) - 1)) { 10046396Sbostic off_t cur_off, rel_off, vers_off; 10146396Sbostic 10246309Sbostic /* Offset relative to start of text image in VM. */ 10346309Sbostic #ifdef hp300 10446309Sbostic rel_off = nbuf.n_value; 10546309Sbostic #endif 10646309Sbostic #ifdef tahoe 10746309Sbostic /* 10846309Sbostic * On tahoe, first 0x800 is reserved for communication 10946309Sbostic * with the console processor. 11046309Sbostic */ 11146309Sbostic rel_off = ((nbuf.n_value & ~KERNBASE) - 0x800); 11246309Sbostic #endif 11346309Sbostic #ifdef vax 11446309Sbostic rel_off = nbuf.n_value & ~KERNBASE; 11546309Sbostic #endif 11646309Sbostic /* 11746309Sbostic * When loaded, data is rounded to next page cluster 11846309Sbostic * after text, but not in file. 11946309Sbostic */ 12046309Sbostic rel_off -= CLBYTES - (ebuf.a_text % CLBYTES); 12146309Sbostic vers_off = N_TXTOFF(ebuf) + rel_off; 12246396Sbostic 12346396Sbostic cur_off = ftell(fp); 12446396Sbostic if (fseek(fp, vers_off, 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 135*46947Sbostic key.data = (u_char *)VRS_KEY; 136*46947Sbostic key.size = sizeof(VRS_KEY) - 1; 137*46947Sbostic data.data = (u_char *)buf; 138*46947Sbostic data.size = strlen(buf); 139*46947Sbostic if ((db->put)(db, &key, &data, 0)) 140*46947Sbostic error("put"); 14146309Sbostic 14246309Sbostic /* Restore to original values. */ 143*46947Sbostic data.data = (u_char *)&nbuf; 144*46947Sbostic 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 15246396Sbostic badread(nr, p) 15346396Sbostic int nr; 15446396Sbostic char *p; 15546396Sbostic { 15646396Sbostic if (nr < 0) 15746396Sbostic error(kfile); 15846396Sbostic badfmt(p); 15946396Sbostic } 16046396Sbostic 16146309Sbostic badfmt(p) 16246396Sbostic char *p; 16346309Sbostic { 16446309Sbostic (void)fprintf(stderr, 16546309Sbostic "symorder: %s: %s: %s\n", kfile, p, strerror(EFTYPE)); 16646309Sbostic exit(1); 16746309Sbostic } 168