xref: /csrg-svn/old/sdb/docomm.c (revision 7774)
1*7774Srrh static	char sccsid[] = "@(#)docomm.c 4.2 08/17/82";
21332Sbill #include <signal.h>
31332Sbill #include "head.h"
41332Sbill #include <a.out.h>
51332Sbill #include <stab.h>
61332Sbill 
71332Sbill struct user u;
81332Sbill L_INT 	cntval;
91332Sbill INT	signo;
101332Sbill INT	adrflg;
111332Sbill INT	pid;
121332Sbill ADDR	userpc;
131332Sbill char	*s;
141332Sbill enum	{NOCOM, PRCOM, DSCOM, DSICOM} lastcom;
151332Sbill 		/* last command: nothing noteworthy, print source,
161332Sbill 			display variable, display instruction */
171332Sbill 
docommand()181332Sbill docommand() {
191332Sbill 	register char	*p;
201332Sbill 	register int	i;
211332Sbill 	register ADDR	addr, bkaddr;
221332Sbill 	struct proct 	*procp;
231332Sbill 	char s[4];
241332Sbill 
251332Sbill 	cntval = 1;
261332Sbill 	adrflg = 0;
271332Sbill 	errflg = 0;
281332Sbill 
291332Sbill 	if (scallf) {
301332Sbill 		doscall();
311332Sbill 		setcur(1);
321332Sbill 		lastcom = NOCOM;
331332Sbill 		return;
341332Sbill 	}
351332Sbill 
361332Sbill 	if (reflag) {  /* search for regular expression */
371332Sbill 		dore();
381332Sbill 		lastcom = PRCOM;
391332Sbill 		return;
401332Sbill 	}
411332Sbill 
421332Sbill 	if (cmd == '\0') {
431332Sbill 		if (integ != 0 && var[0] != '\0') {
441332Sbill 			error("Invalid command (1)");
451332Sbill 			return;
461332Sbill 		}
471332Sbill 		if (integ != 0) { /* print line number */
481332Sbill 			ffind(integ);
491332Sbill 			fprint();
501332Sbill 			lastcom = PRCOM;
511332Sbill 			return;
521332Sbill 		}
531332Sbill 		if (var[0] != 0) {
541332Sbill 			printf("Unexpected null command\n");
551332Sbill 			return;
561332Sbill 		}
571332Sbill 	}
581332Sbill 
591332Sbill 	switch (cmd) {
601332Sbill 
611332Sbill 	case 'Y':
621332Sbill 		debug = !debug;
631332Sbill 		break;
641332Sbill 
651332Sbill 	case 'V':
661332Sbill 		version();
671332Sbill 		break;
681332Sbill 
691332Sbill 	case 'M':
701332Sbill 		if (args[0]) {
711332Sbill 			setmap(args);
721332Sbill 		} else {
731332Sbill 			printmap("? map", &txtmap);
741332Sbill 			printmap("/ map", &datmap);
751332Sbill 		}
761332Sbill 		break;
771332Sbill 
781332Sbill 	case 'x':
791332Sbill 		printregs();
801332Sbill 		break;
811332Sbill 
821332Sbill 	case 'X':
831332Sbill 		printpc();
841332Sbill 		break;
851332Sbill 
861332Sbill 	case 'a':
871332Sbill 		if (integ) {
881332Sbill 			cpstr(args, "l\n");
891332Sbill 		} else if (proc[0]) {
901332Sbill 			cpall(args, "T\n");
911332Sbill 		} else {
921332Sbill 			error("Bad arguments");
931332Sbill 			break;
941332Sbill 		}
951332Sbill 		goto setbrk;
961332Sbill 		break;
971332Sbill 
981332Sbill 	case 'l':
991332Sbill 		setcur(1);
1001332Sbill 		lastcom = NOCOM;
1011332Sbill 		break;
1021332Sbill 
1031332Sbill 	case 'T':
1041332Sbill 		prfrx(1);
1051332Sbill 		lastcom = NOCOM;
1061332Sbill 		break;
1071332Sbill 
1081332Sbill 	case 't':
1091332Sbill 		prframe();
1101332Sbill 		lastcom = NOCOM;
1111332Sbill 		break;
1121332Sbill 
1131332Sbill 	case 'e':
1141332Sbill 		p = args;
1151332Sbill 		if (*p == '\0') {
1161332Sbill #ifndef FLEXNAMES
1171332Sbill 			printf("%.16s() in \"%s\"\n",
1181332Sbill 				curproc()->pname, curfile);
1191332Sbill #else
1201332Sbill 			printf("%s() in \"%s\"\n",
1211332Sbill 				curproc()->pname, curfile);
1221332Sbill #endif
1231332Sbill 			break;
1241332Sbill 		}
1251332Sbill 
1261332Sbill 		while (*p != '\0')
1271332Sbill 			if (*p++ == '.') goto l1;
1281332Sbill 		/* argument is procedure name */
1291332Sbill 		procp = findproc(args);
1301332Sbill 		if ((procp->pname[0] != '\0') && (procp->sfptr != badfile)) {
1311332Sbill 			finit(adrtofilep(procp->paddr)->sfilename);
1321332Sbill 			ffind(procp->lineno);
1331332Sbill 		}
1341332Sbill 		else printf("Can't find %s\n", args);
1351332Sbill #ifndef FLEXNAMES
1361332Sbill 		printf("%.16s() in \"%s\"\n", curproc()->pname, curfile);
1371332Sbill #else
1381332Sbill 		printf("%s() in \"%s\"\n", curproc()->pname, curfile);
1391332Sbill #endif
1401332Sbill 		lastcom = PRCOM;
1411332Sbill 		break;
1421332Sbill 
1431332Sbill 	l1:	/* argument is filename */
1441332Sbill 		finit(args);
1451332Sbill 		printf("\"%s\"\n", curfile);
1461332Sbill 		lastcom = PRCOM;
1471332Sbill 		break;
1481332Sbill 
1491332Sbill 	case 'p':
1501332Sbill 		if (integ) ffind(integ);
1511332Sbill 		fprint();
1521332Sbill 		lastcom = PRCOM;
1531332Sbill 		break;
1541332Sbill 
1551332Sbill 	case 'q':
1561332Sbill 		exit(0);
1571332Sbill 
1581332Sbill 	case 'w':
1591332Sbill 		if (integ) ffind(integ);
1601332Sbill 		i = fline;
1611332Sbill 		fback(WINDOW/2);
1621332Sbill 		fprintn(WINDOW);
1631332Sbill 		ffind(i);
1641332Sbill 		lastcom = PRCOM;
1651332Sbill 		break;
1661332Sbill 
1671332Sbill 	case 'Q':
1681332Sbill 		prdebug();
1691332Sbill 		break;
1701332Sbill 
1711332Sbill 	case 'z':
1721332Sbill 		if (integ) ffind(integ);
1731332Sbill 		fprintn(WINDOW);
1741332Sbill 		lastcom = PRCOM;
1751332Sbill 		break;
1761332Sbill 
1771332Sbill 	case '-':
1781332Sbill 		fback(integ ? integ : 1);
1791332Sbill 		fpargs();
1801332Sbill 		lastcom = PRCOM;
1811332Sbill 		break;
1821332Sbill 
1831332Sbill 	case '+':
1841332Sbill 		fforward(integ ? integ : 1);
1851332Sbill 		fpargs();
1861332Sbill 		lastcom = PRCOM;
1871332Sbill 		break;
1881332Sbill 
1891332Sbill 	case '\n':
1901332Sbill 		switch (lastcom) {
1911332Sbill 		case PRCOM:
1921332Sbill 			fforward(1);
1931332Sbill 			fprint();
1941332Sbill 			break;
1951332Sbill 		case DSCOM:
1961332Sbill 			oaddr += oincr ? oincr : typetosize(otype, WORDSIZE);
1971332Sbill 			printf("0x%x/ ", oaddr);
1981332Sbill 			dispf((ADDR) oaddr, odesc,
1991332Sbill 			    oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
2001332Sbill 			break;
2011332Sbill 		case DSICOM:
2021332Sbill 			dot += oincr;
2031332Sbill 			prisploc();
2041332Sbill 			dispi(dot, odesc, N_GSYM, 0, 0);
2051332Sbill 			break;
2061332Sbill 		}
2071332Sbill 		break;
2081332Sbill 
2091332Sbill 	case '\004':
2101332Sbill 		if (!isatty(0))
2111332Sbill 			exit(0);
2121332Sbill 		switch (lastcom) {
2131332Sbill 		case PRCOM:
2141332Sbill 			fforward(1);
2151332Sbill 			printf("\b");
2161332Sbill 			fprintn(WINDOW);
2171332Sbill 			lastcom = PRCOM;
2181332Sbill 			break;
2191332Sbill 		case DSICOM:
2201332Sbill 			printf("\b");
2211332Sbill 			for (i=0; i<WINDOW; i++) {
2221332Sbill 				dot += oincr;
2231332Sbill 				prisploc();
2241332Sbill 				if (dispi(dot, odesc, N_GSYM, 0, 0) == -1)
2251332Sbill 					break;
2261332Sbill 			}
2271332Sbill 			break;
2281332Sbill 		case DSCOM:
2291332Sbill 			printf("\b");
2301332Sbill 			for (i=0; i<WINDOW; i++) {
2311332Sbill 				oaddr += oincr ?
2321332Sbill 					oincr : typetosize(otype, WORDSIZE);
2331332Sbill 				printf("0x%x/ ", oaddr);
2341332Sbill 				if (dispf((ADDR) oaddr, odesc,
2351332Sbill 					oclass == N_RSYM ? oclass :
2361332Sbill 					N_GSYM, otype, 0, 0, DSP) == -1)
2371332Sbill 					break;
2381332Sbill 			}
2391332Sbill 			break;
2401332Sbill 		default:
2411332Sbill 			printf("\n");
2421332Sbill 		}
2431332Sbill 		break;
2441332Sbill 
2451332Sbill 	case 'r':
2461332Sbill 		if (args[0] == '\0') getargs();
2471332Sbill 	case 'R':
2481332Sbill 		signo = 0;
2491332Sbill 		cpstr(oldargs, args);
2501332Sbill 		if (debug) error("calling dopcs");
2511332Sbill 		if (integ) cntval = integ;
2521332Sbill 		if (!executing) {
2531332Sbill 			executing = TRUE;
2541332Sbill 			if (integ) cntval = integ;
2551332Sbill 			dopcs('r');
2561332Sbill 			executing = FALSE;
2571332Sbill 		}
2581332Sbill 		if (debug) error("exiting dopcs");
2591332Sbill 		bkaddr = -1;
2601332Sbill 		goto f1;
2611332Sbill 
2621332Sbill 	case 'c':
2631332Sbill 		signo = 0;
2641332Sbill 	case 'C':
2651332Sbill 		if (proc[0] != '\0' || integ != 0) {
2661332Sbill 			setdot();
2671332Sbill 			if (dot == -1) {
2681332Sbill 				error("Cannot set temporary breakpoint");
2691332Sbill 				break;
2701332Sbill 			}
2711332Sbill 			dopcs('b');
2721332Sbill 			bkaddr = dot;
2731332Sbill 		} else
2741332Sbill 			bkaddr = -1;
2751332Sbill 		integ = atoi(args);
2761332Sbill 
2771332Sbill f1:		if (debug) error("calling dopcs");
2781332Sbill 		if (integ) cntval = integ;
2791332Sbill 		dopcs('c');
2801332Sbill 		if (debug) error("exiting dopcs");
2811332Sbill 		if (bkaddr != -1) {
2821332Sbill 			ADDR dotsave;
2831332Sbill 			dotsave = dot;
2841332Sbill 			dot = bkaddr;
2851332Sbill 			dopcs('d');
2861332Sbill 			dot = dotsave;
2871332Sbill 		}
2881332Sbill 		if (!signo) printf("Breakpoint");
2891332Sbill 		printf(" at\n");
2901332Sbill 		setcur(1);
2911332Sbill 		lastcom = NOCOM;
2921332Sbill 		break;
2931332Sbill 
2941332Sbill 	case 'S':
2951332Sbill 	case 's':
2961332Sbill 		signo = 0;
2971332Sbill 		integ = atoi(args);
2981332Sbill 		singstep(integ ? integ : 1, cmd);
2991332Sbill 		if (signo) printf("\n");
3001332Sbill 		setcur(1);
3011332Sbill 		lastcom = NOCOM;
3021332Sbill 		break;
3031332Sbill 
3041332Sbill 	case 'g':
3051332Sbill 		if (pid == 0  ||  signo) {
3061332Sbill 			error("Not stopped at breakpoint");
3071332Sbill 			break;
3081332Sbill 		}
3091332Sbill 		setdot();
3101332Sbill 		if (dot == -1) {
3111332Sbill 			error("Bad address");
3121332Sbill 			break;
3131332Sbill 		}
3141332Sbill 		adrflg = 1;
3151332Sbill 		integ = atoi(args);
3161332Sbill 		if (integ) cntval = integ;
3171332Sbill 		dopcs('c');
3181332Sbill 		if (!signo) printf("Breakpoint");
3191332Sbill 		printf(" at\n");
3201332Sbill 		setcur(1);
3211332Sbill 		lastcom = NOCOM;
3221332Sbill 		break;
3231332Sbill 
3241332Sbill 	case 'k':
3251332Sbill 		if (scallx) {
3261332Sbill 	 		userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs;
3271332Sbill 	 		*(ADDR *)(((ADDR)&u)+FP) = fps;
3281332Sbill 	 		*(ADDR *)(((ADDR)&u)+AP) = aps;
3291332Sbill 			if (bkpts)
3301332Sbill 				bkpts->flag = flagss;
3311332Sbill 			scallx = 0;
3321332Sbill 			error("Procedure killed");
3331332Sbill 			longjmp(env, 0);
3341332Sbill 		} else {
3351332Sbill 			dopcs('k');
3361332Sbill 			printf("\n");
3371332Sbill 			lastcom = NOCOM;
3381332Sbill 			break;
3391332Sbill 		}
3401332Sbill 
3411332Sbill 	case 'B':
3421332Sbill 		prbkpt();
3431332Sbill 		break;
3441332Sbill 
3451332Sbill 	case 'b':
3461332Sbill 	setbrk:
3471332Sbill 		if (proc[0] == '\0' && integ == 0) {
3481332Sbill 			integ = fline;
3491332Sbill 		}
3501332Sbill 		setdot();
3511332Sbill 		if (dot == -1 || dot == 0) {
3521332Sbill 			error("Cannot set breakpoint");
3531332Sbill 			break;
3541332Sbill 		}
3551332Sbill 		dopcs('b');
3561332Sbill 		s[0] = ' ';
3571332Sbill 		s[1] = cmd;
3581332Sbill 		s[2] = '\n';
3591332Sbill 		s[3] = 0;
3601332Sbill 		s[1] = cmd;
3611332Sbill 		printbkpt(s, adrtoprocp(dot), dot);
3621332Sbill 		break;
3631332Sbill 
3641332Sbill 	case 'd':
3651332Sbill 		if (proc[0] == '\0' && integ == 0) {
3661332Sbill 			idbkpt();
3671332Sbill 			break;
3681332Sbill 		}
3691332Sbill 		setdot();
3701332Sbill 		if (dot == -1) {
3711332Sbill 			error("Non existent breakpoint");
3721332Sbill 			break;
3731332Sbill 		}
3741332Sbill 		dopcs('d');
3751332Sbill 		break;
3761332Sbill 
3771332Sbill 	case 'D':
3781332Sbill 		dabkpt();
3791332Sbill 		error("All breakpoints deleted");
3801332Sbill 		break;
3811332Sbill 
3821332Sbill 	case 'm':
3831332Sbill 		addr = varaddr(proc[0] ? proc : curproc()->pname, var);
3841332Sbill 		printf("stopped with value %d\n", monex(addr, 'd'));
3851332Sbill 		setcur(1);
3861332Sbill 		lastcom = NOCOM;
3871332Sbill 		break;
3881332Sbill 
3891332Sbill 	case '?':
3901332Sbill 		if (!(var[0] == '.' && var[1] == '\0'))
3911332Sbill 			setdot();
3921332Sbill 		if (errflg) {
3931332Sbill 			error(errflg);
3941332Sbill 			break;
3951332Sbill 		}
3961332Sbill 		prisploc();
3971332Sbill 		dispi(dot, args[0] ? args : "i", N_GSYM, 0, 0);
3981332Sbill 		lastcom = DSICOM;
3991332Sbill 		break;
4001332Sbill 
4011332Sbill 	case '/':
4021332Sbill 		if (var[0] == '.' && var[1] == '\0') {
4031332Sbill 			if (integ == 0) integ = oaddr;
4041332Sbill 			dispf((ADDR) integ, args[0] ? args : odesc,
4051332Sbill 			    oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
4061332Sbill 			oaddr = integ;
4071332Sbill 		} else
4081332Sbill 		if (integ && (var[0] == '\0')) {
4091332Sbill 			dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP);
4101332Sbill 			oaddr = integ;
4111332Sbill 			cpstr(odesc, args);
4121332Sbill 			oclass = N_GSYM;
4131332Sbill 			otype = 0;
4141332Sbill 		} else
4151332Sbill 			dispvar(proc, var, args);
4161332Sbill 		lastcom = DSCOM;
4171332Sbill 		break;
4181332Sbill 
4191332Sbill 	case '=':
4201332Sbill 		if (var[0] == '\0') {
4211332Sbill 			if (proc[0]) {
4221332Sbill 				addr = getaddr(proc, integ);
4231332Sbill 				if (addr == -1) {
4241332Sbill 					error("Unknown address");
4251332Sbill 					break;
4261332Sbill 				}
4271332Sbill 			}
4281332Sbill 			else
4291332Sbill 				addr = integ;
4301332Sbill 			dispf(addr, args[0] ? args : "x", 0, -1, 0, 0, DSP);
4311332Sbill 		} else
4321332Sbill 			findvar(proc, var, args[0] ? args : "x", 2);
4331332Sbill 		break;
4341332Sbill 
4351332Sbill 	case '!':
4361332Sbill 		if (var[0] == '\0')
4371332Sbill 			addr = getaddr(proc, integ);
4381332Sbill 		else
4391332Sbill 			addr = varaddr(proc, var);
4401332Sbill 		if (addr == -1)
4411332Sbill 			error("Unknown variable");
4421332Sbill 		else {
4431332Sbill 			if (number(args[0]) || eqany(args[0], ".-")) {
4441332Sbill 				char *p;
4451332Sbill 				double atof();
4461332Sbill 				union {
4471332Sbill 					struct{
4481332Sbill 						int w1, w2;
4491332Sbill 					} ww;
4501332Sbill 					double d;
4511332Sbill 				} dbl;
4521332Sbill 
4531332Sbill 				p = (args[0] == '-') ? args+1 : args;
4541332Sbill 				for (; *p != '.' && *p != 'e'; p++) {
4551332Sbill 					if (!number(*p)) goto l2;
4561332Sbill 				}
4571332Sbill 				dbl.d = atof(args);
4581332Sbill 				putval(addr, 'd', dbl.ww.w1);
4591332Sbill 				if (typetodesc(sl_type,0)[0] == 'g')
4601332Sbill 					putval(addr+WORDSIZE, 'd', dbl.ww.w2);
4611332Sbill 				break;
4621332Sbill 			}
4631332Sbill l2:			if (percentflag)
4641332Sbill 				*(ADDR *)(((ADDR)&u)+addr) = argvalue(args);
4651332Sbill 			else if (sl_class == N_RSYM && addr < 16)
4661332Sbill 				putreg(addr,typetodesc(sl_type,subflag)[0],
4671332Sbill 						argvalue(args));
4681332Sbill 			else
4691332Sbill 				putval(addr,typetodesc(sl_type,subflag)[0],
4701332Sbill 						argvalue(args));
4711332Sbill 		}
4721332Sbill 		lastcom = NOCOM;
4731332Sbill 		break;
4741332Sbill 
4751332Sbill 	case '"':
4761332Sbill 		printf(args);
4771332Sbill 		break;
4781332Sbill 	}
4791332Sbill }
4801332Sbill 
fpargs()4811332Sbill fpargs() {
4821332Sbill 	register int i;
4831332Sbill 
4841332Sbill 	switch(args[0]) {
4851332Sbill 	case 'p':
4861332Sbill 	case '\0':
4871332Sbill 		fprint();
4881332Sbill 		break;
4891332Sbill case 'w':
4901332Sbill 		i = fline;
4911332Sbill 		fback(WINDOW/2);
4921332Sbill 		fprintn(WINDOW);
4931332Sbill 		ffind(i);
4941332Sbill 		break;
4951332Sbill 	case 'z':
4961332Sbill 		fprintn(WINDOW);
4971332Sbill 		break;
4981332Sbill 	}
4991332Sbill }
5001332Sbill 
5011332Sbill MSG	BADTXT;
5021332Sbill /* Used by a, b, c, C, d and g commands to find linenumber */
setdot()5031332Sbill setdot() {
5041332Sbill 	if (ncolonflag) {
5051332Sbill 		dot = integ;
5061332Sbill 		get(dot, ISP);
5071332Sbill 		if (errflg)
5081332Sbill 			dot = -1;
5091332Sbill 	} else {
5101332Sbill 		dot = getaddr(proc, integ);
5111332Sbill 		if (dot == -1)
5121332Sbill 			errflg = "Bad line number";
5131332Sbill 	}
5141332Sbill }
515