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