xref: /original-bsd/old/adb/adb.tahoe/sym.c (revision 2301fdfb)
1 #ifndef lint
2 static	char sccsid[] = "@(#)sym.c	1.2 (Berkeley) 04/27/87";
3 #endif
4 
5 /*
6  * adb - symbol table routines
7  */
8 #include "defs.h"
9 #include <stab.h>
10 
11 /*
12  * Lookup a symbol by name.
13  */
14 struct nlist *
15 lookup(symstr)
16 	char *symstr;
17 {
18 	register struct nlist *sp;
19 
20 	cursym = 0;
21 	if (symtab)
22 	for (sp = symtab; sp < esymtab; sp++)
23 		/* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
24 		if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
25 			return(cursym = sp);
26 	return (0);
27 }
28 
29 /*
30  * Find the closest symbol to val, and return
31  * the difference between val and the symbol found.
32  * Leave a pointer to the symbol found as cursym.
33  */
34 findsym(val, type)
35 	register val;
36 	int type;
37 {
38 	register diff;
39 	register struct nlist *sp;
40 
41 	cursym = 0;
42 	diff = MAXINT;
43 	if (type == NSYM || symtab == 0)
44 		return (diff);
45 	for (sp = symtab; sp < esymtab; sp++) {
46 		if (sp->n_type & N_STAB || !(sp->n_type & N_EXT)
47 		    || sp->n_type == (N_FN|N_EXT))
48 			continue;
49 		if (val - sp->n_value < diff && val >= sp->n_value) {
50 			diff = val - sp->n_value;
51 			cursym = sp;
52 			if (diff == 0)
53 				break;
54 		}
55 	}
56 	return (diff);
57 }
58 
59 /*
60  * Advance cursym to the next local variable.
61  * Leave its value in localval as a side effect.
62  * Return 0 at end of file.
63  */
64 localsym(cframe)
65 	ADDR cframe;
66 {
67 	register int type;
68 	register struct nlist *sp;
69 
70 	if (cursym)
71 	for (sp = cursym; ++sp < esymtab; ) {
72 		type = sp->n_type;
73 		if (sp->n_un.n_name[0] =='_' || type == N_FN)
74 			return (0);
75 		switch (type) {
76 
77 		case N_TEXT:
78 		case N_TEXT|N_EXT:
79 		case N_DATA:
80 		case N_DATA|N_EXT:
81 		case N_BSS:
82 		case N_BSS|N_EXT:
83 			localval = sp->n_value;
84 			cursym = sp;
85 			return (1);
86 
87 		case N_LSYM:
88 			localval = cframe - sp->n_value;
89 			cursym = sp;
90 			return (1);
91 
92 		case N_PSYM:
93 		case N_ABS:
94 			localval = cframe + 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 	register v;
115 	int type;
116 	char *s;
117 {
118 	register w;
119 
120 	if (v)
121 		w = findsym(v, type);
122 	if (v==0 || w >= maxoff)
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 {
139 	register off_t d;
140 
141 	d = findsym(v, idsp);
142 	if (d >= maxoff)
143 		return;
144 	printf("%s", cursym->n_un.n_name);
145 	if (d)
146 		printf(OFFMODE, d);
147 }
148