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