xref: /csrg-svn/old/adb/adb.vax/sym.c (revision 18501)
1*18501Sedward static	char sccsid[] = "@(#)sym.c 4.2 03/24/85";
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 *
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  */
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++) {
433767Sroot 		if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0)
443767Sroot 			continue;
453767Sroot 		if (val - sp->n_value < diff && val >= sp->n_value) {
463767Sroot 			diff = val - sp->n_value;
473767Sroot 			cursym = sp;
483767Sroot 			if (diff == 0)
493767Sroot 				break;
503767Sroot 		}
513767Sroot 	}
523767Sroot 	return (diff);
533767Sroot }
543767Sroot 
553767Sroot /*
563767Sroot  * Advance cursym to the next local variable.
573767Sroot  * Leave its value in localval as a side effect.
583767Sroot  * Return 0 at end of file.
593767Sroot  */
603767Sroot localsym(cframe, cargp)
613767Sroot 	ADDR cframe, cargp;
623767Sroot {
633767Sroot 	register int type;
643767Sroot 	register struct nlist *sp;
653767Sroot 
663767Sroot 	if (cursym)
673767Sroot 	for (sp = cursym; ++sp < esymtab; ) {
683767Sroot 		if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN)
693767Sroot 			return (0);
703767Sroot 		type = sp->n_type;
713767Sroot 		switch (sp->n_type) {
723767Sroot 
733767Sroot 		case N_TEXT:
743767Sroot 		case N_TEXT|N_EXT:
753767Sroot 		case N_DATA:
763767Sroot 		case N_DATA|N_EXT:
773767Sroot 		case N_BSS:
783767Sroot 		case N_BSS|N_EXT:
793767Sroot 			localval = sp->n_value;
803767Sroot 			cursym = sp;
813767Sroot 			return (1);
823767Sroot 
833767Sroot 		case N_LSYM:
843767Sroot 			localval = cframe - sp->n_value;
853767Sroot 			cursym = sp;
863767Sroot 			return (1);
873767Sroot 
883767Sroot 		case N_PSYM:
893767Sroot 			/* code below works since n_value > 0 */
903767Sroot 		case N_ABS:
913767Sroot 			if (sp->n_value < 0)
923767Sroot 				localval = cframe + sp->n_value;
933767Sroot 			else
943767Sroot 				localval = cargp + sp->n_value;
953767Sroot 			cursym = sp;
963767Sroot 			return (1);
973767Sroot 		}
983767Sroot 	}
993767Sroot 	cursym = 0;
1003767Sroot 	return (0);
1013767Sroot }
1023767Sroot 
1033767Sroot /*
1043767Sroot  * Print value v and then the string s.
1053767Sroot  * If v is not zero, then we look for a nearby symbol
1063767Sroot  * and print name+offset if we find a symbol for which
1073767Sroot  * offset is small enough.
1083767Sroot  *
1093767Sroot  * For values which are just into kernel address space
1103767Sroot  * that they match exactly or that they be more than maxoff
1113767Sroot  * bytes into kernel space.
1123767Sroot  */
1133767Sroot psymoff(v, type, s)
1143767Sroot 	long v;
1153767Sroot 	int type;
1163767Sroot 	char *s;
1173767Sroot {
1183767Sroot 	long w;
1193767Sroot 
1203767Sroot 	if (v)
1213767Sroot 		w = findsym(v, type);
122*18501Sedward 	if (v==0 || w >= maxoff || (INKERNEL(v) && KVTOPH(v) < maxoff && w))
1233767Sroot 		printf(LPRMODE, v);
1243767Sroot 	else {
1253767Sroot 		printf("%s", cursym->n_un.n_name);
1263767Sroot 		if (w)
1273767Sroot 			printf(OFFMODE, w);
1283767Sroot 	}
1293767Sroot 	printf(s);
1303767Sroot }
1313767Sroot 
1323767Sroot /*
1333767Sroot  * Print value v symbolically if it has a reasonable
1343767Sroot  * interpretation as name+offset.  If not, print nothing.
1353767Sroot  * Used in printing out registers $r.
1363767Sroot  */
1373767Sroot valpr(v, idsp)
1383767Sroot 	long v;
1393767Sroot {
1403767Sroot 	off_t d;
1413767Sroot 
1423767Sroot 	d = findsym(v, idsp);
1433767Sroot 	if (d >= maxoff)
1443767Sroot 		return;
1453767Sroot 	printf("%s", cursym->n_un.n_name);
1463767Sroot 	if (d)
1473767Sroot 		printf(OFFMODE, d);
1483767Sroot }
149