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