xref: /csrg-svn/old/adb/adb.tahoe/runpcs.c (revision 26423)
1*26423Ssam #ifndef lint
2*26423Ssam static	char sccsid[] = "@(#)runpcs.c	1.1 (Berkeley) 02/25/86";
3*26423Ssam #endif
4*26423Ssam /*
5*26423Ssam  *
6*26423Ssam  *	UNIX debugger
7*26423Ssam  *
8*26423Ssam  */
9*26423Ssam 
10*26423Ssam #include "defs.h"
11*26423Ssam 
12*26423Ssam extern	MAP	txtmap;
13*26423Ssam 
14*26423Ssam MSG		NOFORK;
15*26423Ssam MSG		ENDPCS;
16*26423Ssam MSG		BADWAIT;
17*26423Ssam 
18*26423Ssam CHAR		*lp;
19*26423Ssam SIG		sigint;
20*26423Ssam SIG		sigqit;
21*26423Ssam 
22*26423Ssam /* breakpoints */
23*26423Ssam BKPTR		bkpthead;
24*26423Ssam 
25*26423Ssam REGLIST		reglist[];
26*26423Ssam 
27*26423Ssam CHAR		lastc;
28*26423Ssam 
29*26423Ssam INT		fcor;
30*26423Ssam INT		fsym;
31*26423Ssam STRING		errflg;
32*26423Ssam INT		errno;
33*26423Ssam INT		signo;
34*26423Ssam INT		sigcode;
35*26423Ssam 
36*26423Ssam L_INT		dot;
37*26423Ssam STRING		symfil;
38*26423Ssam INT		wtflag;
39*26423Ssam L_INT		pid;
40*26423Ssam L_INT		expv;
41*26423Ssam INT		adrflg;
42*26423Ssam L_INT		loopcnt;
43*26423Ssam 
44*26423Ssam 
45*26423Ssam 
46*26423Ssam 
47*26423Ssam 
48*26423Ssam /* service routines for sub process control */
49*26423Ssam 
getsig(sig)50*26423Ssam getsig(sig)
51*26423Ssam {	return(expr(0) ? expv : sig);
52*26423Ssam }
53*26423Ssam 
54*26423Ssam ADDR userpc = 1;
55*26423Ssam 
runpcs(runmode,execsig)56*26423Ssam runpcs(runmode,execsig)
57*26423Ssam {
58*26423Ssam 	REG		rc;
59*26423Ssam 	REG BKPTR	bkpt;
60*26423Ssam 	IF adrflg THEN userpc=dot; FI
61*26423Ssam 	printf("%s: running\n", symfil);
62*26423Ssam 
63*26423Ssam 	WHILE --loopcnt>=0
64*26423Ssam 	DO
65*26423Ssam #ifdef DEBUG
66*26423Ssam 		printf("\ncontinue %X %D loopcnt=%D\n",userpc,execsig, loopcnt);
67*26423Ssam #endif
68*26423Ssam 		IF runmode==SINGLE
69*26423Ssam 		THEN delbp(); /* hardware handles single-stepping */
70*26423Ssam 		ELSE /* continuing from a breakpoint is hard */
71*26423Ssam 			IF bkpt=scanbkpt(userpc)
72*26423Ssam 			THEN execbkpt(bkpt,execsig); execsig=0;
73*26423Ssam 			FI
74*26423Ssam 			setbp();
75*26423Ssam 		FI
76*26423Ssam 		ptrace(runmode,pid,userpc,execsig);
77*26423Ssam 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
78*26423Ssam 
79*26423Ssam 		IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
80*26423Ssam 		THEN /* stopped by BPT instruction */
81*26423Ssam #ifdef DEBUG
82*26423Ssam 			printf("\n BPT code; '%s'%o'%d",
83*26423Ssam 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
84*26423Ssam #endif
85*26423Ssam 			dot=bkpt->loc;
86*26423Ssam 			IF bkpt->flag==BKPTEXEC
87*26423Ssam 			ORF ((bkpt->flag=BKPTEXEC)
88*26423Ssam 				ANDF bkpt->comm[0]!=EOR
89*26423Ssam 				ANDF command(bkpt->comm,':')
90*26423Ssam 				ANDF --bkpt->count)
91*26423Ssam 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
92*26423Ssam 			ELSE bkpt->count=bkpt->initcnt; rc=1;
93*26423Ssam 			FI
94*26423Ssam 		ELSE execsig=signo; rc=0;
95*26423Ssam 		FI
96*26423Ssam 	OD
97*26423Ssam 	return(rc);
98*26423Ssam }
99*26423Ssam 
100*26423Ssam #define BPOUT 0
101*26423Ssam #define BPIN 1
102*26423Ssam INT bpstate = BPOUT;
103*26423Ssam 
endpcs()104*26423Ssam endpcs()
105*26423Ssam {
106*26423Ssam 	REG BKPTR	bkptr;
107*26423Ssam 	IF pid
108*26423Ssam 	THEN ptrace(EXIT,pid); pid=0; userpc=1;
109*26423Ssam 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
110*26423Ssam 	     DO IF bkptr->flag
111*26423Ssam 		THEN bkptr->flag=BKPTSET;
112*26423Ssam 		FI
113*26423Ssam 	     OD
114*26423Ssam 	FI
115*26423Ssam 	bpstate=BPOUT;
116*26423Ssam }
117*26423Ssam 
118*26423Ssam #ifdef VFORK
nullsig()119*26423Ssam nullsig()
120*26423Ssam {
121*26423Ssam 
122*26423Ssam }
123*26423Ssam #endif
124*26423Ssam 
setup()125*26423Ssam setup()
126*26423Ssam {
127*26423Ssam 	close(fsym); fsym = -1;
128*26423Ssam #ifndef VFORK
129*26423Ssam 	IF (pid = fork()) == 0
130*26423Ssam #else
131*26423Ssam 	IF (pid = vfork()) == 0
132*26423Ssam #endif
133*26423Ssam 	THEN ptrace(SETTRC);
134*26423Ssam #ifdef VFORK
135*26423Ssam 	     signal(SIGTRAP,nullsig);
136*26423Ssam #endif
137*26423Ssam 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
138*26423Ssam 	     doexec(); exit(0);
139*26423Ssam 	ELIF pid == -1
140*26423Ssam 	THEN error(NOFORK);
141*26423Ssam 	ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
142*26423Ssam 	     fsym=open(symfil,wtflag);
143*26423Ssam 	     IF errflg
144*26423Ssam 	     THEN printf("%s: cannot execute\n",symfil);
145*26423Ssam 		  endpcs(); error(0);
146*26423Ssam 	     FI
147*26423Ssam 	FI
148*26423Ssam 	bpstate=BPOUT;
149*26423Ssam }
150*26423Ssam 
execbkpt(bkptr,execsig)151*26423Ssam execbkpt(bkptr,execsig)
152*26423Ssam BKPTR	bkptr;
153*26423Ssam {
154*26423Ssam #ifdef DEBUG
155*26423Ssam 	printf("exbkpt: %d\n",bkptr->count);
156*26423Ssam #endif
157*26423Ssam 	delbp();
158*26423Ssam 	ptrace(SINGLE,pid,bkptr->loc,execsig);
159*26423Ssam 	bkptr->flag=BKPTSET;
160*26423Ssam 	bpwait(); chkerr(); readregs();
161*26423Ssam }
162*26423Ssam 
163*26423Ssam 
doexec()164*26423Ssam doexec()
165*26423Ssam {
166*26423Ssam 	STRING		argl[MAXARG];
167*26423Ssam 	CHAR		args[LINSIZ];
168*26423Ssam 	REG	STRING	p, *ap, filnam;
169*26423Ssam 	extern STRING environ;
170*26423Ssam 
171*26423Ssam 	ap=argl; p=args;
172*26423Ssam 	*ap++=symfil;
173*26423Ssam 	REP	IF rdc()==EOR THEN break; FI
174*26423Ssam 		*ap = p;
175*26423Ssam 		WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD
176*26423Ssam 		*p++=0; filnam = *ap+1;
177*26423Ssam 		IF **ap=='<'
178*26423Ssam 		THEN	close(0);
179*26423Ssam 			IF open(filnam,0)<0
180*26423Ssam 			THEN	printf("%s: cannot open\n",filnam); _exit(0);
181*26423Ssam 			FI
182*26423Ssam 		ELIF **ap=='>'
183*26423Ssam 		THEN	close(1);
184*26423Ssam 			IF creat(filnam,0666)<0
185*26423Ssam 			THEN	printf("%s: cannot create\n",filnam); _exit(0);
186*26423Ssam 			FI
187*26423Ssam 		ELSE	ap++;
188*26423Ssam 		FI
189*26423Ssam 	PER lastc!=EOR DONE
190*26423Ssam 	*ap++=0;
191*26423Ssam 	execve(symfil, argl, environ);
192*26423Ssam 	perror(symfil);
193*26423Ssam }
194*26423Ssam 
scanbkpt(adr)195*26423Ssam BKPTR	scanbkpt(adr)
196*26423Ssam ADDR adr;
197*26423Ssam {
198*26423Ssam 	REG BKPTR	bkptr;
199*26423Ssam 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
200*26423Ssam 	DO IF bkptr->flag ANDF bkptr->loc==adr
201*26423Ssam 	   THEN break;
202*26423Ssam 	   FI
203*26423Ssam 	OD
204*26423Ssam 	return(bkptr);
205*26423Ssam }
206*26423Ssam 
delbp()207*26423Ssam delbp()
208*26423Ssam {
209*26423Ssam 	REG ADDR	a;
210*26423Ssam 	REG BKPTR	bkptr;
211*26423Ssam 	IF bpstate!=BPOUT
212*26423Ssam 	THEN
213*26423Ssam 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
214*26423Ssam 		DO	IF bkptr->flag
215*26423Ssam 			THEN a=bkptr->loc;
216*26423Ssam 				IF a < txtmap.e1 THEN
217*26423Ssam 				ptrace(WIUSER,pid,a,bkptr->ins);
218*26423Ssam 				ELSE
219*26423Ssam 				ptrace(WDUSER,pid,a,bkptr->ins);
220*26423Ssam 				FI
221*26423Ssam 			FI
222*26423Ssam 		OD
223*26423Ssam 		bpstate=BPOUT;
224*26423Ssam 	FI
225*26423Ssam }
226*26423Ssam 
227*26423Ssam #if defined(vax)
228*26423Ssam #define	SETBP(ins)	(BPT | ((ins) &~ 0xff))
229*26423Ssam #else
230*26423Ssam #define	SETBP(ins)	((BPT<<24) | ((ins) & 0xffffff))
231*26423Ssam #endif
232*26423Ssam 
setbp()233*26423Ssam setbp()
234*26423Ssam {
235*26423Ssam 	REG ADDR	a;
236*26423Ssam 	REG BKPTR	bkptr;
237*26423Ssam 
238*26423Ssam 	IF bpstate!=BPIN
239*26423Ssam 	THEN
240*26423Ssam 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
241*26423Ssam 		DO IF bkptr->flag
242*26423Ssam 		   THEN a = bkptr->loc;
243*26423Ssam 			IF a < txtmap.e1 THEN
244*26423Ssam 				bkptr->ins = ptrace(RIUSER, pid, a);
245*26423Ssam 				ptrace(WIUSER, pid, a, SETBP(bkptr->ins));
246*26423Ssam 			ELSE
247*26423Ssam 				bkptr->ins = ptrace(RDUSER, pid, a);
248*26423Ssam 				ptrace(WDUSER, pid, a, SETBP(bkptr->ins));
249*26423Ssam 			FI
250*26423Ssam 			IF errno
251*26423Ssam 			THEN printf("cannot set breakpoint: ");
252*26423Ssam 			     psymoff(bkptr->loc,ISYM,"\n");
253*26423Ssam 			FI
254*26423Ssam 		   FI
255*26423Ssam 		OD
256*26423Ssam 		bpstate=BPIN;
257*26423Ssam 	FI
258*26423Ssam }
259*26423Ssam 
bpwait()260*26423Ssam bpwait()
261*26423Ssam {
262*26423Ssam 	REG w;
263*26423Ssam 	ADDR stat;
264*26423Ssam 
265*26423Ssam 	signal(SIGINT, 1);
266*26423Ssam 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
267*26423Ssam 	signal(SIGINT,sigint);
268*26423Ssam 	IF w == -1
269*26423Ssam 	THEN pid=0;
270*26423Ssam 	     errflg=BADWAIT;
271*26423Ssam 	ELIF (stat & 0177) != 0177
272*26423Ssam 	THEN sigcode = 0;
273*26423Ssam 	     IF signo = stat&0177
274*26423Ssam 	     THEN sigprint();
275*26423Ssam 	     FI
276*26423Ssam 	     IF stat&0200
277*26423Ssam 	     THEN printf(" - core dumped");
278*26423Ssam 		  close(fcor);
279*26423Ssam 		  setcor();
280*26423Ssam 	     FI
281*26423Ssam 	     pid=0;
282*26423Ssam 	     errflg=ENDPCS;
283*26423Ssam 	ELSE signo = stat>>8;
284*26423Ssam 	     sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
285*26423Ssam 	     IF signo!=SIGTRAP
286*26423Ssam 	     THEN sigprint();
287*26423Ssam 	     ELSE signo=0;
288*26423Ssam 	     FI
289*26423Ssam 	     flushbuf();
290*26423Ssam 	FI
291*26423Ssam }
292*26423Ssam 
readregs()293*26423Ssam readregs()
294*26423Ssam {
295*26423Ssam 	/*get REG values from pcs*/
296*26423Ssam 	REG REGPTR	p;
297*26423Ssam 
298*26423Ssam 	FOR p=reglist; p->rname; p++
299*26423Ssam 	DO *(ADDR *)(((ADDR)&u)+p->roffs) =
300*26423Ssam 		    ptrace(RUREGS, pid, p->roffs, 0);
301*26423Ssam 	OD
302*26423Ssam  	userpc= *(ADDR *)(((ADDR)&u)+PC);
303*26423Ssam }
304