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