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