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 *
lookup(symstr)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 *
findsym(val,space,diffp)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 *
nextlocal(sym)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 */
psymoff(f,v,space,o,s)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 */
valpr(v,space)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