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