xref: /csrg-svn/old/adb/adb.vax/sym.c (revision 30968)
1*30968Sbostic static	char sccsid[] = "@(#)sym.c 4.3 04/27/87";
23767Sroot /*
33767Sroot  * adb - symbol table routines
43767Sroot  */
53767Sroot #include "defs.h"
63767Sroot #include <stab.h>
73767Sroot 
83767Sroot /*
93767Sroot  * Lookup a symbol by name.
103767Sroot  */
113767Sroot struct nlist *
lookup(symstr)123767Sroot lookup(symstr)
133767Sroot 	char *symstr;
143767Sroot {
153767Sroot 	register struct nlist *sp;
163767Sroot 
173767Sroot 	cursym = 0;
183767Sroot 	if (symtab)
193767Sroot 	for (sp = symtab; sp < esymtab; sp++)
203767Sroot 		/* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
213767Sroot 		if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
223767Sroot 			return(cursym = sp);
233767Sroot 	return (0);
243767Sroot }
253767Sroot 
263767Sroot /*
273767Sroot  * Find the closest symbol to val, and return
283767Sroot  * the difference between val and the symbol found.
293767Sroot  * Leave a pointer to the symbol found as cursym.
303767Sroot  */
findsym(val,type)313767Sroot findsym(val, type)
323767Sroot 	long val;
333767Sroot 	int type;
343767Sroot {
353767Sroot 	long diff;
363767Sroot 	register struct nlist *sp;
373767Sroot 
383767Sroot 	cursym = 0;
393767Sroot 	diff = MAXINT;
403767Sroot 	if (type == NSYM || symtab == 0)
413767Sroot 		return (diff);
423767Sroot 	for (sp = symtab; sp < esymtab; sp++) {
43*30968Sbostic 		if (sp->n_type & N_STAB || !(sp->n_type & N_EXT)
44*30968Sbostic 		    || sp->n_type == (N_FN|N_EXT))
453767Sroot 			continue;
463767Sroot 		if (val - sp->n_value < diff && val >= sp->n_value) {
473767Sroot 			diff = val - sp->n_value;
483767Sroot 			cursym = sp;
493767Sroot 			if (diff == 0)
503767Sroot 				break;
513767Sroot 		}
523767Sroot 	}
533767Sroot 	return (diff);
543767Sroot }
553767Sroot 
563767Sroot /*
573767Sroot  * Advance cursym to the next local variable.
583767Sroot  * Leave its value in localval as a side effect.
593767Sroot  * Return 0 at end of file.
603767Sroot  */
localsym(cframe,cargp)613767Sroot localsym(cframe, cargp)
623767Sroot 	ADDR cframe, cargp;
633767Sroot {
643767Sroot 	register int type;
653767Sroot 	register struct nlist *sp;
663767Sroot 
673767Sroot 	if (cursym)
683767Sroot 	for (sp = cursym; ++sp < esymtab; ) {
693767Sroot 		if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN)
703767Sroot 			return (0);
713767Sroot 		type = sp->n_type;
723767Sroot 		switch (sp->n_type) {
733767Sroot 
743767Sroot 		case N_TEXT:
753767Sroot 		case N_TEXT|N_EXT:
763767Sroot 		case N_DATA:
773767Sroot 		case N_DATA|N_EXT:
783767Sroot 		case N_BSS:
793767Sroot 		case N_BSS|N_EXT:
803767Sroot 			localval = sp->n_value;
813767Sroot 			cursym = sp;
823767Sroot 			return (1);
833767Sroot 
843767Sroot 		case N_LSYM:
853767Sroot 			localval = cframe - sp->n_value;
863767Sroot 			cursym = sp;
873767Sroot 			return (1);
883767Sroot 
893767Sroot 		case N_PSYM:
903767Sroot 			/* code below works since n_value > 0 */
913767Sroot 		case N_ABS:
923767Sroot 			if (sp->n_value < 0)
933767Sroot 				localval = cframe + sp->n_value;
943767Sroot 			else
953767Sroot 				localval = cargp + sp->n_value;
963767Sroot 			cursym = sp;
973767Sroot 			return (1);
983767Sroot 		}
993767Sroot 	}
1003767Sroot 	cursym = 0;
1013767Sroot 	return (0);
1023767Sroot }
1033767Sroot 
1043767Sroot /*
1053767Sroot  * Print value v and then the string s.
1063767Sroot  * If v is not zero, then we look for a nearby symbol
1073767Sroot  * and print name+offset if we find a symbol for which
1083767Sroot  * offset is small enough.
1093767Sroot  *
1103767Sroot  * For values which are just into kernel address space
1113767Sroot  * that they match exactly or that they be more than maxoff
1123767Sroot  * bytes into kernel space.
1133767Sroot  */
psymoff(v,type,s)1143767Sroot psymoff(v, type, s)
1153767Sroot 	long v;
1163767Sroot 	int type;
1173767Sroot 	char *s;
1183767Sroot {
1193767Sroot 	long w;
1203767Sroot 
1213767Sroot 	if (v)
1223767Sroot 		w = findsym(v, type);
12318501Sedward 	if (v==0 || w >= maxoff || (INKERNEL(v) && KVTOPH(v) < maxoff && w))
1243767Sroot 		printf(LPRMODE, v);
1253767Sroot 	else {
1263767Sroot 		printf("%s", cursym->n_un.n_name);
1273767Sroot 		if (w)
1283767Sroot 			printf(OFFMODE, w);
1293767Sroot 	}
1303767Sroot 	printf(s);
1313767Sroot }
1323767Sroot 
1333767Sroot /*
1343767Sroot  * Print value v symbolically if it has a reasonable
1353767Sroot  * interpretation as name+offset.  If not, print nothing.
1363767Sroot  * Used in printing out registers $r.
1373767Sroot  */
valpr(v,idsp)1383767Sroot valpr(v, idsp)
1393767Sroot 	long v;
1403767Sroot {
1413767Sroot 	off_t d;
1423767Sroot 
1433767Sroot 	d = findsym(v, idsp);
1443767Sroot 	if (d >= maxoff)
1453767Sroot 		return;
1463767Sroot 	printf("%s", cursym->n_un.n_name);
1473767Sroot 	if (d)
1483767Sroot 		printf(OFFMODE, d);
1493767Sroot }
150