|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)sym.c 5.2 (Berkeley) 4/9/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.