1 #ifndef lint 2 static char sccsid[] = "@(#)sym.c 5.2 (Berkeley) 04/09/89"; 3 #endif 4 5 /* 6 * adb - symbol table routines 7 */ 8 #include "defs.h" 9 #include <stab.h> 10 11 #define isstab(sp) ((sp)->n_type & N_STAB) 12 13 /* 14 * Lookup a symbol by name. 15 */ 16 struct nlist * 17 lookup(symstr) 18 register char *symstr; 19 { 20 register struct nlist *sp; 21 22 if (symtab) 23 for (sp = symtab; sp < esymtab; sp++) 24 if (!isstab(sp) && eqsym(sp->n_un.n_name, symstr, '_')) 25 return (sp); 26 return (0); 27 } 28 29 /* 30 * Find the closest symbol to val, and return it and (through 31 * diffp) the difference between val and the symbol found. 32 */ 33 struct nlist * 34 findsym(val, space, diffp) 35 register addr_t val; 36 int space; 37 addr_t *diffp; 38 { 39 register struct nlist *sp; 40 register addr_t diff; 41 struct nlist *sym; 42 43 diff = ~(addr_t)0; 44 sym = NULL; 45 if (space != SP_NONE && symtab != NULL) { 46 for (sp = symtab; sp < esymtab; sp++) { 47 /* must be global */ 48 if (isstab(sp) || (sp->n_type & N_EXT) == 0) 49 continue; 50 /* and not a function */ 51 if (sp->n_type == (N_FN|N_EXT)) 52 continue; 53 /* and have a greater address */ 54 if (val < sp->n_value) 55 continue; 56 /* and be closer than the last one */ 57 if (val - sp->n_value >= diff) 58 continue; 59 sym = sp; 60 diff = val - sp->n_value; 61 if (diff == 0) 62 break; 63 } 64 } 65 *diffp = diff; 66 return (sym); 67 } 68 69 /* 70 * Return the next local symbol after sym, or NULL at end of such locals. 71 */ 72 /* ARGSUSED */ 73 struct nlist * 74 nextlocal(sym) 75 struct nlist *sym; 76 { 77 78 #ifdef busted 79 /* 80 * none of this works at the moment, because the symbols are not in 81 * the desired order. 82 */ 83 if (sym == NULL) 84 return (NULL); 85 while (++sym < esymtab) { 86 /* 87 * External and file name symbols terminate the 88 * list of local symbols. Otherwise, if it is 89 * a .stabs parameter or local symbol, take it. 90 */ 91 if ((sym->n_type & N_EXT) || sym->n_type == N_FN) 92 break; 93 if (sym->n_type == N_LSYM || sym->n_type == N_PSYM) 94 return (sym); 95 } 96 #endif 97 return (NULL); 98 } 99 100 /* 101 * Print value v (in format f) and then (as another format) s. 102 * If v is not zero, we look for a nearby symbol and print name+offset 103 * if we find a symbol whose offset is small enough (less than o). 104 */ 105 psymoff(f, v, space, o, s) 106 char *f; 107 addr_t v; 108 int space; 109 addr_t o; 110 char *s; 111 { 112 struct nlist *sp; 113 addr_t offset; 114 115 if (v && (sp = findsym(v, space, &offset)) != NULL && offset < o) 116 adbprintf("%s%?+R", sp->n_un.n_name, 117 offset != 0, (expr_t)offset); 118 else 119 adbprintf(f, (expr_t)v); 120 adbprintf(s); 121 } 122 123 /* 124 * Print value v symbolically if it has a reasonable 125 * interpretation as name+offset. If not, print nothing. 126 * Used in printing out registers $r. 127 */ 128 valpr(v, space) 129 addr_t v; 130 int space; 131 { 132 struct nlist *sp; 133 addr_t offset; 134 135 if (v && (sp = findsym(v, space, &offset)) != NULL && offset < maxoff) 136 adbprintf("%s%?+R", sp->n_un.n_name, 137 offset != 0, (expr_t)offset); 138 } 139