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