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