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*46396Sbostic static char sccsid[] = "@(#)nlist.c 5.2 (Berkeley) 02/12/91"; 1046309Sbostic #endif /* not lint */ 1146309Sbostic 1246309Sbostic #include <sys/param.h> 13*46396Sbostic #include <fcntl.h> 1446309Sbostic #include <limits.h> 1546309Sbostic #include <ndbm.h> 1646309Sbostic #include <a.out.h> 17*46396Sbostic #include <errno.h> 18*46396Sbostic #include <unistd.h> 1946309Sbostic #include <kvm.h> 2046309Sbostic #include <stdio.h> 21*46396Sbostic #include <string.h> 22*46396Sbostic #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; 3246309Sbostic DBM *db; 3346309Sbostic { 34*46396Sbostic register int nsyms; 3546309Sbostic struct exec ebuf; 36*46396Sbostic FILE *fp; 3746309Sbostic NLIST nbuf; 3846309Sbostic datum key, data; 39*46396Sbostic int fd, nr, strsize; 40*46396Sbostic char *strtab, buf[1024]; 4146309Sbostic 4246309Sbostic kfile = name; 43*46396Sbostic if ((fd = open(name, O_RDONLY, 0)) < 0) 4446309Sbostic error(name); 4546309Sbostic 46*46396Sbostic /* Read in exec structure. */ 47*46396Sbostic nr = read(fd, (char *)&ebuf, sizeof(struct exec)); 48*46396Sbostic if (nr != sizeof(struct exec)) 49*46396Sbostic badfmt(nr, "no exec header"); 50*46396Sbostic 51*46396Sbostic /* Check magic number and symbol count. */ 5246309Sbostic if (N_BADMAG(ebuf)) 5346309Sbostic badfmt("bad magic number"); 54*46396Sbostic if (!ebuf.a_syms) 5546309Sbostic badfmt("stripped"); 5646309Sbostic 57*46396Sbostic /* Seek to string table. */ 58*46396Sbostic if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1) 59*46396Sbostic badfmt("corrupted string table"); 6046309Sbostic 61*46396Sbostic /* Read in the size of the symbol table. */ 62*46396Sbostic nr = read(fd, (char *)&strsize, sizeof(strsize)); 63*46396Sbostic if (nr != sizeof(strsize)) 64*46396Sbostic badread(nr, "no symbol table"); 6546309Sbostic 66*46396Sbostic /* Read in the string table. */ 67*46396Sbostic strsize -= sizeof(strsize); 68*46396Sbostic if (!(strtab = (char *)malloc(strsize))) 69*46396Sbostic error(name); 70*46396Sbostic if ((nr = read(fd, strtab, strsize)) != strsize) 71*46396Sbostic badread(nr, "corrupted symbol table"); 72*46396Sbostic 73*46396Sbostic /* Seek to symbol table. */ 74*46396Sbostic if (!(fp = fdopen(fd, "r"))) 75*46396Sbostic error(name); 76*46396Sbostic if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1) 77*46396Sbostic error(name); 78*46396Sbostic 7946309Sbostic data.dptr = (char *)&nbuf; 8046309Sbostic data.dsize = sizeof(NLIST); 8146309Sbostic 82*46396Sbostic /* Read each symbol and enter it into the database. */ 83*46396Sbostic nsyms = ebuf.a_syms / sizeof(struct nlist); 84*46396Sbostic while (nsyms--) { 85*46396Sbostic if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) { 86*46396Sbostic if (feof(fp)) 87*46396Sbostic badfmt("corrupted symbol table"); 88*46396Sbostic error(name); 89*46396Sbostic } 9046309Sbostic if (!nbuf._strx || nbuf.n_type&N_STAB) 9146309Sbostic continue; 9246309Sbostic 93*46396Sbostic key.dptr = strtab + nbuf._strx - sizeof(long); 94*46396Sbostic key.dsize = strlen(key.dptr); 9546309Sbostic if (dbm_store(db, key, data, DBM_INSERT) < 0) 9646309Sbostic error("dbm_store"); 9746309Sbostic 98*46396Sbostic if (!strncmp(key.dptr, VRS_SYM, sizeof(VRS_SYM) - 1)) { 99*46396Sbostic off_t cur_off, rel_off, vers_off; 100*46396Sbostic 10146309Sbostic /* Offset relative to start of text image in VM. */ 10246309Sbostic #ifdef hp300 10346309Sbostic rel_off = nbuf.n_value; 10446309Sbostic #endif 10546309Sbostic #ifdef tahoe 10646309Sbostic /* 10746309Sbostic * On tahoe, first 0x800 is reserved for communication 10846309Sbostic * with the console processor. 10946309Sbostic */ 11046309Sbostic rel_off = ((nbuf.n_value & ~KERNBASE) - 0x800); 11146309Sbostic #endif 11246309Sbostic #ifdef vax 11346309Sbostic rel_off = nbuf.n_value & ~KERNBASE; 11446309Sbostic #endif 11546309Sbostic /* 11646309Sbostic * When loaded, data is rounded to next page cluster 11746309Sbostic * after text, but not in file. 11846309Sbostic */ 11946309Sbostic rel_off -= CLBYTES - (ebuf.a_text % CLBYTES); 12046309Sbostic vers_off = N_TXTOFF(ebuf) + rel_off; 121*46396Sbostic 122*46396Sbostic cur_off = ftell(fp); 123*46396Sbostic if (fseek(fp, vers_off, SEEK_SET) == -1) 12446309Sbostic badfmt("corrupted string table"); 12546309Sbostic 12646309Sbostic /* 12746309Sbostic * Read version string up to, and including newline. 12846309Sbostic * This code assumes that a newline terminates the 12946309Sbostic * version line. 13046309Sbostic */ 131*46396Sbostic if (fgets(buf, sizeof(buf), fp) == NULL) 13246309Sbostic badfmt("corrupted string table"); 13346309Sbostic 134*46396Sbostic key.dptr = VRS_KEY; 135*46396Sbostic key.dsize = sizeof(VRS_KEY) - 1; 136*46396Sbostic data.dptr = buf; 137*46396Sbostic data.dsize = strlen(buf); 13846309Sbostic if (dbm_store(db, key, data, DBM_INSERT) < 0) 13946309Sbostic error("dbm_store"); 14046309Sbostic 14146309Sbostic /* Restore to original values. */ 14246309Sbostic data.dptr = (char *)&nbuf; 14346309Sbostic data.dsize = sizeof(NLIST); 144*46396Sbostic if (fseek(fp, cur_off, SEEK_SET) == -1) 145*46396Sbostic badfmt("corrupted string table"); 14646309Sbostic } 14746309Sbostic } 148*46396Sbostic (void)fclose(fp); 14946309Sbostic } 15046309Sbostic 151*46396Sbostic badread(nr, p) 152*46396Sbostic int nr; 153*46396Sbostic char *p; 154*46396Sbostic { 155*46396Sbostic if (nr < 0) 156*46396Sbostic error(kfile); 157*46396Sbostic badfmt(p); 158*46396Sbostic } 159*46396Sbostic 16046309Sbostic badfmt(p) 161*46396Sbostic char *p; 16246309Sbostic { 16346309Sbostic (void)fprintf(stderr, 16446309Sbostic "symorder: %s: %s: %s\n", kfile, p, strerror(EFTYPE)); 16546309Sbostic exit(1); 16646309Sbostic } 167