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