xref: /original-bsd/old/sdb/runpcs.c (revision b09715ed)
1*b09715edSrrh static	char sccsid[] = "@(#)runpcs.c 4.2 08/17/82";
21e5ca63fSbill #
31e5ca63fSbill /*
41e5ca63fSbill  *
51e5ca63fSbill  *	UNIX debugger
61e5ca63fSbill  *
71e5ca63fSbill  */
81e5ca63fSbill 
91e5ca63fSbill #include "head.h"
101e5ca63fSbill #include <a.out.h>
111e5ca63fSbill #include <stab.h>
121e5ca63fSbill struct user u;
131e5ca63fSbill #include <stdio.h>
141e5ca63fSbill 
151e5ca63fSbill #ifndef SIGTRAP
161e5ca63fSbill #define	SIGTRAP SIGTRC
171e5ca63fSbill #endif
181e5ca63fSbill 
191e5ca63fSbill MSG		NOFORK;
201e5ca63fSbill MSG		ENDPCS;
211e5ca63fSbill MSG		BADWAIT;
221e5ca63fSbill 
231e5ca63fSbill ADDR		sigint;
241e5ca63fSbill ADDR		sigqit;
251e5ca63fSbill ADDR		userpc;
261e5ca63fSbill 
271e5ca63fSbill /* breakpoints */
281e5ca63fSbill BKPTR		bkpthead;
291e5ca63fSbill 
301e5ca63fSbill CHAR		lastc;
311e5ca63fSbill 
321e5ca63fSbill INT		fcor;
331e5ca63fSbill INT		fsym;
341e5ca63fSbill STRING		errflg;
351e5ca63fSbill int		errno;
361e5ca63fSbill INT		signo;
371e5ca63fSbill 
381e5ca63fSbill L_INT		dot;
391e5ca63fSbill STRING		symfil;
401e5ca63fSbill INT		wtflag;
411e5ca63fSbill INT		pid;
421e5ca63fSbill INT		adrflg;
431e5ca63fSbill L_INT		loopcnt;
441e5ca63fSbill 
451e5ca63fSbill 
461e5ca63fSbill 
471e5ca63fSbill 
481e5ca63fSbill 
491e5ca63fSbill 
getsig(sig)501e5ca63fSbill getsig(sig)
511e5ca63fSbill {	return(sig);
521e5ca63fSbill }
531e5ca63fSbill 
runpcs(runmode,execsig)541e5ca63fSbill runpcs(runmode,execsig)
551e5ca63fSbill {
561e5ca63fSbill 	REG BKPTR	bkpt;
571e5ca63fSbill 	IF adrflg THEN userpc=dot; FI
581e5ca63fSbill 	WHILE --loopcnt>=0
591e5ca63fSbill 	DO
601e5ca63fSbill 		if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
611e5ca63fSbill 		IF runmode==SINGLE
621e5ca63fSbill 		THEN delbp(); /* hardware handles single-stepping */
631e5ca63fSbill 		ELSE /* continuing from a breakpoint is hard */
641e5ca63fSbill 			IF bkpt=scanbkpt(userpc)
651e5ca63fSbill 			THEN execbkpt(bkpt,execsig); execsig=0;
661e5ca63fSbill 			FI
671e5ca63fSbill 			setbp();
681e5ca63fSbill 		FI
691e5ca63fSbill 		ptrace(runmode,pid,userpc,execsig);
701e5ca63fSbill 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
711e5ca63fSbill 
721e5ca63fSbill 	loop1:	IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
731e5ca63fSbill 		THEN /* stopped by BPT instruction */
741e5ca63fSbill 			if (debug) printf("\n BPT code; '%s'%o'%o'%d",
751e5ca63fSbill 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
761e5ca63fSbill 			dot=bkpt->loc;
771e5ca63fSbill 			IF bkpt->comm[0] != EOR
781e5ca63fSbill 			THEN acommand(bkpt->comm);
791e5ca63fSbill 			FI
801e5ca63fSbill 			IF bkpt->flag==BKPTEXEC
811e5ca63fSbill 			ORF ((bkpt->flag=BKPTEXEC)
821e5ca63fSbill 				ANDF bkpt->comm[0]!=EOR)
831e5ca63fSbill 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
841e5ca63fSbill 			     goto loop1;
851e5ca63fSbill  			ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
861e5ca63fSbill 			FI
871e5ca63fSbill 		ELSE execsig=signo;
881e5ca63fSbill 		     if (execsig) break;
891e5ca63fSbill 		FI
901e5ca63fSbill 	OD
911e5ca63fSbill  		if (debug) printf("Returning from runpcs\n");
921e5ca63fSbill }
931e5ca63fSbill 
941e5ca63fSbill #define BPOUT 0
951e5ca63fSbill #define BPIN 1
961e5ca63fSbill INT bpstate;
971e5ca63fSbill 
endpcs()981e5ca63fSbill endpcs()
991e5ca63fSbill {
1001e5ca63fSbill 	REG BKPTR	bkptr;
1011e5ca63fSbill  		if (debug) printf("Entering endpcs with pid=%d\n");
1021e5ca63fSbill 	IF pid
1031e5ca63fSbill 	THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
1041e5ca63fSbill 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
1051e5ca63fSbill 	     DO IF bkptr->flag
1061e5ca63fSbill 		THEN bkptr->flag=BKPTSET;
1071e5ca63fSbill 		FI
1081e5ca63fSbill 	     OD
1091e5ca63fSbill 	FI
1101e5ca63fSbill 	bpstate=BPOUT;
1111e5ca63fSbill }
1121e5ca63fSbill 
1131e5ca63fSbill #ifdef VFORK
nullsig()1141e5ca63fSbill nullsig()
1151e5ca63fSbill {
1161e5ca63fSbill 
1171e5ca63fSbill }
1181e5ca63fSbill #endif
1191e5ca63fSbill 
setup()1201e5ca63fSbill setup()
1211e5ca63fSbill {
1221e5ca63fSbill 	close(fsym); fsym = -1;
1231e5ca63fSbill #ifdef VFORK
1241e5ca63fSbill 	IF (pid = vfork()) == 0
1251e5ca63fSbill #else
1261e5ca63fSbill 	IF (pid = fork()) == 0
1271e5ca63fSbill #endif
1281e5ca63fSbill 	THEN ptrace(SETTRC,0,0,0);
1291e5ca63fSbill 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
1301e5ca63fSbill #ifdef VFORK
1311e5ca63fSbill 	     signal(SIGTRAP,nullsig);
1321e5ca63fSbill #endif
1331e5ca63fSbill  		if (debug) printf("About to doexec  pid=%d\n",pid);
1341e5ca63fSbill 	     doexec(); _exit(0);
1351e5ca63fSbill 	ELIF pid == -1
1361e5ca63fSbill 	THEN error(NOFORK);
1371e5ca63fSbill 	ELSE bpwait(); readregs();
1381e5ca63fSbill 	if (debug) printf("About to open symfil = %s\n", symfil);
1391e5ca63fSbill 	     fsym=open(symfil,wtflag);
1401e5ca63fSbill 	     IF errflg
1411e5ca63fSbill 	     THEN printf("%s: cannot execute\n",symfil);
1421e5ca63fSbill  		if (debug) printf("%d %s\n", errflg, errflg);
1431e5ca63fSbill 		  endpcs();
1441e5ca63fSbill 	     FI
1451e5ca63fSbill 	FI
1461e5ca63fSbill 	bpstate=BPOUT;
1471e5ca63fSbill }
1481e5ca63fSbill 
execbkpt(bkptr,execsig)1491e5ca63fSbill execbkpt(bkptr,execsig)
1501e5ca63fSbill BKPTR	bkptr;
1511e5ca63fSbill {
1521e5ca63fSbill 	if (debug) printf("exbkpt: %d\n",bkptr->count);
1531e5ca63fSbill 	delbp();
1541e5ca63fSbill 	ptrace(SINGLE,pid,bkptr->loc,execsig);
1551e5ca63fSbill 	bkptr->flag=BKPTSET;
1561e5ca63fSbill 	bpwait(); chkerr(); readregs();
1571e5ca63fSbill }
1581e5ca63fSbill 
1591e5ca63fSbill extern STRING environ;
1601e5ca63fSbill 
doexec()1611e5ca63fSbill doexec()
1621e5ca63fSbill {
1631e5ca63fSbill 	char *argl[MAXARG], args[LINSIZ];
1641e5ca63fSbill 	register char c, redchar, *argsp, **arglp, *filnam;
1651e5ca63fSbill 
1661e5ca63fSbill 	arglp = argl;
1671e5ca63fSbill 	argsp = args;
1681e5ca63fSbill 	*arglp++ = symfil;
1691e5ca63fSbill 	c = ' ';
1701e5ca63fSbill 
1711e5ca63fSbill 	do {
1721e5ca63fSbill 		while (eqany(c, " \t")) {
1731e5ca63fSbill 			c = rdc();
1741e5ca63fSbill 		}
1751e5ca63fSbill 		if (eqany(c, "<>")) {
1761e5ca63fSbill 			redchar = c;
1771e5ca63fSbill 			do {
1781e5ca63fSbill 				c = rdc();
1791e5ca63fSbill 			} while (eqany(c, " \t"));
1801e5ca63fSbill 			filnam = argsp;
1811e5ca63fSbill 			do {
1821e5ca63fSbill 				*argsp++ = c;
1831e5ca63fSbill 				c = rdc();
1841e5ca63fSbill 			} while (!eqany(c, " <>\t\n"));
1851e5ca63fSbill 			*argsp++ = '\0';
1861e5ca63fSbill 			if (redchar == '<') {
1871e5ca63fSbill 				close(0);
1881e5ca63fSbill 				if (open(filnam,0) < 0) {
1891e5ca63fSbill 					printf("%s: cannot open\n",filnam);
1901e5ca63fSbill 					fflush(stdout);
1911e5ca63fSbill 					_exit(0);
1921e5ca63fSbill 				}
1931e5ca63fSbill 			} else {
1941e5ca63fSbill 				close(1);
1951e5ca63fSbill 				if (creat(filnam,0666) < 0) {
1961e5ca63fSbill 					printf("%s: cannot create\n",filnam);
1971e5ca63fSbill 					fflush(stdout);
1981e5ca63fSbill 					 _exit(0);
1991e5ca63fSbill 				}
2001e5ca63fSbill 			}
2011e5ca63fSbill 		} else if (c != '\n') {
2021e5ca63fSbill 			*arglp++ = argsp;
2031e5ca63fSbill 			do {
2041e5ca63fSbill 				*argsp++ = c;
2051e5ca63fSbill 				c = rdc();
2061e5ca63fSbill 			} while(!eqany(c, " <>\t\n"));
2071e5ca63fSbill 			*argsp++ = '\0';
2081e5ca63fSbill 		}
2091e5ca63fSbill 	} while (c != '\n');
2101e5ca63fSbill 	*arglp = (char *) 0;
2111e5ca63fSbill 	if (debug) {
2121e5ca63fSbill 		char **dap;
2131e5ca63fSbill 		printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
2141e5ca63fSbill 		for (dap = argl; *dap; dap++) {
2151e5ca63fSbill 			printf("%s, ", *dap);
2161e5ca63fSbill 		}
2171e5ca63fSbill 	}
2181e5ca63fSbill 	exect(symfil, argl, environ);
2191e5ca63fSbill 	perror("Returned from exect");
2201e5ca63fSbill }
2211e5ca63fSbill 
scanbkpt(adr)2221e5ca63fSbill BKPTR	scanbkpt(adr)
2231e5ca63fSbill ADDR adr;
2241e5ca63fSbill {
2251e5ca63fSbill 	REG BKPTR	bkptr;
2261e5ca63fSbill 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2271e5ca63fSbill 	DO IF bkptr->flag ANDF bkptr->loc==adr
2281e5ca63fSbill 	   THEN break;
2291e5ca63fSbill 	   FI
2301e5ca63fSbill 	OD
2311e5ca63fSbill 	return(bkptr);
2321e5ca63fSbill }
2331e5ca63fSbill 
delbp()2341e5ca63fSbill delbp()
2351e5ca63fSbill {
2361e5ca63fSbill 	REG ADDR	a;
2371e5ca63fSbill 	REG BKPTR	bkptr;
2381e5ca63fSbill 	IF bpstate!=BPOUT
2391e5ca63fSbill 	THEN
2401e5ca63fSbill 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2411e5ca63fSbill 		DO	IF bkptr->flag
2421e5ca63fSbill 			THEN a=bkptr->loc;
2431e5ca63fSbill 				ptrace(WIUSER,pid,a,
2441e5ca63fSbill 					(bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
2451e5ca63fSbill 			FI
2461e5ca63fSbill 		OD
2471e5ca63fSbill 		bpstate=BPOUT;
2481e5ca63fSbill 	FI
2491e5ca63fSbill }
2501e5ca63fSbill 
setbp()2511e5ca63fSbill setbp()
2521e5ca63fSbill {
2531e5ca63fSbill 	REG ADDR		a;
2541e5ca63fSbill 	REG BKPTR	bkptr;
2551e5ca63fSbill 
2561e5ca63fSbill 	IF bpstate!=BPIN
2571e5ca63fSbill 	THEN
2581e5ca63fSbill 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2591e5ca63fSbill 		DO IF bkptr->flag
2601e5ca63fSbill 		   THEN a = bkptr->loc;
2611e5ca63fSbill 			bkptr->ins = ptrace(RIUSER, pid, a, 0);
2621e5ca63fSbill 			ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
2631e5ca63fSbill 			IF errno
2641e5ca63fSbill 			THEN error("cannot set breakpoint: ");
2651e5ca63fSbill 			     printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
2661e5ca63fSbill 				adrtolineno(dot), dot);
2671e5ca63fSbill 			FI
2681e5ca63fSbill 		   FI
2691e5ca63fSbill 		OD
2701e5ca63fSbill 		bpstate=BPIN;
2711e5ca63fSbill 	FI
2721e5ca63fSbill }
2731e5ca63fSbill 
bpwait()2741e5ca63fSbill bpwait()
2751e5ca63fSbill {
2761e5ca63fSbill 	REG ADDR w;
2771e5ca63fSbill 	ADDR stat;
2781e5ca63fSbill 
2791e5ca63fSbill 	signal(SIGINT, 1);
2801e5ca63fSbill 	if (debug) printf("Waiting for pid %d\n",pid);
2811e5ca63fSbill 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
2821e5ca63fSbill 	if (debug) printf("Ending wait\n");
2831e5ca63fSbill 	if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
2841e5ca63fSbill 	signal(SIGINT,sigint);
2851e5ca63fSbill 	IF w == -1
2861e5ca63fSbill 	THEN pid=0;
2871e5ca63fSbill 	     errflg=BADWAIT;
2881e5ca63fSbill 	ELIF (stat & 0177) != 0177
2891e5ca63fSbill 	THEN IF signo = stat&0177
2901e5ca63fSbill 	     THEN sigprint();
2911e5ca63fSbill 	     FI
2921e5ca63fSbill 	     IF stat&0200
2931e5ca63fSbill 	     THEN error(" - core dumped");
2941e5ca63fSbill 		  close(fcor);
2951e5ca63fSbill 		  setcor();
2961e5ca63fSbill 	     FI
2971e5ca63fSbill 	     pid=0;
2981e5ca63fSbill 	     errflg=ENDPCS;
2991e5ca63fSbill 	ELSE signo = stat>>8;
3001e5ca63fSbill     	     if (debug) printf("PC = %d, dbsubn = %d\n",
3011e5ca63fSbill 		ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
3021e5ca63fSbill 	     IF signo!=SIGTRAP ANDF
3031e5ca63fSbill 		ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
3041e5ca63fSbill 	     THEN sigprint();
3051e5ca63fSbill 	     ELSE signo=0;
3061e5ca63fSbill 	     FI
3071e5ca63fSbill 	FI
3081e5ca63fSbill }
3091e5ca63fSbill 
3101e5ca63fSbill REGLIST reglist[];
readregs()3111e5ca63fSbill readregs()
3121e5ca63fSbill {
3131e5ca63fSbill 	/*get REG values from pcs*/
3141e5ca63fSbill 	REG i;
3151e5ca63fSbill 	FOR i=24; --i>=0;
3161e5ca63fSbill 	DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
3171e5ca63fSbill 		    ptrace(RUREGS, pid, reglist[i].roffs, 0);
3181e5ca63fSbill 	OD
3191e5ca63fSbill  	userpc= *(ADDR *)(((ADDR)&u)+PC);
3201e5ca63fSbill }
3211e5ca63fSbill 
3221e5ca63fSbill char
readchar()3231e5ca63fSbill readchar() {
3241e5ca63fSbill 	lastc = *argsp++;
3251e5ca63fSbill 	if (lastc == '\0') lastc = '\n';
3261e5ca63fSbill 	return(lastc);
3271e5ca63fSbill }
3281e5ca63fSbill 
3291e5ca63fSbill char
rdc()3301e5ca63fSbill rdc()
3311e5ca63fSbill {
3321e5ca63fSbill 	register char c;
3331e5ca63fSbill 
3341e5ca63fSbill 	c = *argsp++;
3351e5ca63fSbill 	return(c == '\0' ? '\n' : c);
3361e5ca63fSbill }
337