1*30112Ssam /* kdb_sym.c 7.1 86/11/20 */ 2*30112Ssam 3*30112Ssam /* 4*30112Ssam * adb - symbol table routines 5*30112Ssam */ 6*30112Ssam #include "../kdb/defs.h" 7*30112Ssam #include <stab.h> 8*30112Ssam 9*30112Ssam /* 10*30112Ssam * Initialize the symbol table. 11*30112Ssam */ 12*30112Ssam setsym(sym, esym, strtab, strsize) 13*30112Ssam struct nlist *sym, *esym; 14*30112Ssam char *strtab; 15*30112Ssam { 16*30112Ssam register struct nlist *sp; 17*30112Ssam 18*30112Ssam symtab = sym, esymtab = esym; 19*30112Ssam for (sp = symtab; sp < esymtab; sp++) 20*30112Ssam if (sp->n_un.n_strx) { 21*30112Ssam if (sp->n_un.n_strx > strsize) { 22*30112Ssam printf("setsym: Bad string table index (%d)\n", 23*30112Ssam sp->n_un.n_strx); 24*30112Ssam sp->n_un.n_strx = 0; /* XXX */ 25*30112Ssam continue; 26*30112Ssam } 27*30112Ssam sp->n_un.n_name = strtab + sp->n_un.n_strx; 28*30112Ssam } 29*30112Ssam } 30*30112Ssam 31*30112Ssam /* 32*30112Ssam * Lookup a symbol by name. 33*30112Ssam */ 34*30112Ssam struct nlist * 35*30112Ssam lookup(symstr) 36*30112Ssam char *symstr; 37*30112Ssam { 38*30112Ssam register struct nlist *sp; 39*30112Ssam 40*30112Ssam cursym = 0; 41*30112Ssam if (symtab) 42*30112Ssam for (sp = symtab; sp < esymtab; sp++) 43*30112Ssam /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */ 44*30112Ssam if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_')) 45*30112Ssam return(cursym = sp); 46*30112Ssam return (0); 47*30112Ssam } 48*30112Ssam 49*30112Ssam /* 50*30112Ssam * Find the closest symbol to val, and return 51*30112Ssam * the difference between val and the symbol found. 52*30112Ssam * Leave a pointer to the symbol found as cursym. 53*30112Ssam */ 54*30112Ssam findsym(val, type) 55*30112Ssam register val; 56*30112Ssam int type; 57*30112Ssam { 58*30112Ssam register diff; 59*30112Ssam register struct nlist *sp; 60*30112Ssam 61*30112Ssam cursym = 0; 62*30112Ssam diff = MAXINT; 63*30112Ssam if (type == NSYM || symtab == 0) 64*30112Ssam return (diff); 65*30112Ssam for (sp = symtab; sp < esymtab; sp++) { 66*30112Ssam if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0) 67*30112Ssam continue; 68*30112Ssam if (val - sp->n_value < diff && val >= sp->n_value) { 69*30112Ssam diff = val - sp->n_value; 70*30112Ssam cursym = sp; 71*30112Ssam if (diff == 0) 72*30112Ssam break; 73*30112Ssam } 74*30112Ssam } 75*30112Ssam return (diff); 76*30112Ssam } 77*30112Ssam 78*30112Ssam /* 79*30112Ssam * Advance cursym to the next local variable. 80*30112Ssam * Leave its value in localval as a side effect. 81*30112Ssam * Return 0 at end of file. 82*30112Ssam */ 83*30112Ssam localsym(cframe) 84*30112Ssam ADDR cframe; 85*30112Ssam { 86*30112Ssam register int type; 87*30112Ssam register struct nlist *sp; 88*30112Ssam 89*30112Ssam if (cursym) 90*30112Ssam for (sp = cursym; ++sp < esymtab; ) { 91*30112Ssam type = sp->n_type; 92*30112Ssam if (sp->n_un.n_name[0] =='_' || type == N_FN) 93*30112Ssam return (0); 94*30112Ssam switch (type) { 95*30112Ssam 96*30112Ssam case N_TEXT: 97*30112Ssam case N_TEXT|N_EXT: 98*30112Ssam case N_DATA: 99*30112Ssam case N_DATA|N_EXT: 100*30112Ssam case N_BSS: 101*30112Ssam case N_BSS|N_EXT: 102*30112Ssam localval = sp->n_value; 103*30112Ssam cursym = sp; 104*30112Ssam return (1); 105*30112Ssam 106*30112Ssam case N_LSYM: 107*30112Ssam localval = cframe - sp->n_value; 108*30112Ssam cursym = sp; 109*30112Ssam return (1); 110*30112Ssam 111*30112Ssam case N_PSYM: 112*30112Ssam case N_ABS: 113*30112Ssam localval = cframe + sp->n_value; 114*30112Ssam cursym = sp; 115*30112Ssam return (1); 116*30112Ssam } 117*30112Ssam } 118*30112Ssam cursym = 0; 119*30112Ssam return (0); 120*30112Ssam } 121*30112Ssam 122*30112Ssam /* 123*30112Ssam * Print value v and then the string s. 124*30112Ssam * If v is not zero, then we look for a nearby symbol 125*30112Ssam * and print name+offset if we find a symbol for which 126*30112Ssam * offset is small enough. 127*30112Ssam * 128*30112Ssam * For values which are just into kernel address space 129*30112Ssam * that they match exactly or that they be more than maxoff 130*30112Ssam * bytes into kernel space. 131*30112Ssam */ 132*30112Ssam psymoff(v, type, s) 133*30112Ssam register v; 134*30112Ssam int type; 135*30112Ssam char *s; 136*30112Ssam { 137*30112Ssam register w; 138*30112Ssam 139*30112Ssam if (v) 140*30112Ssam w = findsym(v, type); 141*30112Ssam if (v==0 || w >= maxoff) 142*30112Ssam printf(LPRMODE, v); 143*30112Ssam else { 144*30112Ssam printf("%s", cursym->n_un.n_name); 145*30112Ssam if (w) 146*30112Ssam printf(OFFMODE, w); 147*30112Ssam } 148*30112Ssam printf(s); 149*30112Ssam } 150*30112Ssam 151*30112Ssam /* 152*30112Ssam * Print value v symbolically if it has a reasonable 153*30112Ssam * interpretation as name+offset. If not, print nothing. 154*30112Ssam * Used in printing out registers $r. 155*30112Ssam */ 156*30112Ssam valpr(v, idsp) 157*30112Ssam { 158*30112Ssam register off_t d; 159*30112Ssam 160*30112Ssam d = findsym(v, idsp); 161*30112Ssam if (d >= maxoff) 162*30112Ssam return; 163*30112Ssam printf("%s", cursym->n_un.n_name); 164*30112Ssam if (d) 165*30112Ssam printf(OFFMODE, d); 166*30112Ssam } 167