1 #ifndef lint 2 static char sccsid[] = "@(#)sym.c 1.1 (Berkeley) 02/25/86"; 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)==0) 47 continue; 48 if (val - sp->n_value < diff && val >= sp->n_value) { 49 diff = val - sp->n_value; 50 cursym = sp; 51 if (diff == 0) 52 break; 53 } 54 } 55 return (diff); 56 } 57 58 /* 59 * Advance cursym to the next local variable. 60 * Leave its value in localval as a side effect. 61 * Return 0 at end of file. 62 */ 63 localsym(cframe) 64 ADDR cframe; 65 { 66 register int type; 67 register struct nlist *sp; 68 69 if (cursym) 70 for (sp = cursym; ++sp < esymtab; ) { 71 type = sp->n_type; 72 if (sp->n_un.n_name[0] =='_' || type == N_FN) 73 return (0); 74 switch (type) { 75 76 case N_TEXT: 77 case N_TEXT|N_EXT: 78 case N_DATA: 79 case N_DATA|N_EXT: 80 case N_BSS: 81 case N_BSS|N_EXT: 82 localval = sp->n_value; 83 cursym = sp; 84 return (1); 85 86 case N_LSYM: 87 localval = cframe - sp->n_value; 88 cursym = sp; 89 return (1); 90 91 case N_PSYM: 92 case N_ABS: 93 localval = cframe + sp->n_value; 94 cursym = sp; 95 return (1); 96 } 97 } 98 cursym = 0; 99 return (0); 100 } 101 102 /* 103 * Print value v and then the string s. 104 * If v is not zero, then we look for a nearby symbol 105 * and print name+offset if we find a symbol for which 106 * offset is small enough. 107 * 108 * For values which are just into kernel address space 109 * that they match exactly or that they be more than maxoff 110 * bytes into kernel space. 111 */ 112 psymoff(v, type, s) 113 register v; 114 int type; 115 char *s; 116 { 117 register w; 118 119 if (v) 120 w = findsym(v, type); 121 if (v==0 || w >= maxoff) 122 printf(LPRMODE, v); 123 else { 124 printf("%s", cursym->n_un.n_name); 125 if (w) 126 printf(OFFMODE, w); 127 } 128 printf(s); 129 } 130 131 /* 132 * Print value v symbolically if it has a reasonable 133 * interpretation as name+offset. If not, print nothing. 134 * Used in printing out registers $r. 135 */ 136 valpr(v, idsp) 137 { 138 register off_t d; 139 140 d = findsym(v, idsp); 141 if (d >= maxoff) 142 return; 143 printf("%s", cursym->n_un.n_name); 144 if (d) 145 printf(OFFMODE, d); 146 } 147