xref: /csrg-svn/old/sdb/runpcs.c (revision 1349)
1*1349Sbill static	char sccsid[] = "@(#)runpcs.c 4.1 10/09/80";
2*1349Sbill #
3*1349Sbill /*
4*1349Sbill  *
5*1349Sbill  *	UNIX debugger
6*1349Sbill  *
7*1349Sbill  */
8*1349Sbill 
9*1349Sbill #include "head.h"
10*1349Sbill #include <a.out.h>
11*1349Sbill #include <stab.h>
12*1349Sbill struct user u;
13*1349Sbill #include <stdio.h>
14*1349Sbill 
15*1349Sbill #ifndef SIGTRAP
16*1349Sbill #define	SIGTRAP SIGTRC
17*1349Sbill #endif
18*1349Sbill 
19*1349Sbill MSG		NOFORK;
20*1349Sbill MSG		ENDPCS;
21*1349Sbill MSG		BADWAIT;
22*1349Sbill 
23*1349Sbill ADDR		sigint;
24*1349Sbill ADDR		sigqit;
25*1349Sbill ADDR		userpc;
26*1349Sbill 
27*1349Sbill /* breakpoints */
28*1349Sbill BKPTR		bkpthead;
29*1349Sbill 
30*1349Sbill CHAR		lastc;
31*1349Sbill 
32*1349Sbill INT		fcor;
33*1349Sbill INT		fsym;
34*1349Sbill STRING		errflg;
35*1349Sbill int		errno;
36*1349Sbill INT		signo;
37*1349Sbill 
38*1349Sbill L_INT		dot;
39*1349Sbill STRING		symfil;
40*1349Sbill INT		wtflag;
41*1349Sbill INT		pid;
42*1349Sbill INT		adrflg;
43*1349Sbill L_INT		loopcnt;
44*1349Sbill 
45*1349Sbill 
46*1349Sbill 
47*1349Sbill 
48*1349Sbill 
49*1349Sbill 
50*1349Sbill getsig(sig)
51*1349Sbill {	return(sig);
52*1349Sbill }
53*1349Sbill 
54*1349Sbill runpcs(runmode,execsig)
55*1349Sbill {
56*1349Sbill 	REG BKPTR	bkpt;
57*1349Sbill 	IF adrflg THEN userpc=dot; FI
58*1349Sbill 	WHILE --loopcnt>=0
59*1349Sbill 	DO
60*1349Sbill 		if (debug) printf("\ncontinue %x %d\n",userpc,execsig);
61*1349Sbill 		IF runmode==SINGLE
62*1349Sbill 		THEN delbp(); /* hardware handles single-stepping */
63*1349Sbill 		ELSE /* continuing from a breakpoint is hard */
64*1349Sbill 			IF bkpt=scanbkpt(userpc)
65*1349Sbill 			THEN execbkpt(bkpt,execsig); execsig=0;
66*1349Sbill 			FI
67*1349Sbill 			setbp();
68*1349Sbill 		FI
69*1349Sbill 		ptrace(runmode,pid,userpc,execsig);
70*1349Sbill 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
71*1349Sbill 
72*1349Sbill 	loop1:	IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
73*1349Sbill 		THEN /* stopped by BPT instruction */
74*1349Sbill 			if (debug) printf("\n BPT code; '%s'%o'%o'%d",
75*1349Sbill 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
76*1349Sbill 			dot=bkpt->loc;
77*1349Sbill 			IF bkpt->comm[0] != EOR
78*1349Sbill 			THEN acommand(bkpt->comm);
79*1349Sbill 			FI
80*1349Sbill 			IF bkpt->flag==BKPTEXEC
81*1349Sbill 			ORF ((bkpt->flag=BKPTEXEC)
82*1349Sbill 				ANDF bkpt->comm[0]!=EOR)
83*1349Sbill 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
84*1349Sbill 			     goto loop1;
85*1349Sbill  			ELSE bkpt->flag=BKPTSET; bkpt->count=bkpt->initcnt;
86*1349Sbill 			FI
87*1349Sbill 		ELSE execsig=signo;
88*1349Sbill 		     if (execsig) break;
89*1349Sbill 		FI
90*1349Sbill 	OD
91*1349Sbill  		if (debug) printf("Returning from runpcs\n");
92*1349Sbill }
93*1349Sbill 
94*1349Sbill #define BPOUT 0
95*1349Sbill #define BPIN 1
96*1349Sbill INT bpstate;
97*1349Sbill 
98*1349Sbill endpcs()
99*1349Sbill {
100*1349Sbill 	REG BKPTR	bkptr;
101*1349Sbill  		if (debug) printf("Entering endpcs with pid=%d\n");
102*1349Sbill 	IF pid
103*1349Sbill 	THEN ptrace(EXIT,pid,0,0); pid=0; userpc=1;
104*1349Sbill 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
105*1349Sbill 	     DO IF bkptr->flag
106*1349Sbill 		THEN bkptr->flag=BKPTSET;
107*1349Sbill 		FI
108*1349Sbill 	     OD
109*1349Sbill 	FI
110*1349Sbill 	bpstate=BPOUT;
111*1349Sbill }
112*1349Sbill 
113*1349Sbill #ifdef VFORK
114*1349Sbill nullsig()
115*1349Sbill {
116*1349Sbill 
117*1349Sbill }
118*1349Sbill #endif
119*1349Sbill 
120*1349Sbill setup()
121*1349Sbill {
122*1349Sbill 	close(fsym); fsym = -1;
123*1349Sbill #ifdef VFORK
124*1349Sbill 	IF (pid = vfork()) == 0
125*1349Sbill #else
126*1349Sbill 	IF (pid = fork()) == 0
127*1349Sbill #endif
128*1349Sbill 	THEN ptrace(SETTRC,0,0,0);
129*1349Sbill 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
130*1349Sbill #ifdef VFORK
131*1349Sbill 	     signal(SIGTRAP,nullsig);
132*1349Sbill #endif
133*1349Sbill  		if (debug) printf("About to doexec  pid=%d\n",pid);
134*1349Sbill 	     doexec(); _exit(0);
135*1349Sbill 	ELIF pid == -1
136*1349Sbill 	THEN error(NOFORK);
137*1349Sbill 	ELSE bpwait(); readregs();
138*1349Sbill 	if (debug) printf("About to open symfil = %s\n", symfil);
139*1349Sbill 	     fsym=open(symfil,wtflag);
140*1349Sbill 	     IF errflg
141*1349Sbill 	     THEN printf("%s: cannot execute\n",symfil);
142*1349Sbill  		if (debug) printf("%d %s\n", errflg, errflg);
143*1349Sbill 		  endpcs();
144*1349Sbill 	     FI
145*1349Sbill 	FI
146*1349Sbill 	bpstate=BPOUT;
147*1349Sbill }
148*1349Sbill 
149*1349Sbill execbkpt(bkptr,execsig)
150*1349Sbill BKPTR	bkptr;
151*1349Sbill {
152*1349Sbill 	if (debug) printf("exbkpt: %d\n",bkptr->count);
153*1349Sbill 	delbp();
154*1349Sbill 	ptrace(SINGLE,pid,bkptr->loc,execsig);
155*1349Sbill 	bkptr->flag=BKPTSET;
156*1349Sbill 	bpwait(); chkerr(); readregs();
157*1349Sbill }
158*1349Sbill 
159*1349Sbill extern STRING environ;
160*1349Sbill 
161*1349Sbill doexec()
162*1349Sbill {
163*1349Sbill 	char *argl[MAXARG], args[LINSIZ];
164*1349Sbill 	register char c, redchar, *argsp, **arglp, *filnam;
165*1349Sbill 
166*1349Sbill 	arglp = argl;
167*1349Sbill 	argsp = args;
168*1349Sbill 	*arglp++ = symfil;
169*1349Sbill 	c = ' ';
170*1349Sbill 
171*1349Sbill 	do {
172*1349Sbill 		while (eqany(c, " \t")) {
173*1349Sbill 			c = rdc();
174*1349Sbill 		}
175*1349Sbill 		if (eqany(c, "<>")) {
176*1349Sbill 			redchar = c;
177*1349Sbill 			do {
178*1349Sbill 				c = rdc();
179*1349Sbill 			} while (eqany(c, " \t"));
180*1349Sbill 			filnam = argsp;
181*1349Sbill 			do {
182*1349Sbill 				*argsp++ = c;
183*1349Sbill 				c = rdc();
184*1349Sbill 			} while (!eqany(c, " <>\t\n"));
185*1349Sbill 			*argsp++ = '\0';
186*1349Sbill 			if (redchar == '<') {
187*1349Sbill 				close(0);
188*1349Sbill 				if (open(filnam,0) < 0) {
189*1349Sbill 					printf("%s: cannot open\n",filnam);
190*1349Sbill 					fflush(stdout);
191*1349Sbill 					_exit(0);
192*1349Sbill 				}
193*1349Sbill 			} else {
194*1349Sbill 				close(1);
195*1349Sbill 				if (creat(filnam,0666) < 0) {
196*1349Sbill 					printf("%s: cannot create\n",filnam);
197*1349Sbill 					fflush(stdout);
198*1349Sbill 					 _exit(0);
199*1349Sbill 				}
200*1349Sbill 			}
201*1349Sbill 		} else if (c != '\n') {
202*1349Sbill 			*arglp++ = argsp;
203*1349Sbill 			do {
204*1349Sbill 				*argsp++ = c;
205*1349Sbill 				c = rdc();
206*1349Sbill 			} while(!eqany(c, " <>\t\n"));
207*1349Sbill 			*argsp++ = '\0';
208*1349Sbill 		}
209*1349Sbill 	} while (c != '\n');
210*1349Sbill 	*arglp = (char *) 0;
211*1349Sbill 	if (debug) {
212*1349Sbill 		char **dap;
213*1349Sbill 		printf("About to exect(%s, %d, %d)\n",symfil,argl,environ);
214*1349Sbill 		for (dap = argl; *dap; dap++) {
215*1349Sbill 			printf("%s, ", *dap);
216*1349Sbill 		}
217*1349Sbill 	}
218*1349Sbill 	exect(symfil, argl, environ);
219*1349Sbill 	perror("Returned from exect");
220*1349Sbill }
221*1349Sbill 
222*1349Sbill BKPTR	scanbkpt(adr)
223*1349Sbill ADDR adr;
224*1349Sbill {
225*1349Sbill 	REG BKPTR	bkptr;
226*1349Sbill 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
227*1349Sbill 	DO IF bkptr->flag ANDF bkptr->loc==adr
228*1349Sbill 	   THEN break;
229*1349Sbill 	   FI
230*1349Sbill 	OD
231*1349Sbill 	return(bkptr);
232*1349Sbill }
233*1349Sbill 
234*1349Sbill delbp()
235*1349Sbill {
236*1349Sbill 	REG ADDR	a;
237*1349Sbill 	REG BKPTR	bkptr;
238*1349Sbill 	IF bpstate!=BPOUT
239*1349Sbill 	THEN
240*1349Sbill 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
241*1349Sbill 		DO	IF bkptr->flag
242*1349Sbill 			THEN a=bkptr->loc;
243*1349Sbill 				ptrace(WIUSER,pid,a,
244*1349Sbill 					(bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
245*1349Sbill 			FI
246*1349Sbill 		OD
247*1349Sbill 		bpstate=BPOUT;
248*1349Sbill 	FI
249*1349Sbill }
250*1349Sbill 
251*1349Sbill setbp()
252*1349Sbill {
253*1349Sbill 	REG ADDR		a;
254*1349Sbill 	REG BKPTR	bkptr;
255*1349Sbill 
256*1349Sbill 	IF bpstate!=BPIN
257*1349Sbill 	THEN
258*1349Sbill 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
259*1349Sbill 		DO IF bkptr->flag
260*1349Sbill 		   THEN a = bkptr->loc;
261*1349Sbill 			bkptr->ins = ptrace(RIUSER, pid, a, 0);
262*1349Sbill 			ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
263*1349Sbill 			IF errno
264*1349Sbill 			THEN error("cannot set breakpoint: ");
265*1349Sbill 			     printf("%s:%d @ %d\n", adrtoprocp(dot)->pname,
266*1349Sbill 				adrtolineno(dot), dot);
267*1349Sbill 			FI
268*1349Sbill 		   FI
269*1349Sbill 		OD
270*1349Sbill 		bpstate=BPIN;
271*1349Sbill 	FI
272*1349Sbill }
273*1349Sbill 
274*1349Sbill bpwait()
275*1349Sbill {
276*1349Sbill 	REG ADDR w;
277*1349Sbill 	ADDR stat;
278*1349Sbill 
279*1349Sbill 	signal(SIGINT, 1);
280*1349Sbill 	if (debug) printf("Waiting for pid %d\n",pid);
281*1349Sbill 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
282*1349Sbill 	if (debug) printf("Ending wait\n");
283*1349Sbill 	if (debug) printf("w = %d; pid = %d; stat = %o;\n", w,pid,stat);
284*1349Sbill 	signal(SIGINT,sigint);
285*1349Sbill 	IF w == -1
286*1349Sbill 	THEN pid=0;
287*1349Sbill 	     errflg=BADWAIT;
288*1349Sbill 	ELIF (stat & 0177) != 0177
289*1349Sbill 	THEN IF signo = stat&0177
290*1349Sbill 	     THEN sigprint();
291*1349Sbill 	     FI
292*1349Sbill 	     IF stat&0200
293*1349Sbill 	     THEN error(" - core dumped");
294*1349Sbill 		  close(fcor);
295*1349Sbill 		  setcor();
296*1349Sbill 	     FI
297*1349Sbill 	     pid=0;
298*1349Sbill 	     errflg=ENDPCS;
299*1349Sbill 	ELSE signo = stat>>8;
300*1349Sbill     	     if (debug) printf("PC = %d, dbsubn = %d\n",
301*1349Sbill 		ptrace(RUREGS, pid, PC, 0), extaddr("_dbsubn"));
302*1349Sbill 	     IF signo!=SIGTRAP ANDF
303*1349Sbill 		ptrace(RUREGS, pid, PC, 0) != extaddr("_dbsubn")
304*1349Sbill 	     THEN sigprint();
305*1349Sbill 	     ELSE signo=0;
306*1349Sbill 	     FI
307*1349Sbill 	FI
308*1349Sbill }
309*1349Sbill 
310*1349Sbill REGLIST reglist[];
311*1349Sbill readregs()
312*1349Sbill {
313*1349Sbill 	/*get REG values from pcs*/
314*1349Sbill 	REG i;
315*1349Sbill 	FOR i=24; --i>=0;
316*1349Sbill 	DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
317*1349Sbill 		    ptrace(RUREGS, pid, reglist[i].roffs, 0);
318*1349Sbill 	OD
319*1349Sbill  	userpc= *(ADDR *)(((ADDR)&u)+PC);
320*1349Sbill }
321*1349Sbill 
322*1349Sbill char
323*1349Sbill readchar() {
324*1349Sbill 	lastc = *argsp++;
325*1349Sbill 	if (lastc == '\0') lastc = '\n';
326*1349Sbill 	return(lastc);
327*1349Sbill }
328*1349Sbill 
329*1349Sbill char
330*1349Sbill rdc()
331*1349Sbill {
332*1349Sbill 	register char c;
333*1349Sbill 
334*1349Sbill 	c = *argsp++;
335*1349Sbill 	return(c == '\0' ? '\n' : c);
336*1349Sbill }
337