1 #ifndef lint
2 static char sccsid[] = "@(#)sym.c 1.2 (Berkeley) 04/27/87";
3 #endif
4
5 /*
6 * adb - symbol table routines
7 */
8 #include "defs.h"
9 #include <stab.h>
10
11 /*
12 * Lookup a symbol by name.
13 */
14 struct nlist *
lookup(symstr)15 lookup(symstr)
16 char *symstr;
17 {
18 register struct nlist *sp;
19
20 cursym = 0;
21 if (symtab)
22 for (sp = symtab; sp < esymtab; sp++)
23 /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
24 if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
25 return(cursym = sp);
26 return (0);
27 }
28
29 /*
30 * Find the closest symbol to val, and return
31 * the difference between val and the symbol found.
32 * Leave a pointer to the symbol found as cursym.
33 */
findsym(val,type)34 findsym(val, type)
35 register val;
36 int type;
37 {
38 register diff;
39 register struct nlist *sp;
40
41 cursym = 0;
42 diff = MAXINT;
43 if (type == NSYM || symtab == 0)
44 return (diff);
45 for (sp = symtab; sp < esymtab; sp++) {
46 if (sp->n_type & N_STAB || !(sp->n_type & N_EXT)
47 || sp->n_type == (N_FN|N_EXT))
48 continue;
49 if (val - sp->n_value < diff && val >= sp->n_value) {
50 diff = val - sp->n_value;
51 cursym = sp;
52 if (diff == 0)
53 break;
54 }
55 }
56 return (diff);
57 }
58
59 /*
60 * Advance cursym to the next local variable.
61 * Leave its value in localval as a side effect.
62 * Return 0 at end of file.
63 */
localsym(cframe)64 localsym(cframe)
65 ADDR cframe;
66 {
67 register int type;
68 register struct nlist *sp;
69
70 if (cursym)
71 for (sp = cursym; ++sp < esymtab; ) {
72 type = sp->n_type;
73 if (sp->n_un.n_name[0] =='_' || type == N_FN)
74 return (0);
75 switch (type) {
76
77 case N_TEXT:
78 case N_TEXT|N_EXT:
79 case N_DATA:
80 case N_DATA|N_EXT:
81 case N_BSS:
82 case N_BSS|N_EXT:
83 localval = sp->n_value;
84 cursym = sp;
85 return (1);
86
87 case N_LSYM:
88 localval = cframe - sp->n_value;
89 cursym = sp;
90 return (1);
91
92 case N_PSYM:
93 case N_ABS:
94 localval = cframe + sp->n_value;
95 cursym = sp;
96 return (1);
97 }
98 }
99 cursym = 0;
100 return (0);
101 }
102
103 /*
104 * Print value v and then the string s.
105 * If v is not zero, then we look for a nearby symbol
106 * and print name+offset if we find a symbol for which
107 * offset is small enough.
108 *
109 * For values which are just into kernel address space
110 * that they match exactly or that they be more than maxoff
111 * bytes into kernel space.
112 */
psymoff(v,type,s)113 psymoff(v, type, s)
114 register v;
115 int type;
116 char *s;
117 {
118 register w;
119
120 if (v)
121 w = findsym(v, type);
122 if (v==0 || w >= maxoff)
123 printf(LPRMODE, v);
124 else {
125 printf("%s", cursym->n_un.n_name);
126 if (w)
127 printf(OFFMODE, w);
128 }
129 printf(s);
130 }
131
132 /*
133 * Print value v symbolically if it has a reasonable
134 * interpretation as name+offset. If not, print nothing.
135 * Used in printing out registers $r.
136 */
valpr(v,idsp)137 valpr(v, idsp)
138 {
139 register off_t d;
140
141 d = findsym(v, idsp);
142 if (d >= maxoff)
143 return;
144 printf("%s", cursym->n_un.n_name);
145 if (d)
146 printf(OFFMODE, d);
147 }
148