xref: /csrg-svn/old/sdb/display.c (revision 7773)
1*7773Srrh static	char sccsid[] = "@(#)display.c 4.3 08/17/82";
21331Sbill #include "head.h"
31331Sbill #include <a.out.h>
41331Sbill #include <stab.h>
51331Sbill #include "cdefs.h"
61331Sbill struct user u;
71331Sbill BKPTR	bkpthead;
81331Sbill 
91331Sbill #ifdef FLEXNAMES
101331Sbill #define	bread(a,b,c)	stread(b,c)
111331Sbill #define	blseek(a,b,c)	stseek(b,c)
121331Sbill #endif
131331Sbill 
141331Sbill /* initialize frame pointers to top of call stack */
151331Sbill /*  MACHINE DEPENDENT */
161331Sbill struct proct *
initframe()171331Sbill initframe() {
181331Sbill 	argp = *(ADDR *) (((ADDR) &u) + AP);
191331Sbill 	frame = *(ADDR *) (((ADDR) &u) + FP);
201331Sbill 	callpc = *(ADDR *) (((ADDR) &u) + PC);
211331Sbill 	if ((frame == 0) || (frame & 0xf0000000 != 0x70000000))
221331Sbill 		return(badproc);
231331Sbill 	return(adrtoprocp(callpc++));  /* ++ because UNIX backs up instrs */
241331Sbill }
251331Sbill 
261331Sbill 
271331Sbill struct proct *
nextframe()281331Sbill nextframe() {
291331Sbill 	callpc = get(frame+16, DSP);
301331Sbill 	argp = get(frame+8, DSP);
311331Sbill 	frame = get(frame+12, DSP) & EVEN;
322815Swnj 	if (callpc > 0x70000000) {
332815Swnj 		/* error handler kludge */
342815Swnj 		callpc = get(frame+64, DSP);
351331Sbill 		argp = get(frame+8, DSP);
361331Sbill 		frame = get(frame+12, DSP) & EVEN;
371331Sbill 	}
381331Sbill 	if ((frame == 0) || (frame & 0xf0000000 != 0x70000000))
391331Sbill 		return(badproc);
401331Sbill 	return(adrtoprocp(callpc-1));
411331Sbill }
421331Sbill 
431331Sbill /* returns core image address for variable */
441331Sbill /*  MACHINE DEPENDENT */
451331Sbill ADDR
formaddr(class,addr)461331Sbill formaddr(class, addr)
47*7773Srrh u_char class;
481331Sbill ADDR addr; {
491331Sbill if (debug) printf("formaddr(%o, %d)\n", class & 0377, addr);
501331Sbill 	switch(class & STABMASK) {
511331Sbill 	case N_RSYM:
521331Sbill 		return(stackreg(addr));
531331Sbill 	case N_GSYM:
541331Sbill 	case N_SSYM:
551331Sbill 	case N_STSYM:
561331Sbill 	case N_LCSYM:
571331Sbill 		return(addr);
581331Sbill 
591331Sbill 	case N_PSYM:
601331Sbill 		return(argp+addr);
611331Sbill 
621331Sbill 	case N_LSYM:
631331Sbill 		return(frame+addr);
641331Sbill 
651331Sbill 	default:
661331Sbill 		printf("Bad class in formaddr: 0%o",
671331Sbill 			class & 0377);
681331Sbill 		return(0);
691331Sbill 	}
701331Sbill }
711331Sbill 
721331Sbill char class;
731331Sbill 
741331Sbill /*
751331Sbill  *  stackreg(reg):
761331Sbill  * If the register for the current frame is somewhere on the stack
771331Sbill  * then return the address of where it is, otherwise its still in
781331Sbill  * the register so return the register number.
791331Sbill  * We distinguish the two by noting that register numbers are less
801331Sbill  * than 16 and that stack addresses are greater.
811331Sbill  *
821331Sbill  *  MACHINE DEPENDENT
831331Sbill  */
841331Sbill ADDR
stackreg(reg)851331Sbill stackreg(reg) {
861331Sbill 	register int curframe, regfl, mask, i;
871331Sbill 	struct proct *procp;
881331Sbill 	ADDR regaddr;
891331Sbill 
901331Sbill 	curframe = frame;
911331Sbill 	regaddr = reg;
921331Sbill 	regfl = 0x10000 << reg;
931331Sbill 	for (procp=initframe(); frame!=curframe; procp=nextframe()) {
941331Sbill 		if (procp == badproc) {
951331Sbill 			error("Stackreg error: frame");
961331Sbill 			return(-1);
971331Sbill 		}
981331Sbill 		mask = get(frame+4, DSP);
991331Sbill 		if (mask & regfl) {
1001331Sbill 			regaddr = frame + 20;
1011331Sbill 			for (i=0; i<reg; i++) {
1021331Sbill 				if (mask & 0x10000)
1031331Sbill 					regaddr += WORDSIZE;
1041331Sbill 				mask = mask >> 1;
1051331Sbill 			}
1061331Sbill 			if (!(mask & 0x10000)) {
1071331Sbill 				error("Stackreg error: contents");
1081331Sbill 				return(-1);
1091331Sbill 			}
1101331Sbill 		}
1111331Sbill 	}
1121331Sbill 	return(regaddr);
1131331Sbill }
1141331Sbill 
1151331Sbill /* returns address of proc:var. Sets externals class and subflag */
1161331Sbill ADDR
varaddr(proc,var)1171331Sbill varaddr(proc, var)
1181331Sbill char *proc, *var; {
1191331Sbill 	return(findvar(proc, var, "", 0));
1201331Sbill }
1211331Sbill 
1221331Sbill /*
1231331Sbill  * displays values of variables matching proc:var,
1241331Sbill  * returns its address
1251331Sbill  */
1261331Sbill ADDR
dispvar(proc,var,fmt)1271331Sbill dispvar(proc, var, fmt)
1281331Sbill char *proc, *var, *fmt; {
1291331Sbill 	return(findvar(proc, var, fmt, 1));
1301331Sbill }
1311331Sbill 
1321331Sbill /*
1331331Sbill  * Find and print values of all variables matching proc:var
1341331Sbill  *	using specified format.
1351331Sbill  * Returns address of last matching variable.
1361331Sbill  *
1371331Sbill  * prvar==0 => no output,
1381331Sbill  * prvar==1 => output value,
1391331Sbill  * prvar==2 => output addr
1401331Sbill  */
1411331Sbill ADDR
findvar(proc,var,fmt,prvar)1421331Sbill findvar(proc, var, fmt, prvar)
1431331Sbill char *proc, *var, *fmt; {
1441331Sbill 	ADDR addr = -1, a = -1;
1451331Sbill 	int metaflag = 0, match=0, nullflag=0, depthcnt = -1;
1461331Sbill 	char *comblk;
1471331Sbill 	register struct proct *procp;
1481331Sbill 
1491331Sbill 	if (percentflag) {	/* kludge for register names */
1501331Sbill 		return(regout(var, prvar, fmt));
1511331Sbill 	}
1521331Sbill 
1531331Sbill 	if (var[0] == '\0') {
1541331Sbill 		error("Unexpected null variable name");
1551331Sbill 		return(-1);
1561331Sbill 	}
1571331Sbill 
1581331Sbill 	metaflag = eqany('*', proc) || eqany('?', proc) ||
1591331Sbill 		eqany('*', var) || eqany('?', var);
1601331Sbill 
1611331Sbill 	if (proc[0] == '\0') {
1621331Sbill 		nullflag++;
1631331Sbill 		proc = curproc()->pname;
1641331Sbill 	}
1651331Sbill 
1661331Sbill 	comblk = colonflag ? "" : "*";
1671331Sbill 
1681331Sbill 	if (integ && !eqany(var[0], "->.[")) {
1691331Sbill 		depthcnt = integ;
1701331Sbill 	}
1711331Sbill 	if (integ) {
1721331Sbill 		if (eqany(var[0], "->.["))
1731331Sbill 			match++;
1741331Sbill 		else
1751331Sbill 			depthcnt = integ;
1761331Sbill 	}
1771331Sbill 
1781331Sbill 	procp = initframe();
1791331Sbill 	if (!eqany(var[0], "->.[") && !(nullflag && colonflag)) {
1801331Sbill 		do {
1811331Sbill 			if (eqpat(proc, procp->pname)) {
1821331Sbill 				match++;
1831331Sbill 				if (--depthcnt==0 || integ==0) {
1841331Sbill 					a = outvar(procp->pname, var, fmt,
1851331Sbill 						metaflag, integ, N_GSYM,
1861331Sbill 						0, prname, comblk, prvar);
1871331Sbill 					if (a != -1)
1881331Sbill 						addr = a;
1891331Sbill 					if (depthcnt == 0)
1901331Sbill 						break;
1911331Sbill 				}
1921331Sbill 			}
1931331Sbill 		} while ((procp=nextframe()) != badproc);
1941331Sbill 	}
1951331Sbill 
1961331Sbill 	if ((colonflag || metaflag || a == -1) &&
1971331Sbill 			(nullflag || eqpat(proc, ""))) {
1981331Sbill 		a = outvar("", var, fmt, metaflag, integ,
1991331Sbill 			N_GSYM, 0, prname, comblk, prvar);
2001331Sbill 		if (a != -1) {
2011331Sbill 			addr = a;
2021331Sbill 			match++;
2031331Sbill 		}
2041331Sbill 	}
2051331Sbill 
2061331Sbill 	if (match==0 && colonflag) {
2071331Sbill 		procp = initframe();
2081331Sbill 		do {
2091331Sbill 			if (eqstr(curproc()->pname, procp->pname))
2101331Sbill 				break;
2111331Sbill 		} while ((procp=nextframe()) != badproc);
2121331Sbill 		a = outvar(curproc()->pname, var, fmt, metaflag,
2131331Sbill 			integ, N_GSYM, 0, prname,
2141331Sbill 			nullflag ? "_BLNK_" : proc, prvar);
2151331Sbill 		if (a != -1) {
2161331Sbill 			addr = a;
2171331Sbill 			match++;
2181331Sbill 		}
2191331Sbill 	}
2201331Sbill 
2211331Sbill 	if (addr == -1 && match == 0) {
2221331Sbill 		addr = extoutvar(var, fmt, metaflag, prvar);
2231331Sbill 		if (addr != -1)
2241331Sbill 			return(addr);
2251331Sbill 	}
2261331Sbill 	if (match == 0) {
2271331Sbill 		printf("%s not an active procedure\n", proc);
2281331Sbill 		return(-1);
2291331Sbill 	}
2301331Sbill 	if (addr == -1) {
2311331Sbill 		if (var[0] == '.')
2321331Sbill 			var++;
2331331Sbill 		if (proc[0])
2341331Sbill #ifndef FLEXNAMES
2351331Sbill 			printf("%.16s:%s not found\n", proc, var);
2361331Sbill #else
2371331Sbill 			printf("%s:%s not found\n", proc, var);
2381331Sbill #endif
2391331Sbill 		else
2401331Sbill 			printf("%s not found\n", var);
2411331Sbill 		return(-1);
2421331Sbill 	}
2431331Sbill 	return(addr);
2441331Sbill }
2451331Sbill 
2461331Sbill char *
typetodesc(type,subflag)2471331Sbill typetodesc(type, subflag)
2481331Sbill short type; {
2491331Sbill 	register int ptr, ftn, ary;
2501331Sbill 	register char *desc;
2511331Sbill 
2521331Sbill 	static char *typedesc[] = {
2531331Sbill 		"d",  /* undef */
2541331Sbill 		"d",  /* farg */
2551331Sbill 		"c",  /* char */
2561331Sbill 		"hd",  /* short */
2571331Sbill 		"d",  /* int */
2581331Sbill 		"ld",  /* long */
2591331Sbill 		"f",  /* float */
2601331Sbill 		"g",  /* double */
2611331Sbill 		"d",  /* strty */
2621331Sbill 		"d",  /* unionty */
2631331Sbill 		"d",  /* enumty */
2641331Sbill 		"d",  /* moety */
2651331Sbill 		"bu",  /* uchar */
2661331Sbill 		"hu",  /* ushort */
2671331Sbill 		"u",  /* unsigned */
2681331Sbill 		"lu",  /* ulong */
2691331Sbill 		"d"   /* ? */
2701331Sbill 	};
2711331Sbill 
2721331Sbill 	ptr = ftn = ary = 0;
2731331Sbill 
2741331Sbill 	desc = typedesc[type&BTMASK];
2751331Sbill 	for (; type & TMASK; type = DECREF(type)) {
2761331Sbill 		if (ISPTR(type)) ptr++;
2771331Sbill 		else if (ISFTN(type)) ftn++;
2781331Sbill 		else if (ISARY(type)) ary++;
2791331Sbill 	}
2801331Sbill 
2811331Sbill 	if ((ptr-subflag == 1  || ary-subflag == 1)  &&  desc[0] == 'c')
2821331Sbill 		return("s");
2831331Sbill 	if (debug)
2841331Sbill 		printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc);
2851331Sbill 	if (ptr + ary ==  subflag)
2861331Sbill 		return(desc);
2871331Sbill 	if (ptr) return("x");
2881331Sbill 	if (ptr==1 && ftn==1) return("p");
2891331Sbill 	return(desc);
2901331Sbill }
2911331Sbill 
typetosize(type,stsize)2921331Sbill typetosize(type, stsize)
2931331Sbill short type; {
2941331Sbill 	register int ptr, ftn, ary;
2951331Sbill 	register int size;
2961331Sbill 
2971331Sbill 	static char typesize[] = {
2981331Sbill 		4,  /* undef */
2991331Sbill 		4,  /* farg */
3001331Sbill 		1,  /* char */
3011331Sbill 		2,  /* short */
3021331Sbill 		WORDSIZE,  /* int */
3031331Sbill 		4,  /* long */
3041331Sbill 		4,  /* float */
3051331Sbill 		8,  /* double */
3061331Sbill 		0,  /* strty */
3071331Sbill 		0,  /* unionty */
3081331Sbill 		4,  /* enumty */
3091331Sbill 		4,  /* moety */
3101331Sbill 		1,  /* uchar */
3111331Sbill 		2,  /* ushort */
3121331Sbill 		4,  /* unsigned */
3131331Sbill 		4,  /* ulong */
3141331Sbill 		4   /* ? */
3151331Sbill 	};
3161331Sbill 
3171331Sbill 	ptr = ftn = ary = 0;
3181331Sbill 
3191331Sbill 	size = typesize[type&BTMASK];
3201331Sbill 	for (; type & TMASK; type = DECREF(type)) {
3211331Sbill 		if (ISPTR(type)) ptr++;
3221331Sbill 		else if (ISFTN(type)) ftn++;
3231331Sbill 		else if (ISARY(type)) ary++;
3241331Sbill 	}
3251331Sbill 
3261331Sbill 	if (debug)
3271331Sbill 		printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n",
3281331Sbill 				ptr,ftn,ary,size,stsize);
3291331Sbill 	if (ptr>1) return(4);
3301331Sbill 	if (size == 0) return(stsize);
3311331Sbill 	else return(size);
3321331Sbill }
3331331Sbill 
3341331Sbill 
3351331Sbill /* print breakpoints */
prbkpt()3361331Sbill prbkpt() {
3371331Sbill 	register BKPTR bkptr;
3381331Sbill 	register int cnt;
3391331Sbill 	char *cmdp;
3401331Sbill 
3411331Sbill 	cnt = 0;
3421331Sbill 
3431331Sbill 	for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
3441331Sbill 		if (bkptr->flag) {
3451331Sbill 			cnt++;
3461331Sbill 			printbkpt("", adrtoprocp(bkptr->loc), bkptr->loc);
3471331Sbill 			cmdp = bkptr->comm;
3481331Sbill 			if (*cmdp != '\n') {
3491331Sbill 				printf("   <");
3501331Sbill 				while (*cmdp != '\n')
3511331Sbill 					printf("%c", *cmdp++);
3521331Sbill 				printf(">\n");
3531331Sbill 			}
3541331Sbill 			else
3551331Sbill 				printf("\n");
3561331Sbill 		}
3571331Sbill 	if (cnt == 0)
3581331Sbill 		printf("No breakpoints set\n");
3591331Sbill }
3601331Sbill 
3611331Sbill /* interactively delete breakpoints */
3621331Sbill 
idbkpt()3631331Sbill idbkpt() {
3641331Sbill 	register BKPTR bkptr;
3651331Sbill 	register int yesflg, cnt;
366*7773Srrh 	char c;
3671331Sbill 
3681331Sbill 	cnt = 0;
3691331Sbill 
3701331Sbill 	for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
3711331Sbill 		if (bkptr->flag) {
3721331Sbill 			printbkpt(" ? ", adrtoprocp(bkptr->loc), bkptr->loc);
3731331Sbill 			yesflg = 0;
3741331Sbill 			cnt++;
3751331Sbill 			do {
3761331Sbill 				c = getchar();
3771331Sbill 				if (c == 'y' || c == 'd') yesflg++;
3781331Sbill 			} while (c != '\n');
3791331Sbill 			if (yesflg)
3801331Sbill 				bkptr->flag = 0;
3811331Sbill 		}
3821331Sbill 	if (cnt == 0)
3831331Sbill 		printf("No breakpoints set\n");
3841331Sbill }
3851331Sbill 
3861331Sbill /* delete all breakpoints */
3871331Sbill 
dabkpt()3881331Sbill dabkpt() {
3891331Sbill 	register BKPTR bkptr;
3901331Sbill 
3911331Sbill 	for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
3921331Sbill 		bkptr->flag = 0;
3931331Sbill }
3941331Sbill 
3951331Sbill /*
3961331Sbill  * Print name of breakpoint for a, b, d commands:
3971331Sbill  */
printbkpt(s,procp,dot)3981331Sbill printbkpt(s, procp, dot)
3991331Sbill char *s; struct proct *procp; ADDR dot; {
4001331Sbill 	adrtolineno(dot);
4011331Sbill 	if (dot != lnfaddr)
4021331Sbill 		printf("0x%x (", dot);
4031331Sbill 	prlnoff(procp, dot);
4041331Sbill 	if (dot != lnfaddr)
4051331Sbill 		printf(")");
4061331Sbill 	printf("%s", s);
4071331Sbill }
4081331Sbill 
4091331Sbill /* print call frame */
prframe()4101331Sbill prframe() {
4111331Sbill 	prfrx(0);
4121331Sbill }
4131331Sbill 
4141331Sbill /* set top to print just the top procedure */
prfrx(top)4151331Sbill prfrx(top) {
4161331Sbill 	int narg;
4171331Sbill 	long offset;
418*7773Srrh 	u_char class;
4191331Sbill 	register int endflg;
4201331Sbill 	char *p;
4211331Sbill 	struct proct *procp;
4221331Sbill 	struct nlist stentry;
4231331Sbill 
4241331Sbill 	if ((procp = initframe()) == badproc) return;
4251331Sbill 	do {
4261331Sbill 		if (get(frame+12, DSP) == 0) return;
4271331Sbill 		p = procp->pname;
4281331Sbill 		if (eqstr("__dbsubc", p)) return;
4291331Sbill 		if (p[0] == '_') {
4301331Sbill 			endflg = 1;
4311331Sbill #ifndef FLEXNAMES
4321331Sbill 			printf("%.15s(", p+1);
4331331Sbill #else
4341331Sbill 			printf("%s(", p+1);
4351331Sbill #endif
4361331Sbill 		}
4371331Sbill 		else {
4381331Sbill #ifndef FLEXNAMES
4391331Sbill 			printf("%.16s(", p);
4401331Sbill #else
4411331Sbill 			printf("%s(", p);
4421331Sbill #endif
4431331Sbill 			endflg = 0;
4441331Sbill 		}
4451331Sbill 		if (endflg == 0) {
4461331Sbill 			offset = procp->st_offset;
4471331Sbill 			blseek(&sbuf, offset, 0);
4481331Sbill 			do {
4491331Sbill 				if (bread(&sbuf, &stentry, sizeof stentry) <
4501331Sbill 							sizeof stentry) {
4511331Sbill 					endflg++;
4521331Sbill 					break;
4531331Sbill 				}
4541331Sbill 				class = stentry.n_type & STABMASK;
4551331Sbill 			} while (class == N_FUN);
4561331Sbill 			while (class != N_PSYM) {
4571331Sbill 				if (bread(&sbuf, &stentry, sizeof stentry) <
4581331Sbill 							sizeof stentry) {
4591331Sbill 					endflg++;
4601331Sbill 					break;
4611331Sbill 				}
4621331Sbill 				class = stentry.n_type & STABMASK;
4631331Sbill 				if (class == N_FUN) {
4641331Sbill 					endflg++;
4651331Sbill 					break;
4661331Sbill 				}
4671331Sbill 			}
4681331Sbill 		}
4691331Sbill 		narg = get(argp, DSP);
4701331Sbill 		if (narg & ~0xff) narg = 0;
4711331Sbill 		argp += WORDSIZE;
4721331Sbill 		while (narg) {
4731331Sbill 			if (endflg) {
4741331Sbill 				printf("%d", get(argp, DSP));
4751331Sbill 				argp += 4;
4761331Sbill 			} else {
4771331Sbill 				int length;
4781331Sbill #ifndef FLEXNAMES
4791331Sbill 				printf("%.16s=", stentry.n_name);
4801331Sbill #else
4811331Sbill 				printf("%s=", stentry.n_un.n_name);
4821331Sbill #endif
4831331Sbill 				dispx(argp, "", N_GSYM, stentry.n_desc,
4841331Sbill 					0, 0, DSP);
4851331Sbill 				length = typetosize(stentry.n_desc, 0);
4861331Sbill 				if (length > WORDSIZE)
4871331Sbill 					argp += length;
4881331Sbill 				else
4891331Sbill 					argp += WORDSIZE;
4901331Sbill 			}
4911331Sbill 			do {
4921331Sbill 				if (endflg) break;
4931331Sbill 				if (bread(&sbuf, &stentry, sizeof stentry) <
4941331Sbill 							sizeof stentry) {
4951331Sbill 					endflg++;
4961331Sbill 					break;
4971331Sbill 				}
4981331Sbill 				class = stentry.n_type & STABMASK;
4991331Sbill 				if (class == N_FUN) {
5001331Sbill 					endflg++;
5011331Sbill 					break;
5021331Sbill 				}
5031331Sbill 			} while (class != N_PSYM);
5041331Sbill 		l1:	if (--narg != 0) printf(",");
5051331Sbill 		}
5061331Sbill 		printf(")");
5071331Sbill 		if (debug) printf("  @ 0x%x ", callpc);
5081331Sbill 		if (procp->sfptr != badfile)
5091331Sbill 			printf("   [%s:%d]", adrtofilep(callpc-1)->sfilename,
5101331Sbill 				adrtolineno(callpc-1));
5111331Sbill 		printf("\n");
5121331Sbill 	} while (((procp = nextframe()) != badproc) && !top);
5131331Sbill }
5141331Sbill 
5151331Sbill INT		signo;
5161331Sbill STRING		signals[];
5171331Sbill extern	nsig;
sigprint()5181331Sbill sigprint()
5191331Sbill {
5201331Sbill 
5211331Sbill 	if (signo < nsig)
5221331Sbill 		printf("%s", signals[signo]);
5231331Sbill 	else
5241331Sbill 		printf("signal %d???", signals[signo]);
5251331Sbill }
526