xref: /original-bsd/old/adb/adb.vax/sym.c (revision c7de680c)
1 static	char sccsid[] = "@(#)sym.c 4.1 05/14/81";
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)==0)
44 			continue;
45 		if (val - sp->n_value < diff && val >= sp->n_value) {
46 			diff = val - sp->n_value;
47 			cursym = sp;
48 			if (diff == 0)
49 				break;
50 		}
51 	}
52 	return (diff);
53 }
54 
55 /*
56  * Advance cursym to the next local variable.
57  * Leave its value in localval as a side effect.
58  * Return 0 at end of file.
59  */
60 localsym(cframe, cargp)
61 	ADDR cframe, cargp;
62 {
63 	register int type;
64 	register struct nlist *sp;
65 
66 	if (cursym)
67 	for (sp = cursym; ++sp < esymtab; ) {
68 		if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN)
69 			return (0);
70 		type = sp->n_type;
71 		switch (sp->n_type) {
72 
73 		case N_TEXT:
74 		case N_TEXT|N_EXT:
75 		case N_DATA:
76 		case N_DATA|N_EXT:
77 		case N_BSS:
78 		case N_BSS|N_EXT:
79 			localval = sp->n_value;
80 			cursym = sp;
81 			return (1);
82 
83 		case N_LSYM:
84 			localval = cframe - sp->n_value;
85 			cursym = sp;
86 			return (1);
87 
88 		case N_PSYM:
89 			/* code below works since n_value > 0 */
90 		case N_ABS:
91 			if (sp->n_value < 0)
92 				localval = cframe + sp->n_value;
93 			else
94 				localval = cargp + sp->n_value;
95 			cursym = sp;
96 			return (1);
97 		}
98 	}
99 	cursym = 0;
100 	return (0);
101 }
102 
103 /*
104  * Print value v and then the string s.
105  * If v is not zero, then we look for a nearby symbol
106  * and print name+offset if we find a symbol for which
107  * offset is small enough.
108  *
109  * For values which are just into kernel address space
110  * that they match exactly or that they be more than maxoff
111  * bytes into kernel space.
112  */
113 psymoff(v, type, s)
114 	long v;
115 	int type;
116 	char *s;
117 {
118 	long w;
119 
120 	if (v)
121 		w = findsym(v, type);
122 	if (v==0 || w >= maxoff || (KVTOPH(v) < maxoff && w))
123 		printf(LPRMODE, v);
124 	else {
125 		printf("%s", cursym->n_un.n_name);
126 		if (w)
127 			printf(OFFMODE, w);
128 	}
129 	printf(s);
130 }
131 
132 /*
133  * Print value v symbolically if it has a reasonable
134  * interpretation as name+offset.  If not, print nothing.
135  * Used in printing out registers $r.
136  */
137 valpr(v, idsp)
138 	long v;
139 {
140 	off_t d;
141 
142 	d = findsym(v, idsp);
143 	if (d >= maxoff)
144 		return;
145 	printf("%s", cursym->n_un.n_name);
146 	if (d)
147 		printf(OFFMODE, d);
148 }
149