xref: /csrg-svn/sys/deprecated/kdb/kdb_sym.c (revision 41343)
130296Ssam /*
230296Ssam  * Copyright (c) 1986 Regents of the University of California.
330296Ssam  * All rights reserved.  The Berkeley software License Agreement
430296Ssam  * specifies the terms and conditions for redistribution.
530296Ssam  *
6*41343Ssklower  *	@(#)kdb_sym.c	7.3 (Berkeley) 05/03/90
730296Ssam  */
830112Ssam 
930112Ssam /*
1030112Ssam  * adb - symbol table routines
1130112Ssam  */
1230112Ssam #include "../kdb/defs.h"
1330112Ssam #include <stab.h>
1430112Ssam 
1530112Ssam /*
1630112Ssam  * Initialize the symbol table.
1730112Ssam  */
kdbsetsym(sym,esym,strtab,strsize)18*41343Ssklower kdbsetsym(sym, esym, strtab, strsize)
1930296Ssam 	char *sym, *esym, *strtab;
2030112Ssam {
2130112Ssam 	register struct nlist *sp;
2230112Ssam 
23*41343Ssklower 	kdbsymtab = (struct nlist *)sym, kdbesymtab = (struct nlist *)esym;
24*41343Ssklower 	for (sp = kdbsymtab; sp < kdbesymtab; sp++)
2530112Ssam 		if (sp->n_un.n_strx) {
2630112Ssam 			if (sp->n_un.n_strx > strsize) {
27*41343Ssklower 				kdbprintf("setsym: Bad string table index (%d)\n",
2830112Ssam 				    sp->n_un.n_strx);
2930112Ssam 				sp->n_un.n_strx = 0;	/* XXX */
3030112Ssam 				continue;
3130112Ssam 			}
3230112Ssam 			sp->n_un.n_name = strtab + sp->n_un.n_strx;
3330112Ssam 		}
3430112Ssam }
3530112Ssam 
3630112Ssam /*
3730112Ssam  * Lookup a symbol by name.
3830112Ssam  */
3930112Ssam struct nlist *
kdblookup(symstr)40*41343Ssklower kdblookup(symstr)
4130112Ssam 	char *symstr;
4230112Ssam {
4330112Ssam 	register struct nlist *sp;
4430112Ssam 
45*41343Ssklower 	kdbcursym = 0;
46*41343Ssklower 	if (kdbsymtab)
47*41343Ssklower 	for (sp = kdbsymtab; sp < kdbesymtab; sp++)
4830112Ssam 		/* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
49*41343Ssklower 		if ((sp->n_type&N_STAB)==0 && kdbeqsym(sp->n_un.n_name, symstr, '_'))
50*41343Ssklower 			return(kdbcursym = sp);
5130112Ssam 	return (0);
5230112Ssam }
5330112Ssam 
5430112Ssam /*
5530112Ssam  * Find the closest symbol to val, and return
5630112Ssam  * the difference between val and the symbol found.
5730112Ssam  * Leave a pointer to the symbol found as cursym.
5830112Ssam  */
kdbfindsym(val,type)59*41343Ssklower kdbfindsym(val, type)
6030296Ssam 	register long val;
6130112Ssam 	int type;
6230112Ssam {
6330112Ssam 	register diff;
6430112Ssam 	register struct nlist *sp;
6530112Ssam 
66*41343Ssklower 	kdbcursym = 0;
6730112Ssam 	diff = MAXINT;
68*41343Ssklower 	if (type == NSYM || kdbsymtab == 0)
6930112Ssam 		return (diff);
70*41343Ssklower 	for (sp = kdbsymtab; sp < kdbesymtab; sp++) {
7130112Ssam 		if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0)
7230112Ssam 			continue;
7330112Ssam 		if (val - sp->n_value < diff && val >= sp->n_value) {
7430112Ssam 			diff = val - sp->n_value;
75*41343Ssklower 			kdbcursym = sp;
7630112Ssam 			if (diff == 0)
7730112Ssam 				break;
7830112Ssam 		}
7930112Ssam 	}
8030112Ssam 	return (diff);
8130112Ssam }
8230112Ssam 
8330112Ssam /*
8430112Ssam  * Advance cursym to the next local variable.
8530112Ssam  * Leave its value in localval as a side effect.
8630112Ssam  * Return 0 at end of file.
8730112Ssam  */
kdblocalsym(cframe)88*41343Ssklower kdblocalsym(cframe)
8930296Ssam 	long cframe;
9030112Ssam {
9130112Ssam 	register int type;
9230112Ssam 	register struct nlist *sp;
9330112Ssam 
94*41343Ssklower 	if (kdbcursym)
95*41343Ssklower 	for (sp = kdbcursym; ++sp < kdbesymtab; ) {
9630112Ssam 		type = sp->n_type;
9730112Ssam 		if (sp->n_un.n_name[0] =='_' || type == N_FN)
9830112Ssam 			return (0);
9930112Ssam 		switch (type) {
10030112Ssam 
10130112Ssam 		case N_TEXT:
10230112Ssam 		case N_TEXT|N_EXT:
10330112Ssam 		case N_DATA:
10430112Ssam 		case N_DATA|N_EXT:
10530112Ssam 		case N_BSS:
10630112Ssam 		case N_BSS|N_EXT:
107*41343Ssklower 			kdblocalval = sp->n_value;
108*41343Ssklower 			kdbcursym = sp;
10930112Ssam 			return (1);
11030112Ssam 
11130112Ssam 		case N_LSYM:
112*41343Ssklower 			kdblocalval = cframe - sp->n_value;
113*41343Ssklower 			kdbcursym = sp;
11430112Ssam 			return (1);
11530112Ssam 
11630112Ssam 		case N_PSYM:
11730112Ssam 		case N_ABS:
118*41343Ssklower 			kdblocalval = cframe + sp->n_value;
119*41343Ssklower 			kdbcursym = sp;
12030112Ssam 			return (1);
12130112Ssam 		}
12230112Ssam 	}
123*41343Ssklower 	kdbcursym = 0;
12430112Ssam 	return (0);
12530112Ssam }
12630112Ssam 
12730112Ssam /*
12830112Ssam  * Print value v and then the string s.
12930112Ssam  * If v is not zero, then we look for a nearby symbol
13030112Ssam  * and print name+offset if we find a symbol for which
13130112Ssam  * offset is small enough.
13230112Ssam  *
13330112Ssam  * For values which are just into kernel address space
13430112Ssam  * that they match exactly or that they be more than maxoff
13530112Ssam  * bytes into kernel space.
13630112Ssam  */
kdbpsymoff(v,type,s)137*41343Ssklower kdbpsymoff(v, type, s)
13830296Ssam 	register long v;
13930112Ssam 	int type;
14030112Ssam 	char *s;
14130112Ssam {
14230112Ssam 	register w;
14330112Ssam 
14430112Ssam 	if (v)
145*41343Ssklower 		w = kdbfindsym(v, type);
146*41343Ssklower 	if (v==0 || w >= kdbmaxoff)
147*41343Ssklower 		kdbprintf(LPRMODE, v);
14830112Ssam 	else {
149*41343Ssklower 		kdbprintf("%s", kdbcursym->n_un.n_name);
15030112Ssam 		if (w)
151*41343Ssklower 			kdbprintf(OFFMODE, w);
15230112Ssam 	}
153*41343Ssklower 	kdbprintf(s);
15430112Ssam }
15530112Ssam 
15630112Ssam /*
15730112Ssam  * Print value v symbolically if it has a reasonable
15830112Ssam  * interpretation as name+offset.  If not, print nothing.
15930112Ssam  * Used in printing out registers $r.
16030112Ssam  */
kdbvalpr(v,idsp)161*41343Ssklower kdbvalpr(v, idsp)
16230296Ssam 	long v;
16330112Ssam {
16430112Ssam 	register off_t d;
16530112Ssam 
166*41343Ssklower 	d = kdbfindsym(v, idsp);
167*41343Ssklower 	if (d >= kdbmaxoff)
16830112Ssam 		return;
169*41343Ssklower 	kdbprintf("%s", kdbcursym->n_un.n_name);
17030112Ssam 	if (d)
171*41343Ssklower 		kdbprintf(OFFMODE, d);
17230112Ssam }
173