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