xref: /csrg-svn/old/adb/adb.vax/runpcs.c (revision 8926)
13765Sroot #
23765Sroot /*
33765Sroot  *
43765Sroot  *	UNIX debugger
53765Sroot  *
63765Sroot  */
73765Sroot 
83765Sroot #include "defs.h"
9*8926Srrh static	char sccsid[] = "@(#)runpcs.c 4.2 10/28/82";
103765Sroot 
113765Sroot extern	MAP	txtmap;
123765Sroot 
133765Sroot MSG		NOFORK;
143765Sroot MSG		ENDPCS;
153765Sroot MSG		BADWAIT;
163765Sroot 
173765Sroot CHAR		*lp;
183765Sroot ADDR		sigint;
193765Sroot ADDR		sigqit;
203765Sroot 
213765Sroot /* breakpoints */
223765Sroot BKPTR		bkpthead;
233765Sroot 
243765Sroot REGLIST		reglist[];
253765Sroot 
263765Sroot CHAR		lastc;
273765Sroot 
283765Sroot INT		fcor;
293765Sroot INT		fsym;
303765Sroot STRING		errflg;
313765Sroot INT		errno;
323765Sroot INT		signo;
333765Sroot INT		sigcode;
343765Sroot 
353765Sroot L_INT		dot;
363765Sroot STRING		symfil;
373765Sroot INT		wtflag;
383765Sroot L_INT		pid;
393765Sroot L_INT		expv;
403765Sroot INT		adrflg;
413765Sroot L_INT		loopcnt;
423765Sroot 
433765Sroot 
443765Sroot 
453765Sroot 
463765Sroot 
473765Sroot /* service routines for sub process control */
483765Sroot 
493765Sroot getsig(sig)
503765Sroot {	return(expr(0) ? expv : sig);
513765Sroot }
523765Sroot 
533765Sroot ADDR userpc = 1;
543765Sroot 
553765Sroot runpcs(runmode,execsig)
563765Sroot {
573765Sroot 	INT		rc;
583765Sroot 	REG BKPTR	bkpt;
593765Sroot 	IF adrflg THEN userpc=dot; FI
603765Sroot 	printf("%s: running\n", symfil);
613765Sroot 
623765Sroot 	WHILE --loopcnt>=0
633765Sroot 	DO
643765Sroot #ifdef DEBUG
653765Sroot 		printf("\ncontinue %x %d\n",userpc,execsig);
663765Sroot #endif
673765Sroot 		IF runmode==SINGLE
683765Sroot 		THEN delbp(); /* hardware handles single-stepping */
693765Sroot 		ELSE /* continuing from a breakpoint is hard */
703765Sroot 			IF bkpt=scanbkpt(userpc)
713765Sroot 			THEN execbkpt(bkpt,execsig); execsig=0;
723765Sroot 			FI
733765Sroot 			setbp();
743765Sroot 		FI
753765Sroot 		ptrace(runmode,pid,userpc,execsig);
763765Sroot 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
773765Sroot 
783765Sroot 		IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
793765Sroot 		THEN /* stopped by BPT instruction */
803765Sroot #ifdef DEBUG
813765Sroot 			printf("\n BPT code; '%s'%o'%o'%d",
823765Sroot 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
833765Sroot #endif
843765Sroot 			dot=bkpt->loc;
853765Sroot 			IF bkpt->flag==BKPTEXEC
863765Sroot 			ORF ((bkpt->flag=BKPTEXEC)
873765Sroot 				ANDF bkpt->comm[0]!=EOR
883765Sroot 				ANDF command(bkpt->comm,':')
893765Sroot 				ANDF --bkpt->count)
903765Sroot 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
913765Sroot 			ELSE bkpt->count=bkpt->initcnt; rc=1;
923765Sroot 			FI
933765Sroot 		ELSE execsig=signo; rc=0;
943765Sroot 		FI
953765Sroot 	OD
963765Sroot 	return(rc);
973765Sroot }
983765Sroot 
993765Sroot #define BPOUT 0
1003765Sroot #define BPIN 1
1013765Sroot INT bpstate = BPOUT;
1023765Sroot 
1033765Sroot endpcs()
1043765Sroot {
1053765Sroot 	REG BKPTR	bkptr;
1063765Sroot 	IF pid
1073765Sroot 	THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
1083765Sroot 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
1093765Sroot 	     DO IF bkptr->flag
1103765Sroot 		THEN bkptr->flag=BKPTSET;
1113765Sroot 		FI
1123765Sroot 	     OD
1133765Sroot 	FI
1143765Sroot 	bpstate=BPOUT;
1153765Sroot }
1163765Sroot 
1173765Sroot #ifdef VFORK
1183765Sroot nullsig()
1193765Sroot {
1203765Sroot 
1213765Sroot }
1223765Sroot #endif
1233765Sroot 
1243765Sroot setup()
1253765Sroot {
1263765Sroot 	close(fsym); fsym = -1;
1273765Sroot #ifndef VFORK
1283765Sroot 	IF (pid = fork()) == 0
1293765Sroot #else
1303765Sroot 	IF (pid = vfork()) == 0
1313765Sroot #endif
1323765Sroot 	THEN ptrace(SETTRC,0,0,0);
1333765Sroot #ifdef VFORK
1343765Sroot 	     signal(SIGTRAP,nullsig);
1353765Sroot #endif
1363765Sroot 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
1373765Sroot 	     doexec(); exit(0);
1383765Sroot 	ELIF pid == -1
1393765Sroot 	THEN error(NOFORK);
1403765Sroot 	ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
1413765Sroot 	     fsym=open(symfil,wtflag);
1423765Sroot 	     IF errflg
1433765Sroot 	     THEN printf("%s: cannot execute\n",symfil);
1443765Sroot 		  endpcs(); error(0);
1453765Sroot 	     FI
1463765Sroot 	FI
1473765Sroot 	bpstate=BPOUT;
1483765Sroot }
1493765Sroot 
1503765Sroot execbkpt(bkptr,execsig)
1513765Sroot BKPTR	bkptr;
1523765Sroot {
1533765Sroot #ifdef DEBUG
1543765Sroot 	printf("exbkpt: %d\n",bkptr->count);
1553765Sroot #endif
1563765Sroot 	delbp();
1573765Sroot 	ptrace(SINGLE,pid,bkptr->loc,execsig);
1583765Sroot 	bkptr->flag=BKPTSET;
1593765Sroot 	bpwait(); chkerr(); readregs();
1603765Sroot }
1613765Sroot 
1623765Sroot 
1633765Sroot doexec()
1643765Sroot {
1653765Sroot 	STRING		argl[MAXARG];
1663765Sroot 	CHAR		args[LINSIZ];
1673765Sroot 	STRING		p, *ap, filnam;
1683765Sroot 	extern STRING environ;
1693765Sroot 	ap=argl; p=args;
1703765Sroot 	*ap++=symfil;
1713765Sroot 	REP	IF rdc()==EOR THEN break; FI
1723765Sroot 		*ap = p;
173*8926Srrh 		/*
174*8926Srrh 		 * First thing is to look for direction characters
175*8926Srrh 		 * and get filename.  Do not use up the args for filenames.
176*8926Srrh 		 * Then get rid of spaces before next args.
177*8926Srrh 		 */
178*8926Srrh 		IF lastc=='<'
179*8926Srrh 		THEN	REP readchar(); PER lastc==SP ORF lastc==TB DONE
180*8926Srrh 			filnam = p;
181*8926Srrh 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>'
182*8926Srrh 				DO *p++=lastc; readchar(); OD
183*8926Srrh 			*p = 0;
184*8926Srrh 			close(0);
1853765Sroot 			IF open(filnam,0)<0
1863765Sroot 			THEN	printf("%s: cannot open\n",filnam); _exit(0);
1873765Sroot 			FI
188*8926Srrh 			p = *ap;
189*8926Srrh 		ELIF lastc=='>'
190*8926Srrh 		THEN	REP readchar(); PER lastc==SP ORF lastc==TB DONE
191*8926Srrh 			filnam = p;
192*8926Srrh 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='<'
193*8926Srrh 				DO *p++=lastc; readchar(); OD
194*8926Srrh 			*p = '\0';
195*8926Srrh 			close(1);
1963765Sroot 			IF creat(filnam,0666)<0
1973765Sroot 			THEN	printf("%s: cannot create\n",filnam); _exit(0);
1983765Sroot 			FI
199*8926Srrh 			p = *ap;
200*8926Srrh 		ELSE
201*8926Srrh 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' ANDF lastc!='<'
202*8926Srrh 				DO *p++=lastc; readchar(); OD
203*8926Srrh 			*p++ = '\0';
204*8926Srrh 	 		ap++;
2053765Sroot 		FI
206*8926Srrh 		WHILE lastc==SP ORF lastc==TB DO readchar(); OD
207*8926Srrh 
2083765Sroot 	PER lastc!=EOR DONE
2093765Sroot 	*ap++=0;
2103765Sroot 	exect(symfil, argl, environ);
2113765Sroot 	perror(symfil);
2123765Sroot }
2133765Sroot 
2143765Sroot BKPTR	scanbkpt(adr)
2153765Sroot ADDR adr;
2163765Sroot {
2173765Sroot 	REG BKPTR	bkptr;
2183765Sroot 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2193765Sroot 	DO IF bkptr->flag ANDF bkptr->loc==adr
2203765Sroot 	   THEN break;
2213765Sroot 	   FI
2223765Sroot 	OD
2233765Sroot 	return(bkptr);
2243765Sroot }
2253765Sroot 
2263765Sroot delbp()
2273765Sroot {
2283765Sroot 	REG ADDR	a;
2293765Sroot 	REG BKPTR	bkptr;
2303765Sroot 	IF bpstate!=BPOUT
2313765Sroot 	THEN
2323765Sroot 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2333765Sroot 		DO	IF bkptr->flag
2343765Sroot 			THEN a=bkptr->loc;
2353765Sroot 				IF a < txtmap.e1 THEN
2363765Sroot 				ptrace(WIUSER,pid,a,
2373765Sroot 					(bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
2383765Sroot 				ELSE
2393765Sroot 				ptrace(WDUSER,pid,a,
2403765Sroot 					(bkptr->ins&0xFF)|(ptrace(RDUSER,pid,a,0)&~0xFF));
2413765Sroot 				FI
2423765Sroot 			FI
2433765Sroot 		OD
2443765Sroot 		bpstate=BPOUT;
2453765Sroot 	FI
2463765Sroot }
2473765Sroot 
2483765Sroot setbp()
2493765Sroot {
2503765Sroot 	REG ADDR		a;
2513765Sroot 	REG BKPTR	bkptr;
2523765Sroot 
2533765Sroot 	IF bpstate!=BPIN
2543765Sroot 	THEN
2553765Sroot 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2563765Sroot 		DO IF bkptr->flag
2573765Sroot 		   THEN a = bkptr->loc;
2583765Sroot 			IF a < txtmap.e1 THEN
2593765Sroot 				bkptr->ins = ptrace(RIUSER, pid, a, 0);
2603765Sroot 				ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
2613765Sroot 			ELSE
2623765Sroot 				bkptr->ins = ptrace(RDUSER, pid, a, 0);
2633765Sroot 				ptrace(WDUSER, pid, a, BPT | (bkptr->ins&~0xFF));
2643765Sroot 			FI
2653765Sroot 			IF errno
2663765Sroot 			THEN prints("cannot set breakpoint: ");
2673765Sroot 			     psymoff(bkptr->loc,ISYM,"\n");
2683765Sroot 			FI
2693765Sroot 		   FI
2703765Sroot 		OD
2713765Sroot 		bpstate=BPIN;
2723765Sroot 	FI
2733765Sroot }
2743765Sroot 
2753765Sroot bpwait()
2763765Sroot {
2773765Sroot 	REG ADDR w;
2783765Sroot 	ADDR stat;
2793765Sroot 
2803765Sroot 	signal(SIGINT, 1);
2813765Sroot 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
2823765Sroot 	signal(SIGINT,sigint);
2833765Sroot 	IF w == -1
2843765Sroot 	THEN pid=0;
2853765Sroot 	     errflg=BADWAIT;
2863765Sroot 	ELIF (stat & 0177) != 0177
2873765Sroot 	THEN sigcode = 0;
2883765Sroot 	     IF signo = stat&0177
2893765Sroot 	     THEN sigprint();
2903765Sroot 	     FI
2913765Sroot 	     IF stat&0200
2923765Sroot 	     THEN prints(" - core dumped");
2933765Sroot 		  close(fcor);
2943765Sroot 		  setcor();
2953765Sroot 	     FI
2963765Sroot 	     pid=0;
2973765Sroot 	     errflg=ENDPCS;
2983765Sroot 	ELSE signo = stat>>8;
2993765Sroot 	     sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
3003765Sroot 	     IF signo!=SIGTRAP
3013765Sroot 	     THEN sigprint();
3023765Sroot 	     ELSE signo=0;
3033765Sroot 	     FI
3043765Sroot 	     flushbuf();
3053765Sroot 	FI
3063765Sroot }
3073765Sroot 
3083765Sroot readregs()
3093765Sroot {
3103765Sroot 	/*get REG values from pcs*/
3113765Sroot 	REG i;
3123765Sroot 	FOR i=24; --i>=0;
3133765Sroot 	DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
3143765Sroot 		    ptrace(RUREGS, pid, reglist[i].roffs, 0);
3153765Sroot 	OD
3163765Sroot  	userpc= *(ADDR *)(((ADDR)&u)+PC);
3173765Sroot }
3183765Sroot 
3193765Sroot 
320