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