xref: /original-bsd/old/adb/adb.vax/runpcs.c (revision 6c57d260)
1 #
2 /*
3  *
4  *	UNIX debugger
5  *
6  */
7 
8 #include "defs.h"
9 static	char sccsid[] = "@(#)runpcs.c 4.1 05/14/81";
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 		WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD
174 		*p++=0; filnam = *ap+1;
175 		IF **ap=='<'
176 		THEN	close(0);
177 			IF open(filnam,0)<0
178 			THEN	printf("%s: cannot open\n",filnam); _exit(0);
179 			FI
180 		ELIF **ap=='>'
181 		THEN	close(1);
182 			IF creat(filnam,0666)<0
183 			THEN	printf("%s: cannot create\n",filnam); _exit(0);
184 			FI
185 		ELSE	ap++;
186 		FI
187 	PER lastc!=EOR DONE
188 	*ap++=0;
189 	exect(symfil, argl, environ);
190 	perror(symfil);
191 }
192 
193 BKPTR	scanbkpt(adr)
194 ADDR adr;
195 {
196 	REG BKPTR	bkptr;
197 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
198 	DO IF bkptr->flag ANDF bkptr->loc==adr
199 	   THEN break;
200 	   FI
201 	OD
202 	return(bkptr);
203 }
204 
205 delbp()
206 {
207 	REG ADDR	a;
208 	REG BKPTR	bkptr;
209 	IF bpstate!=BPOUT
210 	THEN
211 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
212 		DO	IF bkptr->flag
213 			THEN a=bkptr->loc;
214 				IF a < txtmap.e1 THEN
215 				ptrace(WIUSER,pid,a,
216 					(bkptr->ins&0xFF)|(ptrace(RIUSER,pid,a,0)&~0xFF));
217 				ELSE
218 				ptrace(WDUSER,pid,a,
219 					(bkptr->ins&0xFF)|(ptrace(RDUSER,pid,a,0)&~0xFF));
220 				FI
221 			FI
222 		OD
223 		bpstate=BPOUT;
224 	FI
225 }
226 
227 setbp()
228 {
229 	REG ADDR		a;
230 	REG BKPTR	bkptr;
231 
232 	IF bpstate!=BPIN
233 	THEN
234 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
235 		DO IF bkptr->flag
236 		   THEN a = bkptr->loc;
237 			IF a < txtmap.e1 THEN
238 				bkptr->ins = ptrace(RIUSER, pid, a, 0);
239 				ptrace(WIUSER, pid, a, BPT | (bkptr->ins&~0xFF));
240 			ELSE
241 				bkptr->ins = ptrace(RDUSER, pid, a, 0);
242 				ptrace(WDUSER, pid, a, BPT | (bkptr->ins&~0xFF));
243 			FI
244 			IF errno
245 			THEN prints("cannot set breakpoint: ");
246 			     psymoff(bkptr->loc,ISYM,"\n");
247 			FI
248 		   FI
249 		OD
250 		bpstate=BPIN;
251 	FI
252 }
253 
254 bpwait()
255 {
256 	REG ADDR w;
257 	ADDR stat;
258 
259 	signal(SIGINT, 1);
260 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
261 	signal(SIGINT,sigint);
262 	IF w == -1
263 	THEN pid=0;
264 	     errflg=BADWAIT;
265 	ELIF (stat & 0177) != 0177
266 	THEN sigcode = 0;
267 	     IF signo = stat&0177
268 	     THEN sigprint();
269 	     FI
270 	     IF stat&0200
271 	     THEN prints(" - core dumped");
272 		  close(fcor);
273 		  setcor();
274 	     FI
275 	     pid=0;
276 	     errflg=ENDPCS;
277 	ELSE signo = stat>>8;
278 	     sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
279 	     IF signo!=SIGTRAP
280 	     THEN sigprint();
281 	     ELSE signo=0;
282 	     FI
283 	     flushbuf();
284 	FI
285 }
286 
287 readregs()
288 {
289 	/*get REG values from pcs*/
290 	REG i;
291 	FOR i=24; --i>=0;
292 	DO *(ADDR *)(((ADDR)&u)+reglist[i].roffs) =
293 		    ptrace(RUREGS, pid, reglist[i].roffs, 0);
294 	OD
295  	userpc= *(ADDR *)(((ADDR)&u)+PC);
296 }
297 
298 
299