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