xref: /csrg-svn/sys/deprecated/kdb/kdb_sym.c (revision 30296)
1*30296Ssam /*
2*30296Ssam  * Copyright (c) 1986 Regents of the University of California.
3*30296Ssam  * All rights reserved.  The Berkeley software License Agreement
4*30296Ssam  * specifies the terms and conditions for redistribution.
5*30296Ssam  *
6*30296Ssam  *	@(#)kdb_sym.c	7.2 (Berkeley) 12/15/86
7*30296Ssam  */
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  */
1830112Ssam setsym(sym, esym, strtab, strsize)
19*30296Ssam 	char *sym, *esym, *strtab;
2030112Ssam {
2130112Ssam 	register struct nlist *sp;
2230112Ssam 
23*30296Ssam 	symtab = (struct nlist *)sym, esymtab = (struct nlist *)esym;
2430112Ssam 	for (sp = symtab; sp < esymtab; sp++)
2530112Ssam 		if (sp->n_un.n_strx) {
2630112Ssam 			if (sp->n_un.n_strx > strsize) {
2730112Ssam 				printf("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 *
4030112Ssam lookup(symstr)
4130112Ssam 	char *symstr;
4230112Ssam {
4330112Ssam 	register struct nlist *sp;
4430112Ssam 
4530112Ssam 	cursym = 0;
4630112Ssam 	if (symtab)
4730112Ssam 	for (sp = symtab; sp < esymtab; sp++)
4830112Ssam 		/* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
4930112Ssam 		if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
5030112Ssam 			return(cursym = 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  */
5930112Ssam findsym(val, type)
60*30296Ssam 	register long val;
6130112Ssam 	int type;
6230112Ssam {
6330112Ssam 	register diff;
6430112Ssam 	register struct nlist *sp;
6530112Ssam 
6630112Ssam 	cursym = 0;
6730112Ssam 	diff = MAXINT;
6830112Ssam 	if (type == NSYM || symtab == 0)
6930112Ssam 		return (diff);
7030112Ssam 	for (sp = symtab; sp < esymtab; 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;
7530112Ssam 			cursym = 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  */
8830112Ssam localsym(cframe)
89*30296Ssam 	long cframe;
9030112Ssam {
9130112Ssam 	register int type;
9230112Ssam 	register struct nlist *sp;
9330112Ssam 
9430112Ssam 	if (cursym)
9530112Ssam 	for (sp = cursym; ++sp < esymtab; ) {
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:
10730112Ssam 			localval = sp->n_value;
10830112Ssam 			cursym = sp;
10930112Ssam 			return (1);
11030112Ssam 
11130112Ssam 		case N_LSYM:
11230112Ssam 			localval = cframe - sp->n_value;
11330112Ssam 			cursym = sp;
11430112Ssam 			return (1);
11530112Ssam 
11630112Ssam 		case N_PSYM:
11730112Ssam 		case N_ABS:
11830112Ssam 			localval = cframe + sp->n_value;
11930112Ssam 			cursym = sp;
12030112Ssam 			return (1);
12130112Ssam 		}
12230112Ssam 	}
12330112Ssam 	cursym = 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  */
13730112Ssam psymoff(v, type, s)
138*30296Ssam 	register long v;
13930112Ssam 	int type;
14030112Ssam 	char *s;
14130112Ssam {
14230112Ssam 	register w;
14330112Ssam 
14430112Ssam 	if (v)
14530112Ssam 		w = findsym(v, type);
14630112Ssam 	if (v==0 || w >= maxoff)
14730112Ssam 		printf(LPRMODE, v);
14830112Ssam 	else {
14930112Ssam 		printf("%s", cursym->n_un.n_name);
15030112Ssam 		if (w)
15130112Ssam 			printf(OFFMODE, w);
15230112Ssam 	}
15330112Ssam 	printf(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  */
16130112Ssam valpr(v, idsp)
162*30296Ssam 	long v;
16330112Ssam {
16430112Ssam 	register off_t d;
16530112Ssam 
16630112Ssam 	d = findsym(v, idsp);
16730112Ssam 	if (d >= maxoff)
16830112Ssam 		return;
16930112Ssam 	printf("%s", cursym->n_un.n_name);
17030112Ssam 	if (d)
17130112Ssam 		printf(OFFMODE, d);
17230112Ssam }
173