1 /*
2 * Copyright (c) 1986 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * @(#)kdb_sym.c 7.3 (Berkeley) 05/03/90
7 */
8
9 /*
10 * adb - symbol table routines
11 */
12 #include "../kdb/defs.h"
13 #include <stab.h>
14
15 /*
16 * Initialize the symbol table.
17 */
kdbsetsym(sym,esym,strtab,strsize)18 kdbsetsym(sym, esym, strtab, strsize)
19 char *sym, *esym, *strtab;
20 {
21 register struct nlist *sp;
22
23 kdbsymtab = (struct nlist *)sym, kdbesymtab = (struct nlist *)esym;
24 for (sp = kdbsymtab; sp < kdbesymtab; sp++)
25 if (sp->n_un.n_strx) {
26 if (sp->n_un.n_strx > strsize) {
27 kdbprintf("setsym: Bad string table index (%d)\n",
28 sp->n_un.n_strx);
29 sp->n_un.n_strx = 0; /* XXX */
30 continue;
31 }
32 sp->n_un.n_name = strtab + sp->n_un.n_strx;
33 }
34 }
35
36 /*
37 * Lookup a symbol by name.
38 */
39 struct nlist *
kdblookup(symstr)40 kdblookup(symstr)
41 char *symstr;
42 {
43 register struct nlist *sp;
44
45 kdbcursym = 0;
46 if (kdbsymtab)
47 for (sp = kdbsymtab; sp < kdbesymtab; sp++)
48 /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
49 if ((sp->n_type&N_STAB)==0 && kdbeqsym(sp->n_un.n_name, symstr, '_'))
50 return(kdbcursym = sp);
51 return (0);
52 }
53
54 /*
55 * Find the closest symbol to val, and return
56 * the difference between val and the symbol found.
57 * Leave a pointer to the symbol found as cursym.
58 */
kdbfindsym(val,type)59 kdbfindsym(val, type)
60 register long val;
61 int type;
62 {
63 register diff;
64 register struct nlist *sp;
65
66 kdbcursym = 0;
67 diff = MAXINT;
68 if (type == NSYM || kdbsymtab == 0)
69 return (diff);
70 for (sp = kdbsymtab; sp < kdbesymtab; sp++) {
71 if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0)
72 continue;
73 if (val - sp->n_value < diff && val >= sp->n_value) {
74 diff = val - sp->n_value;
75 kdbcursym = sp;
76 if (diff == 0)
77 break;
78 }
79 }
80 return (diff);
81 }
82
83 /*
84 * Advance cursym to the next local variable.
85 * Leave its value in localval as a side effect.
86 * Return 0 at end of file.
87 */
kdblocalsym(cframe)88 kdblocalsym(cframe)
89 long cframe;
90 {
91 register int type;
92 register struct nlist *sp;
93
94 if (kdbcursym)
95 for (sp = kdbcursym; ++sp < kdbesymtab; ) {
96 type = sp->n_type;
97 if (sp->n_un.n_name[0] =='_' || type == N_FN)
98 return (0);
99 switch (type) {
100
101 case N_TEXT:
102 case N_TEXT|N_EXT:
103 case N_DATA:
104 case N_DATA|N_EXT:
105 case N_BSS:
106 case N_BSS|N_EXT:
107 kdblocalval = sp->n_value;
108 kdbcursym = sp;
109 return (1);
110
111 case N_LSYM:
112 kdblocalval = cframe - sp->n_value;
113 kdbcursym = sp;
114 return (1);
115
116 case N_PSYM:
117 case N_ABS:
118 kdblocalval = cframe + sp->n_value;
119 kdbcursym = sp;
120 return (1);
121 }
122 }
123 kdbcursym = 0;
124 return (0);
125 }
126
127 /*
128 * Print value v and then the string s.
129 * If v is not zero, then we look for a nearby symbol
130 * and print name+offset if we find a symbol for which
131 * offset is small enough.
132 *
133 * For values which are just into kernel address space
134 * that they match exactly or that they be more than maxoff
135 * bytes into kernel space.
136 */
kdbpsymoff(v,type,s)137 kdbpsymoff(v, type, s)
138 register long v;
139 int type;
140 char *s;
141 {
142 register w;
143
144 if (v)
145 w = kdbfindsym(v, type);
146 if (v==0 || w >= kdbmaxoff)
147 kdbprintf(LPRMODE, v);
148 else {
149 kdbprintf("%s", kdbcursym->n_un.n_name);
150 if (w)
151 kdbprintf(OFFMODE, w);
152 }
153 kdbprintf(s);
154 }
155
156 /*
157 * Print value v symbolically if it has a reasonable
158 * interpretation as name+offset. If not, print nothing.
159 * Used in printing out registers $r.
160 */
kdbvalpr(v,idsp)161 kdbvalpr(v, idsp)
162 long v;
163 {
164 register off_t d;
165
166 d = kdbfindsym(v, idsp);
167 if (d >= kdbmaxoff)
168 return;
169 kdbprintf("%s", kdbcursym->n_un.n_name);
170 if (d)
171 kdbprintf(OFFMODE, d);
172 }
173