1*46309Sbostic /*- 2*46309Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*46309Sbostic * All rights reserved. 4*46309Sbostic * 5*46309Sbostic * %sccs.include.redist.c% 6*46309Sbostic */ 7*46309Sbostic 8*46309Sbostic #ifndef lint 9*46309Sbostic static char sccsid[] = "@(#)nlist.c 5.1 (Berkeley) 02/06/91"; 10*46309Sbostic #endif /* not lint */ 11*46309Sbostic 12*46309Sbostic #include <sys/param.h> 13*46309Sbostic #include <errno.h> 14*46309Sbostic #include <limits.h> 15*46309Sbostic #include <ndbm.h> 16*46309Sbostic #include <a.out.h> 17*46309Sbostic #include <kvm.h> 18*46309Sbostic #include <unistd.h> 19*46309Sbostic #include <stdio.h> 20*46309Sbostic 21*46309Sbostic typedef struct nlist NLIST; 22*46309Sbostic #define _strx n_un.n_strx 23*46309Sbostic #define _name n_un.n_name 24*46309Sbostic 25*46309Sbostic #define BFLEN 1024 26*46309Sbostic #define VRS "_version" 27*46309Sbostic 28*46309Sbostic static char *kfile; 29*46309Sbostic 30*46309Sbostic create_knlist(name, db) 31*46309Sbostic char *name; 32*46309Sbostic DBM *db; 33*46309Sbostic { 34*46309Sbostic register char *bp; 35*46309Sbostic register int ch, len; 36*46309Sbostic struct exec ebuf; 37*46309Sbostic FILE *fstr, *fsym; 38*46309Sbostic NLIST nbuf; 39*46309Sbostic off_t string_off, symbol_off, symbol_size; 40*46309Sbostic off_t rel_off, vers_off; 41*46309Sbostic datum key, data; 42*46309Sbostic char sbuf[BFLEN]; 43*46309Sbostic 44*46309Sbostic /* Two pointers, one for symbol table and one for string table. */ 45*46309Sbostic kfile = name; 46*46309Sbostic if ((fsym = fopen(name, "r")) == NULL || 47*46309Sbostic (fstr = fopen(name, "r")) == NULL) 48*46309Sbostic error(name); 49*46309Sbostic 50*46309Sbostic if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1) 51*46309Sbostic badfmt("no exec header"); 52*46309Sbostic if (N_BADMAG(ebuf)) 53*46309Sbostic badfmt("bad magic number"); 54*46309Sbostic 55*46309Sbostic symbol_size = ebuf.a_syms; 56*46309Sbostic if (!symbol_size) 57*46309Sbostic badfmt("stripped"); 58*46309Sbostic 59*46309Sbostic symbol_off = N_SYMOFF(ebuf); 60*46309Sbostic string_off = symbol_off + symbol_size; 61*46309Sbostic 62*46309Sbostic if (fseek(fsym, symbol_off, SEEK_SET) == -1) 63*46309Sbostic badfmt("corrupted symbol table"); 64*46309Sbostic 65*46309Sbostic key.dptr = sbuf; 66*46309Sbostic data.dptr = (char *)&nbuf; 67*46309Sbostic data.dsize = sizeof(NLIST); 68*46309Sbostic 69*46309Sbostic for (; symbol_size; symbol_size -= sizeof(NLIST)) { 70*46309Sbostic if (fread((char *)&nbuf, sizeof (NLIST), 1, fsym) != 1) 71*46309Sbostic badfmt("corrupted symbol table"); 72*46309Sbostic if (!nbuf._strx || nbuf.n_type&N_STAB) 73*46309Sbostic continue; 74*46309Sbostic if (fseek(fstr, string_off + nbuf._strx, SEEK_SET) == -1) 75*46309Sbostic badfmt("corrupted string table"); 76*46309Sbostic 77*46309Sbostic /* Read string. */ 78*46309Sbostic bp = sbuf; 79*46309Sbostic for (len = 0; (ch = getc(fstr)) != EOF && ch != '\0';) { 80*46309Sbostic if (++len == BFLEN) { 81*46309Sbostic (void)fprintf(stderr, 82*46309Sbostic "kvm_mkdb: symbol too long."); 83*46309Sbostic break; 84*46309Sbostic } 85*46309Sbostic *bp++ = ch; 86*46309Sbostic } 87*46309Sbostic if (len == BFLEN) 88*46309Sbostic continue; 89*46309Sbostic 90*46309Sbostic /* Store string. */ 91*46309Sbostic key.dsize = len; 92*46309Sbostic if (dbm_store(db, key, data, DBM_INSERT) < 0) 93*46309Sbostic error("dbm_store"); 94*46309Sbostic 95*46309Sbostic if (!strncmp(sbuf, VRS, sizeof(VRS) - 1)) { 96*46309Sbostic /* Offset relative to start of text image in VM. */ 97*46309Sbostic #ifdef hp300 98*46309Sbostic rel_off = nbuf.n_value; 99*46309Sbostic #endif 100*46309Sbostic #ifdef tahoe 101*46309Sbostic /* 102*46309Sbostic * On tahoe, first 0x800 is reserved for communication 103*46309Sbostic * with the console processor. 104*46309Sbostic */ 105*46309Sbostic rel_off = ((nbuf.n_value & ~KERNBASE) - 0x800); 106*46309Sbostic #endif 107*46309Sbostic #ifdef vax 108*46309Sbostic rel_off = nbuf.n_value & ~KERNBASE; 109*46309Sbostic #endif 110*46309Sbostic /* 111*46309Sbostic * When loaded, data is rounded to next page cluster 112*46309Sbostic * after text, but not in file. 113*46309Sbostic */ 114*46309Sbostic rel_off -= CLBYTES - (ebuf.a_text % CLBYTES); 115*46309Sbostic vers_off = N_TXTOFF(ebuf) + rel_off; 116*46309Sbostic if (fseek(fstr, vers_off, SEEK_SET) == -1) 117*46309Sbostic badfmt("corrupted string table"); 118*46309Sbostic 119*46309Sbostic /* 120*46309Sbostic * Read version string up to, and including newline. 121*46309Sbostic * This code assumes that a newline terminates the 122*46309Sbostic * version line. 123*46309Sbostic */ 124*46309Sbostic if (fgets(sbuf, sizeof(sbuf), fstr) == NULL) 125*46309Sbostic badfmt("corrupted string table"); 126*46309Sbostic 127*46309Sbostic key.dptr = VERSION; 128*46309Sbostic key.dsize = sizeof(VERSION) - 1; 129*46309Sbostic data.dptr = sbuf; 130*46309Sbostic data.dsize = strlen(sbuf); 131*46309Sbostic if (dbm_store(db, key, data, DBM_INSERT) < 0) 132*46309Sbostic error("dbm_store"); 133*46309Sbostic 134*46309Sbostic /* Restore to original values. */ 135*46309Sbostic key.dptr = sbuf; 136*46309Sbostic data.dptr = (char *)&nbuf; 137*46309Sbostic data.dsize = sizeof(NLIST); 138*46309Sbostic } 139*46309Sbostic } 140*46309Sbostic (void)fclose(fstr); 141*46309Sbostic (void)fclose(fsym); 142*46309Sbostic } 143*46309Sbostic 144*46309Sbostic badfmt(p) 145*46309Sbostic { 146*46309Sbostic (void)fprintf(stderr, 147*46309Sbostic "symorder: %s: %s: %s\n", kfile, p, strerror(EFTYPE)); 148*46309Sbostic exit(1); 149*46309Sbostic } 150