xref: /csrg-svn/old/adb/adb.vax/runpcs.c (revision 18764)
114471Ssam #ifndef lint
2*18764Ssam static	char sccsid[] = "@(#)runpcs.c	4.6 04/25/85";
314471Ssam #endif
43765Sroot /*
53765Sroot  *
63765Sroot  *	UNIX debugger
73765Sroot  *
83765Sroot  */
93765Sroot 
103765Sroot #include "defs.h"
113765Sroot 
123765Sroot extern	MAP	txtmap;
133765Sroot 
143765Sroot MSG		NOFORK;
153765Sroot MSG		ENDPCS;
163765Sroot MSG		BADWAIT;
173765Sroot 
183765Sroot CHAR		*lp;
193765Sroot ADDR		sigint;
203765Sroot ADDR		sigqit;
213765Sroot 
223765Sroot /* breakpoints */
233765Sroot BKPTR		bkpthead;
243765Sroot 
253765Sroot REGLIST		reglist[];
263765Sroot 
273765Sroot CHAR		lastc;
283765Sroot 
293765Sroot INT		fcor;
303765Sroot INT		fsym;
313765Sroot STRING		errflg;
323765Sroot INT		errno;
333765Sroot INT		signo;
343765Sroot INT		sigcode;
353765Sroot 
363765Sroot L_INT		dot;
373765Sroot STRING		symfil;
383765Sroot INT		wtflag;
393765Sroot L_INT		pid;
403765Sroot L_INT		expv;
413765Sroot INT		adrflg;
423765Sroot L_INT		loopcnt;
433765Sroot 
443765Sroot 
453765Sroot 
463765Sroot 
473765Sroot 
483765Sroot /* service routines for sub process control */
493765Sroot 
getsig(sig)503765Sroot getsig(sig)
513765Sroot {	return(expr(0) ? expv : sig);
523765Sroot }
533765Sroot 
543765Sroot ADDR userpc = 1;
553765Sroot 
runpcs(runmode,execsig)563765Sroot runpcs(runmode,execsig)
573765Sroot {
583765Sroot 	INT		rc;
593765Sroot 	REG BKPTR	bkpt;
603765Sroot 	IF adrflg THEN userpc=dot; FI
613765Sroot 	printf("%s: running\n", symfil);
623765Sroot 
633765Sroot 	WHILE --loopcnt>=0
643765Sroot 	DO
653765Sroot #ifdef DEBUG
663765Sroot 		printf("\ncontinue %x %d\n",userpc,execsig);
673765Sroot #endif
683765Sroot 		IF runmode==SINGLE
693765Sroot 		THEN delbp(); /* hardware handles single-stepping */
703765Sroot 		ELSE /* continuing from a breakpoint is hard */
713765Sroot 			IF bkpt=scanbkpt(userpc)
723765Sroot 			THEN execbkpt(bkpt,execsig); execsig=0;
733765Sroot 			FI
743765Sroot 			setbp();
753765Sroot 		FI
763765Sroot 		ptrace(runmode,pid,userpc,execsig);
773765Sroot 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
783765Sroot 
793765Sroot 		IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
803765Sroot 		THEN /* stopped by BPT instruction */
813765Sroot #ifdef DEBUG
823765Sroot 			printf("\n BPT code; '%s'%o'%o'%d",
833765Sroot 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
843765Sroot #endif
853765Sroot 			dot=bkpt->loc;
863765Sroot 			IF bkpt->flag==BKPTEXEC
873765Sroot 			ORF ((bkpt->flag=BKPTEXEC)
883765Sroot 				ANDF bkpt->comm[0]!=EOR
893765Sroot 				ANDF command(bkpt->comm,':')
903765Sroot 				ANDF --bkpt->count)
913765Sroot 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
923765Sroot 			ELSE bkpt->count=bkpt->initcnt; rc=1;
933765Sroot 			FI
943765Sroot 		ELSE execsig=signo; rc=0;
953765Sroot 		FI
963765Sroot 	OD
973765Sroot 	return(rc);
983765Sroot }
993765Sroot 
1003765Sroot #define BPOUT 0
1013765Sroot #define BPIN 1
1023765Sroot INT bpstate = BPOUT;
1033765Sroot 
endpcs()1043765Sroot endpcs()
1053765Sroot {
1063765Sroot 	REG BKPTR	bkptr;
1073765Sroot 	IF pid
10817254Ssam 	THEN ptrace(PT_KILL,pid,0,0); pid=0; userpc=1;
1093765Sroot 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
1103765Sroot 	     DO IF bkptr->flag
1113765Sroot 		THEN bkptr->flag=BKPTSET;
1123765Sroot 		FI
1133765Sroot 	     OD
1143765Sroot 	FI
1153765Sroot 	bpstate=BPOUT;
1163765Sroot }
1173765Sroot 
1183765Sroot #ifdef VFORK
nullsig()1193765Sroot nullsig()
1203765Sroot {
1213765Sroot 
1223765Sroot }
1233765Sroot #endif
1243765Sroot 
setup()1253765Sroot setup()
1263765Sroot {
1273765Sroot 	close(fsym); fsym = -1;
1283765Sroot #ifndef VFORK
1293765Sroot 	IF (pid = fork()) == 0
1303765Sroot #else
1313765Sroot 	IF (pid = vfork()) == 0
1323765Sroot #endif
13317254Ssam 	THEN ptrace(PT_TRACE_ME,0,0,0);
1343765Sroot #ifdef VFORK
1353765Sroot 	     signal(SIGTRAP,nullsig);
1363765Sroot #endif
1373765Sroot 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
1383765Sroot 	     doexec(); exit(0);
1393765Sroot 	ELIF pid == -1
1403765Sroot 	THEN error(NOFORK);
1413765Sroot 	ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
1423765Sroot 	     fsym=open(symfil,wtflag);
1433765Sroot 	     IF errflg
1443765Sroot 	     THEN printf("%s: cannot execute\n",symfil);
1453765Sroot 		  endpcs(); error(0);
1463765Sroot 	     FI
1473765Sroot 	FI
1483765Sroot 	bpstate=BPOUT;
1493765Sroot }
1503765Sroot 
execbkpt(bkptr,execsig)1513765Sroot execbkpt(bkptr,execsig)
1523765Sroot BKPTR	bkptr;
1533765Sroot {
1543765Sroot #ifdef DEBUG
1553765Sroot 	printf("exbkpt: %d\n",bkptr->count);
1563765Sroot #endif
1573765Sroot 	delbp();
15817254Ssam 	ptrace(PT_STEP,pid,bkptr->loc,execsig);
1593765Sroot 	bkptr->flag=BKPTSET;
1603765Sroot 	bpwait(); chkerr(); readregs();
1613765Sroot }
1623765Sroot 
1633765Sroot 
doexec()1643765Sroot doexec()
1653765Sroot {
1663765Sroot 	STRING		argl[MAXARG];
1673765Sroot 	CHAR		args[LINSIZ];
1683765Sroot 	STRING		p, *ap, filnam;
1693765Sroot 	extern STRING environ;
1703765Sroot 	ap=argl; p=args;
1713765Sroot 	*ap++=symfil;
1723765Sroot 	REP	IF rdc()==EOR THEN break; FI
1733765Sroot 		*ap = p;
1748926Srrh 		/*
1758926Srrh 		 * First thing is to look for direction characters
1768926Srrh 		 * and get filename.  Do not use up the args for filenames.
1778926Srrh 		 * Then get rid of spaces before next args.
1788926Srrh 		 */
1798926Srrh 		IF lastc=='<'
1808926Srrh 		THEN	REP readchar(); PER lastc==SP ORF lastc==TB DONE
1818926Srrh 			filnam = p;
1828926Srrh 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>'
1838926Srrh 				DO *p++=lastc; readchar(); OD
1848926Srrh 			*p = 0;
1858926Srrh 			close(0);
1863765Sroot 			IF open(filnam,0)<0
1873765Sroot 			THEN	printf("%s: cannot open\n",filnam); _exit(0);
1883765Sroot 			FI
1898926Srrh 			p = *ap;
1908926Srrh 		ELIF lastc=='>'
1918926Srrh 		THEN	REP readchar(); PER lastc==SP ORF lastc==TB DONE
1928926Srrh 			filnam = p;
1938926Srrh 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='<'
1948926Srrh 				DO *p++=lastc; readchar(); OD
1958926Srrh 			*p = '\0';
1968926Srrh 			close(1);
1973765Sroot 			IF creat(filnam,0666)<0
1983765Sroot 			THEN	printf("%s: cannot create\n",filnam); _exit(0);
1993765Sroot 			FI
2008926Srrh 			p = *ap;
2018926Srrh 		ELSE
2028926Srrh 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' ANDF lastc!='<'
2038926Srrh 				DO *p++=lastc; readchar(); OD
2048926Srrh 			*p++ = '\0';
2058926Srrh 	 		ap++;
2063765Sroot 		FI
2073765Sroot 	PER lastc!=EOR DONE
2083765Sroot 	*ap++=0;
2093765Sroot 	exect(symfil, argl, environ);
2103765Sroot 	perror(symfil);
2113765Sroot }
2123765Sroot 
scanbkpt(adr)2133765Sroot BKPTR	scanbkpt(adr)
2143765Sroot ADDR adr;
2153765Sroot {
2163765Sroot 	REG BKPTR	bkptr;
2173765Sroot 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2183765Sroot 	DO IF bkptr->flag ANDF bkptr->loc==adr
2193765Sroot 	   THEN break;
2203765Sroot 	   FI
2213765Sroot 	OD
2223765Sroot 	return(bkptr);
2233765Sroot }
2243765Sroot 
delbp()2253765Sroot delbp()
2263765Sroot {
2273765Sroot 	REG ADDR	a;
2283765Sroot 	REG BKPTR	bkptr;
2293765Sroot 	IF bpstate!=BPOUT
2303765Sroot 	THEN
2313765Sroot 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2323765Sroot 		DO	IF bkptr->flag
2333765Sroot 			THEN a=bkptr->loc;
2343765Sroot 				IF a < txtmap.e1 THEN
235*18764Ssam 					ptrace(PT_WRITE_I,pid,a,bkptr->ins);
2363765Sroot 				ELSE
237*18764Ssam 					ptrace(PT_WRITE_D,pid,a,bkptr->ins);
2383765Sroot 				FI
2393765Sroot 			FI
2403765Sroot 		OD
2413765Sroot 		bpstate=BPOUT;
2423765Sroot 	FI
2433765Sroot }
2443765Sroot 
245*18764Ssam #ifdef vax
246*18764Ssam #define	SETBP(ins)	(BPT | ((ins) &~ 0xFF))
247*18764Ssam #endif
248*18764Ssam 
setbp()2493765Sroot setbp()
2503765Sroot {
2513765Sroot 	REG ADDR		a;
2523765Sroot 	REG BKPTR	bkptr;
2533765Sroot 
2543765Sroot 	IF bpstate!=BPIN
2553765Sroot 	THEN
2563765Sroot 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
2573765Sroot 		DO IF bkptr->flag
2583765Sroot 		   THEN a = bkptr->loc;
2593765Sroot 			IF a < txtmap.e1 THEN
26017254Ssam 				bkptr->ins = ptrace(PT_READ_I, pid, a, 0);
261*18764Ssam 				ptrace(PT_WRITE_I, pid, a, SETBP(bkptr->ins));
2623765Sroot 			ELSE
26317254Ssam 				bkptr->ins = ptrace(PT_READ_D, pid, a, 0);
264*18764Ssam 				ptrace(PT_WRITE_D, pid, a, SETBP(bkptr->ins));
2653765Sroot 			FI
2663765Sroot 			IF errno
2673765Sroot 			THEN prints("cannot set breakpoint: ");
2683765Sroot 			     psymoff(bkptr->loc,ISYM,"\n");
2693765Sroot 			FI
2703765Sroot 		   FI
2713765Sroot 		OD
2723765Sroot 		bpstate=BPIN;
2733765Sroot 	FI
2743765Sroot }
2753765Sroot 
bpwait()2763765Sroot bpwait()
2773765Sroot {
2783765Sroot 	REG ADDR w;
2793765Sroot 	ADDR stat;
2803765Sroot 
2813765Sroot 	signal(SIGINT, 1);
2823765Sroot 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
2833765Sroot 	signal(SIGINT,sigint);
2843765Sroot 	IF w == -1
2853765Sroot 	THEN pid=0;
2863765Sroot 	     errflg=BADWAIT;
2873765Sroot 	ELIF (stat & 0177) != 0177
2883765Sroot 	THEN sigcode = 0;
2893765Sroot 	     IF signo = stat&0177
2903765Sroot 	     THEN sigprint();
2913765Sroot 	     FI
2923765Sroot 	     IF stat&0200
2933765Sroot 	     THEN prints(" - core dumped");
2943765Sroot 		  close(fcor);
2953765Sroot 		  setcor();
2963765Sroot 	     FI
2973765Sroot 	     pid=0;
2983765Sroot 	     errflg=ENDPCS;
2993765Sroot 	ELSE signo = stat>>8;
30017254Ssam 	     sigcode = ptrace(PT_READ_U, pid, &((struct user *)0)->u_code, 0);
3013765Sroot 	     IF signo!=SIGTRAP
3023765Sroot 	     THEN sigprint();
3033765Sroot 	     ELSE signo=0;
3043765Sroot 	     FI
3053765Sroot 	     flushbuf();
3063765Sroot 	FI
3073765Sroot }
3083765Sroot 
readregs()3093765Sroot readregs()
3103765Sroot {
3113765Sroot 	/*get REG values from pcs*/
3123765Sroot 	REG i;
3133765Sroot 	FOR i=24; --i>=0;
3143765Sroot 	DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
31517254Ssam 		    ptrace(PT_READ_U, pid, reglist[i].roffs, 0);
3163765Sroot 	OD
3173765Sroot  	userpc= *(ADDR *)(((ADDR)&u)+PC);
3183765Sroot }
3193765Sroot 
3203765Sroot 
321