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