1 static char sccsid[] = "@(#)sym.c 4.1 05/14/81"; 2 /* 3 * adb - symbol table routines 4 */ 5 #include "defs.h" 6 #include <stab.h> 7 8 /* 9 * Lookup a symbol by name. 10 */ 11 struct nlist * 12 lookup(symstr) 13 char *symstr; 14 { 15 register struct nlist *sp; 16 17 cursym = 0; 18 if (symtab) 19 for (sp = symtab; sp < esymtab; sp++) 20 /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */ 21 if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_')) 22 return(cursym = sp); 23 return (0); 24 } 25 26 /* 27 * Find the closest symbol to val, and return 28 * the difference between val and the symbol found. 29 * Leave a pointer to the symbol found as cursym. 30 */ 31 findsym(val, type) 32 long val; 33 int type; 34 { 35 long diff; 36 register struct nlist *sp; 37 38 cursym = 0; 39 diff = MAXINT; 40 if (type == NSYM || symtab == 0) 41 return (diff); 42 for (sp = symtab; sp < esymtab; sp++) { 43 if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0) 44 continue; 45 if (val - sp->n_value < diff && val >= sp->n_value) { 46 diff = val - sp->n_value; 47 cursym = sp; 48 if (diff == 0) 49 break; 50 } 51 } 52 return (diff); 53 } 54 55 /* 56 * Advance cursym to the next local variable. 57 * Leave its value in localval as a side effect. 58 * Return 0 at end of file. 59 */ 60 localsym(cframe, cargp) 61 ADDR cframe, cargp; 62 { 63 register int type; 64 register struct nlist *sp; 65 66 if (cursym) 67 for (sp = cursym; ++sp < esymtab; ) { 68 if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN) 69 return (0); 70 type = sp->n_type; 71 switch (sp->n_type) { 72 73 case N_TEXT: 74 case N_TEXT|N_EXT: 75 case N_DATA: 76 case N_DATA|N_EXT: 77 case N_BSS: 78 case N_BSS|N_EXT: 79 localval = sp->n_value; 80 cursym = sp; 81 return (1); 82 83 case N_LSYM: 84 localval = cframe - sp->n_value; 85 cursym = sp; 86 return (1); 87 88 case N_PSYM: 89 /* code below works since n_value > 0 */ 90 case N_ABS: 91 if (sp->n_value < 0) 92 localval = cframe + sp->n_value; 93 else 94 localval = cargp + 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 long v; 115 int type; 116 char *s; 117 { 118 long w; 119 120 if (v) 121 w = findsym(v, type); 122 if (v==0 || w >= maxoff || (KVTOPH(v) < maxoff && w)) 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 long v; 139 { 140 off_t d; 141 142 d = findsym(v, idsp); 143 if (d >= maxoff) 144 return; 145 printf("%s", cursym->n_un.n_name); 146 if (d) 147 printf(OFFMODE, d); 148 } 149