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