xref: /csrg-svn/old/sdb/runpcs.c (revision 7776)
1*7776Srrh static	char sccsid[] = "@(#)runpcs.c 4.2 08/17/82";
21349Sbill #
31349Sbill /*
41349Sbill  *
51349Sbill  *	UNIX debugger
61349Sbill  *
71349Sbill  */
81349Sbill 
91349Sbill #include "head.h"
101349Sbill #include <a.out.h>
111349Sbill #include <stab.h>
121349Sbill struct user u;
131349Sbill #include <stdio.h>
141349Sbill 
151349Sbill #ifndef SIGTRAP
161349Sbill #define	SIGTRAP SIGTRC
171349Sbill #endif
181349Sbill 
191349Sbill MSG		NOFORK;
201349Sbill MSG		ENDPCS;
211349Sbill MSG		BADWAIT;
221349Sbill 
231349Sbill ADDR		sigint;
241349Sbill ADDR		sigqit;
251349Sbill ADDR		userpc;
261349Sbill 
271349Sbill /* breakpoints */
281349Sbill BKPTR		bkpthead;
291349Sbill 
301349Sbill CHAR		lastc;
311349Sbill 
321349Sbill INT		fcor;
331349Sbill INT		fsym;
341349Sbill STRING		errflg;
351349Sbill int		errno;
361349Sbill INT		signo;
371349Sbill 
381349Sbill L_INT		dot;
391349Sbill STRING		symfil;
401349Sbill INT		wtflag;
411349Sbill INT		pid;
421349Sbill INT		adrflg;
431349Sbill L_INT		loopcnt;
441349Sbill 
451349Sbill 
461349Sbill 
471349Sbill 
481349Sbill 
491349Sbill 
getsig(sig)501349Sbill getsig(sig)
511349Sbill {	return(sig);
521349Sbill }
531349Sbill 
runpcs(runmode,execsig)541349Sbill runpcs(runmode,execsig)
551349Sbill {
561349Sbill 	REG BKPTR	bkpt;
571349Sbill 	IF adrflg THEN userpc=dot; FI
581349Sbill 	WHILE --loopcnt>=0
591349Sbill 	DO
601349Sbill 		if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
611349Sbill 		IF runmode==SINGLE
621349Sbill 		THEN delbp(); /* hardware handles single-stepping */
631349Sbill 		ELSE /* continuing from a breakpoint is hard */
641349Sbill 			IF bkpt=scanbkpt(userpc)
651349Sbill 			THEN execbkpt(bkpt,execsig); execsig=0;
661349Sbill 			FI
671349Sbill 			setbp();
681349Sbill 		FI
691349Sbill 		ptrace(runmode,pid,userpc,execsig);
701349Sbill 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
711349Sbill 
721349Sbill 	loop1:	IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
731349Sbill 		THEN /* stopped by BPT instruction */
741349Sbill 			if (debug) printf("\n BPT code; '%s'%o'%o'%d",
751349Sbill 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
761349Sbill 			dot=bkpt->loc;
771349Sbill 			IF bkpt->comm[0] != EOR
781349Sbill 			THEN acommand(bkpt->comm);
791349Sbill 			FI
801349Sbill 			IF bkpt->flag==BKPTEXEC
811349Sbill 			ORF ((bkpt->flag=BKPTEXEC)
821349Sbill 				ANDF bkpt->comm[0]!=EOR)
831349Sbill 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
841349Sbill 			     goto loop1;
851349Sbill  			ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
861349Sbill 			FI
871349Sbill 		ELSE execsig=signo;
881349Sbill 		     if (execsig) break;
891349Sbill 		FI
901349Sbill 	OD
911349Sbill  		if (debug) printf("Returning from runpcs\n");
921349Sbill }
931349Sbill 
941349Sbill #define BPOUT 0
951349Sbill #define BPIN 1
961349Sbill INT bpstate;
971349Sbill 
endpcs()981349Sbill endpcs()
991349Sbill {
1001349Sbill 	REG BKPTR	bkptr;
1011349Sbill  		if (debug) printf("Entering endpcs with pid=%d\n");
1021349Sbill 	IF pid
1031349Sbill 	THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
1041349Sbill 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
1051349Sbill 	     DO IF bkptr->flag
1061349Sbill 		THEN bkptr->flag=BKPTSET;
1071349Sbill 		FI
1081349Sbill 	     OD
1091349Sbill 	FI
1101349Sbill 	bpstate=BPOUT;
1111349Sbill }
1121349Sbill 
1131349Sbill #ifdef VFORK
nullsig()1141349Sbill nullsig()
1151349Sbill {
1161349Sbill 
1171349Sbill }
1181349Sbill #endif
1191349Sbill 
setup()1201349Sbill setup()
1211349Sbill {
1221349Sbill 	close(fsym); fsym = -1;
1231349Sbill #ifdef VFORK
1241349Sbill 	IF (pid = vfork()) == 0
1251349Sbill #else
1261349Sbill 	IF (pid = fork()) == 0
1271349Sbill #endif
1281349Sbill 	THEN ptrace(SETTRC,0,0,0);
1291349Sbill 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
1301349Sbill #ifdef VFORK
1311349Sbill 	     signal(SIGTRAP,nullsig);
1321349Sbill #endif
1331349Sbill  		if (debug) printf("About to doexec  pid=%d\n",pid);
1341349Sbill 	     doexec(); _exit(0);
1351349Sbill 	ELIF pid == -1
1361349Sbill 	THEN error(NOFORK);
1371349Sbill 	ELSE bpwait(); readregs();
1381349Sbill 	if (debug) printf("About to open symfil = %s\n", symfil);
1391349Sbill 	     fsym=open(symfil,wtflag);
1401349Sbill 	     IF errflg
1411349Sbill 	     THEN printf("%s: cannot execute\n",symfil);
1421349Sbill  		if (debug) printf("%d %s\n", errflg, errflg);
1431349Sbill 		  endpcs();
1441349Sbill 	     FI
1451349Sbill 	FI
1461349Sbill 	bpstate=BPOUT;
1471349Sbill }
1481349Sbill 
execbkpt(bkptr,execsig)1491349Sbill execbkpt(bkptr,execsig)
1501349Sbill BKPTR	bkptr;
1511349Sbill {
1521349Sbill 	if (debug) printf("exbkpt: %d\n",bkptr->count);
1531349Sbill 	delbp();
1541349Sbill 	ptrace(SINGLE,pid,bkptr->loc,execsig);
1551349Sbill 	bkptr->flag=BKPTSET;
1561349Sbill 	bpwait(); chkerr(); readregs();
1571349Sbill }
1581349Sbill 
1591349Sbill extern STRING environ;
1601349Sbill 
doexec()1611349Sbill doexec()
1621349Sbill {
1631349Sbill 	char *argl[MAXARG], args[LINSIZ];
1641349Sbill 	register char c, redchar, *argsp, **arglp, *filnam;
1651349Sbill 
1661349Sbill 	arglp = argl;
1671349Sbill 	argsp = args;
1681349Sbill 	*arglp++ = symfil;
1691349Sbill 	c = ' ';
1701349Sbill 
1711349Sbill 	do {
1721349Sbill 		while (eqany(c, " \t")) {
1731349Sbill 			c = rdc();
1741349Sbill 		}
1751349Sbill 		if (eqany(c, "<>")) {
1761349Sbill 			redchar = c;
1771349Sbill 			do {
1781349Sbill 				c = rdc();
1791349Sbill 			} while (eqany(c, " \t"));
1801349Sbill 			filnam = argsp;
1811349Sbill 			do {
1821349Sbill 				*argsp++ = c;
1831349Sbill 				c = rdc();
1841349Sbill 			} while (!eqany(c, " <>\t\n"));
1851349Sbill 			*argsp++ = '\0';
1861349Sbill 			if (redchar == '<') {
1871349Sbill 				close(0);
1881349Sbill 				if (open(filnam,0) < 0) {
1891349Sbill 					printf("%s: cannot open\n",filnam);
1901349Sbill 					fflush(stdout);
1911349Sbill 					_exit(0);
1921349Sbill 				}
1931349Sbill 			} else {
1941349Sbill 				close(1);
1951349Sbill 				if (creat(filnam,0666) < 0) {
1961349Sbill 					printf("%s: cannot create\n",filnam);
1971349Sbill 					fflush(stdout);
1981349Sbill 					 _exit(0);
1991349Sbill 				}
2001349Sbill 			}
2011349Sbill 		} else if (c != '\n') {
2021349Sbill 			*arglp++ = argsp;
2031349Sbill 			do {
2041349Sbill 				*argsp++ = c;
2051349Sbill 				c = rdc();
2061349Sbill 			} while(!eqany(c, " <>\t\n"));
2071349Sbill 			*argsp++ = '\0';
2081349Sbill 		}
2091349Sbill 	} while (c != '\n');
2101349Sbill 	*arglp = (char *) 0;
2111349Sbill 	if (debug) {
2121349Sbill 		char **dap;
2131349Sbill 		printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
2141349Sbill 		for (dap = argl; *dap; dap++) {
2151349Sbill 			printf("%s, ", *dap);
2161349Sbill 		}
2171349Sbill 	}
2181349Sbill 	exect(symfil, argl, environ);
2191349Sbill 	perror("Returned from exect");
2201349Sbill }
2211349Sbill 
scanbkpt(adr)2221349Sbill BKPTR	scanbkpt(adr)
2231349Sbill ADDR adr;
2241349Sbill {
2251349Sbill 	REG BKPTR	bkptr;
2261349Sbill 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2271349Sbill 	DO IF bkptr->flag ANDF bkptr->loc==adr
2281349Sbill 	   THEN break;
2291349Sbill 	   FI
2301349Sbill 	OD
2311349Sbill 	return(bkptr);
2321349Sbill }
2331349Sbill 
delbp()2341349Sbill delbp()
2351349Sbill {
2361349Sbill 	REG ADDR	a;
2371349Sbill 	REG BKPTR	bkptr;
2381349Sbill 	IF bpstate!=BPOUT
2391349Sbill 	THEN
2401349Sbill 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2411349Sbill 		DO	IF bkptr->flag
2421349Sbill 			THEN a=bkptr->loc;
2431349Sbill 				ptrace(WIUSER,pid,a,
2441349Sbill 					(bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
2451349Sbill 			FI
2461349Sbill 		OD
2471349Sbill 		bpstate=BPOUT;
2481349Sbill 	FI
2491349Sbill }
2501349Sbill 
setbp()2511349Sbill setbp()
2521349Sbill {
2531349Sbill 	REG ADDR		a;
2541349Sbill 	REG BKPTR	bkptr;
2551349Sbill 
2561349Sbill 	IF bpstate!=BPIN
2571349Sbill 	THEN
2581349Sbill 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2591349Sbill 		DO IF bkptr->flag
2601349Sbill 		   THEN a = bkptr->loc;
2611349Sbill 			bkptr->ins = ptrace(RIUSER, pid, a, 0);
2621349Sbill 			ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
2631349Sbill 			IF errno
2641349Sbill 			THEN error("cannot set breakpoint: ");
2651349Sbill 			     printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
2661349Sbill 				adrtolineno(dot), dot);
2671349Sbill 			FI
2681349Sbill 		   FI
2691349Sbill 		OD
2701349Sbill 		bpstate=BPIN;
2711349Sbill 	FI
2721349Sbill }
2731349Sbill 
bpwait()2741349Sbill bpwait()
2751349Sbill {
2761349Sbill 	REG ADDR w;
2771349Sbill 	ADDR stat;
2781349Sbill 
2791349Sbill 	signal(SIGINT, 1);
2801349Sbill 	if (debug) printf("Waiting for pid %d\n",pid);
2811349Sbill 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
2821349Sbill 	if (debug) printf("Ending wait\n");
2831349Sbill 	if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
2841349Sbill 	signal(SIGINT,sigint);
2851349Sbill 	IF w == -1
2861349Sbill 	THEN pid=0;
2871349Sbill 	     errflg=BADWAIT;
2881349Sbill 	ELIF (stat & 0177) != 0177
2891349Sbill 	THEN IF signo = stat&0177
2901349Sbill 	     THEN sigprint();
2911349Sbill 	     FI
2921349Sbill 	     IF stat&0200
2931349Sbill 	     THEN error(" - core dumped");
2941349Sbill 		  close(fcor);
2951349Sbill 		  setcor();
2961349Sbill 	     FI
2971349Sbill 	     pid=0;
2981349Sbill 	     errflg=ENDPCS;
2991349Sbill 	ELSE signo = stat>>8;
3001349Sbill     	     if (debug) printf("PC = %d, dbsubn = %d\n",
3011349Sbill 		ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
3021349Sbill 	     IF signo!=SIGTRAP ANDF
3031349Sbill 		ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
3041349Sbill 	     THEN sigprint();
3051349Sbill 	     ELSE signo=0;
3061349Sbill 	     FI
3071349Sbill 	FI
3081349Sbill }
3091349Sbill 
3101349Sbill REGLIST reglist[];
readregs()3111349Sbill readregs()
3121349Sbill {
3131349Sbill 	/*get REG values from pcs*/
3141349Sbill 	REG i;
3151349Sbill 	FOR i=24; --i>=0;
3161349Sbill 	DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
3171349Sbill 		    ptrace(RUREGS, pid, reglist[i].roffs, 0);
3181349Sbill 	OD
3191349Sbill  	userpc= *(ADDR *)(((ADDR)&u)+PC);
3201349Sbill }
3211349Sbill 
3221349Sbill char
readchar()3231349Sbill readchar() {
3241349Sbill 	lastc = *argsp++;
3251349Sbill 	if (lastc == '\0') lastc = '\n';
3261349Sbill 	return(lastc);
3271349Sbill }
3281349Sbill 
3291349Sbill char
rdc()3301349Sbill rdc()
3311349Sbill {
3321349Sbill 	register char c;
3331349Sbill 
3341349Sbill 	c = *argsp++;
3351349Sbill 	return(c == '\0' ? '\n' : c);
3361349Sbill }
337