xref: /csrg-svn/old/adb/adb.tahoe/sym.c (revision 30965)
126424Ssam #ifndef lint
2*30965Sbostic static	char sccsid[] = "@(#)sym.c	1.2 (Berkeley) 04/27/87";
326424Ssam #endif
426424Ssam 
526424Ssam /*
626424Ssam  * adb - symbol table routines
726424Ssam  */
826424Ssam #include "defs.h"
926424Ssam #include <stab.h>
1026424Ssam 
1126424Ssam /*
1226424Ssam  * Lookup a symbol by name.
1326424Ssam  */
1426424Ssam struct nlist *
lookup(symstr)1526424Ssam lookup(symstr)
1626424Ssam 	char *symstr;
1726424Ssam {
1826424Ssam 	register struct nlist *sp;
1926424Ssam 
2026424Ssam 	cursym = 0;
2126424Ssam 	if (symtab)
2226424Ssam 	for (sp = symtab; sp < esymtab; sp++)
2326424Ssam 		/* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
2426424Ssam 		if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
2526424Ssam 			return(cursym = sp);
2626424Ssam 	return (0);
2726424Ssam }
2826424Ssam 
2926424Ssam /*
3026424Ssam  * Find the closest symbol to val, and return
3126424Ssam  * the difference between val and the symbol found.
3226424Ssam  * Leave a pointer to the symbol found as cursym.
3326424Ssam  */
findsym(val,type)3426424Ssam findsym(val, type)
3526424Ssam 	register val;
3626424Ssam 	int type;
3726424Ssam {
3826424Ssam 	register diff;
3926424Ssam 	register struct nlist *sp;
4026424Ssam 
4126424Ssam 	cursym = 0;
4226424Ssam 	diff = MAXINT;
4326424Ssam 	if (type == NSYM || symtab == 0)
4426424Ssam 		return (diff);
4526424Ssam 	for (sp = symtab; sp < esymtab; sp++) {
46*30965Sbostic 		if (sp->n_type & N_STAB || !(sp->n_type & N_EXT)
47*30965Sbostic 		    || sp->n_type == (N_FN|N_EXT))
4826424Ssam 			continue;
4926424Ssam 		if (val - sp->n_value < diff && val >= sp->n_value) {
5026424Ssam 			diff = val - sp->n_value;
5126424Ssam 			cursym = sp;
5226424Ssam 			if (diff == 0)
5326424Ssam 				break;
5426424Ssam 		}
5526424Ssam 	}
5626424Ssam 	return (diff);
5726424Ssam }
5826424Ssam 
5926424Ssam /*
6026424Ssam  * Advance cursym to the next local variable.
6126424Ssam  * Leave its value in localval as a side effect.
6226424Ssam  * Return 0 at end of file.
6326424Ssam  */
localsym(cframe)6426424Ssam localsym(cframe)
6526424Ssam 	ADDR cframe;
6626424Ssam {
6726424Ssam 	register int type;
6826424Ssam 	register struct nlist *sp;
6926424Ssam 
7026424Ssam 	if (cursym)
7126424Ssam 	for (sp = cursym; ++sp < esymtab; ) {
7226424Ssam 		type = sp->n_type;
7326424Ssam 		if (sp->n_un.n_name[0] =='_' || type == N_FN)
7426424Ssam 			return (0);
7526424Ssam 		switch (type) {
7626424Ssam 
7726424Ssam 		case N_TEXT:
7826424Ssam 		case N_TEXT|N_EXT:
7926424Ssam 		case N_DATA:
8026424Ssam 		case N_DATA|N_EXT:
8126424Ssam 		case N_BSS:
8226424Ssam 		case N_BSS|N_EXT:
8326424Ssam 			localval = sp->n_value;
8426424Ssam 			cursym = sp;
8526424Ssam 			return (1);
8626424Ssam 
8726424Ssam 		case N_LSYM:
8826424Ssam 			localval = cframe - sp->n_value;
8926424Ssam 			cursym = sp;
9026424Ssam 			return (1);
9126424Ssam 
9226424Ssam 		case N_PSYM:
9326424Ssam 		case N_ABS:
9426424Ssam 			localval = cframe + sp->n_value;
9526424Ssam 			cursym = sp;
9626424Ssam 			return (1);
9726424Ssam 		}
9826424Ssam 	}
9926424Ssam 	cursym = 0;
10026424Ssam 	return (0);
10126424Ssam }
10226424Ssam 
10326424Ssam /*
10426424Ssam  * Print value v and then the string s.
10526424Ssam  * If v is not zero, then we look for a nearby symbol
10626424Ssam  * and print name+offset if we find a symbol for which
10726424Ssam  * offset is small enough.
10826424Ssam  *
10926424Ssam  * For values which are just into kernel address space
11026424Ssam  * that they match exactly or that they be more than maxoff
11126424Ssam  * bytes into kernel space.
11226424Ssam  */
psymoff(v,type,s)11326424Ssam psymoff(v, type, s)
11426424Ssam 	register v;
11526424Ssam 	int type;
11626424Ssam 	char *s;
11726424Ssam {
11826424Ssam 	register w;
11926424Ssam 
12026424Ssam 	if (v)
12126424Ssam 		w = findsym(v, type);
12226424Ssam 	if (v==0 || w >= maxoff)
12326424Ssam 		printf(LPRMODE, v);
12426424Ssam 	else {
12526424Ssam 		printf("%s", cursym->n_un.n_name);
12626424Ssam 		if (w)
12726424Ssam 			printf(OFFMODE, w);
12826424Ssam 	}
12926424Ssam 	printf(s);
13026424Ssam }
13126424Ssam 
13226424Ssam /*
13326424Ssam  * Print value v symbolically if it has a reasonable
13426424Ssam  * interpretation as name+offset.  If not, print nothing.
13526424Ssam  * Used in printing out registers $r.
13626424Ssam  */
valpr(v,idsp)13726424Ssam valpr(v, idsp)
13826424Ssam {
13926424Ssam 	register off_t d;
14026424Ssam 
14126424Ssam 	d = findsym(v, idsp);
14226424Ssam 	if (d >= maxoff)
14326424Ssam 		return;
14426424Ssam 	printf("%s", cursym->n_un.n_name);
14526424Ssam 	if (d)
14626424Ssam 		printf(OFFMODE, d);
14726424Ssam }
148