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