xref: /original-bsd/old/adb/adb.hp300/runpcs.c (revision 1d5f76bd)
1 #ifndef lint
2 static	char sccsid[] = "@(#)runpcs.c	4.6 4/25/85";
3 #endif
4 /*
5  *
6  *	UNIX debugger
7  *
8  */
9 
10 #include "defs.h"
11 #include <sys/wait.h>
12 
13 extern	MAP	txtmap;
14 
15 MSG		NOFORK;
16 MSG		ENDPCS;
17 MSG		BADWAIT;
18 
19 CHAR		*lp;
20 ADDR		sigint;
21 ADDR		sigqit;
22 
23 /* breakpoints */
24 BKPTR		bkpthead;
25 
26 extern REGLIST	reglist[];
27 extern INT	nregs;
28 
29 CHAR		lastc;
30 
31 INT		fcor;
32 INT		fsym;
33 STRING		errflg;
34 int		errno;
35 INT		signo;
36 INT		sigcode;
37 
38 L_INT		dot;
39 STRING		symfil;
40 INT		wtflag;
41 INT		pid;
42 L_INT		expv;
43 INT		adrflg;
44 L_INT		loopcnt;
45 
46 
47 
48 
49 
50 /* service routines for sub process control */
51 
52 getsig(sig)
53 {	return(expr(0) ? expv : sig);
54 }
55 
56 ADDR userpc = 1;
57 
58 runpcs(runmode,execsig)
59 {
60 	INT		rc;
61 	REG BKPTR	bkpt;
62 	IF adrflg THEN userpc=dot; FI
63 	printf("%s: running\n", symfil);
64 
65 	WHILE --loopcnt>=0
66 	DO
67 #ifdef DEBUG
68 		printf("\ncontinue %x %d\n",userpc,execsig);
69 #endif
70 		IF runmode==SINGLE
71 		THEN delbp(); /* hardware handles single-stepping */
72 		ELSE /* continuing from a breakpoint is hard */
73 			IF bkpt=scanbkpt(userpc)
74 			THEN execbkpt(bkpt,execsig); execsig=0;
75 			FI
76 			setbp();
77 		FI
78 		ptrace(runmode,pid,userpc,execsig);
79 		bpwait(); chkerr(); execsig=0; delbp(); readregs();
80 
81 		IF signo==0
82 		ANDF runmode != SINGLE
83 #ifdef mc68000
84 		ANDF (bkpt=scanbkpt(userpc - 2))	/* argh */
85 #else
86 		ANDF (bkpt=scanbkpt(userpc))
87 #endif
88 		THEN /* stopped by BPT instruction */
89 #ifdef DEBUG
90 			printf("\n BPT code; '%s'%o'%o'%d",
91 				bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
92 #endif
93 			dot=bkpt->loc;
94 			userpc = dot;
95 			*(ADDR *)(((ADDR)&u)+PC-getradj(1)) = userpc;
96 			IF bkpt->flag==BKPTEXEC
97 			ORF ((bkpt->flag=BKPTEXEC)
98 				ANDF bkpt->comm[0]!=EOR
99 				ANDF command(bkpt->comm,':')
100 				ANDF --bkpt->count)
101 			THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
102 			ELSE bkpt->count=bkpt->initcnt; rc=1;
103 			FI
104 		ELSE execsig=signo; rc=0;
105 		FI
106 	OD
107 	return(rc);
108 }
109 
110 #define BPOUT 0
111 #define BPIN 1
112 INT bpstate = BPOUT;
113 
114 endpcs()
115 {
116 	REG BKPTR	bkptr;
117 	IF pid
118 	THEN ptrace(PT_KILL,pid,0,0); pid=0; userpc=1;
119 	     FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
120 	     DO IF bkptr->flag
121 		THEN bkptr->flag=BKPTSET;
122 		FI
123 	     OD
124 	FI
125 	bpstate=BPOUT;
126 }
127 
128 #ifdef VFORK
129 nullsig()
130 {
131 
132 }
133 #endif
134 
135 setup()
136 {
137 	close(fsym); fsym = -1;
138 #ifndef VFORK
139 	IF (pid = fork()) == 0
140 #else
141 	IF (pid = vfork()) == 0
142 #endif
143 	THEN ptrace(PT_TRACE_ME,0,0,0);
144 #ifdef VFORK
145 	     signal(SIGTRAP,nullsig);
146 #endif
147 	     signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
148 	     doexec(); exit(0);
149 	ELIF pid == -1
150 	THEN error(NOFORK);
151 	ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
152 	     fsym=open(symfil,wtflag);
153 	     IF errflg
154 	     THEN printf("%s: cannot execute\n",symfil);
155 		  endpcs(); error(0);
156 	     FI
157 	FI
158 	bpstate=BPOUT;
159 }
160 
161 execbkpt(bkptr,execsig)
162 BKPTR	bkptr;
163 {
164 #ifdef DEBUG
165 	printf("exbkpt: %d\n",bkptr->count);
166 #endif
167 	delbp();
168 	ptrace(PT_STEP,pid,bkptr->loc,execsig);
169 	bkptr->flag=BKPTSET;
170 	bpwait(); chkerr(); readregs();
171 }
172 
173 
174 doexec()
175 {
176 	STRING		argl[MAXARG];
177 	CHAR		args[LINSIZ];
178 	STRING		p, *ap, filnam;
179 	extern STRING environ;
180 	ap=argl; p=args;
181 	*ap++=symfil;
182 	REP	IF rdc()==EOR THEN break; FI
183 		*ap = p;
184 		/*
185 		 * First thing is to look for direction characters
186 		 * and get filename.  Do not use up the args for filenames.
187 		 * Then get rid of spaces before next args.
188 		 */
189 		IF 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(0);
196 			IF open(filnam,0)<0
197 			THEN	printf("%s: cannot open\n",filnam); _exit(0);
198 			FI
199 			p = *ap;
200 		ELIF lastc=='>'
201 		THEN	REP readchar(); PER lastc==SP ORF lastc==TB DONE
202 			filnam = p;
203 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='<'
204 				DO *p++=lastc; readchar(); OD
205 			*p = '\0';
206 			close(1);
207 			IF creat(filnam,0666)<0
208 			THEN	printf("%s: cannot create\n",filnam); _exit(0);
209 			FI
210 			p = *ap;
211 		ELSE
212 			WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB ANDF lastc!='>' ANDF lastc!='<'
213 				DO *p++=lastc; readchar(); OD
214 			*p++ = '\0';
215 	 		ap++;
216 		FI
217 	PER lastc!=EOR DONE
218 	*ap++=0;
219 	exect(symfil, argl, environ);
220 	perror(symfil);
221 }
222 
223 BKPTR	scanbkpt(adr)
224 ADDR adr;
225 {
226 	REG BKPTR	bkptr;
227 	FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
228 	DO IF bkptr->flag ANDF bkptr->loc==adr
229 	   THEN break;
230 	   FI
231 	OD
232 	return(bkptr);
233 }
234 
235 delbp()
236 {
237 	REG ADDR	a;
238 	REG BKPTR	bkptr;
239 	IF bpstate!=BPOUT
240 	THEN
241 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
242 		DO	IF bkptr->flag
243 			THEN a=bkptr->loc;
244 				IF a < txtmap.e1 THEN
245 					ptrace(PT_WRITE_I,pid,a,bkptr->ins);
246 				ELSE
247 					ptrace(PT_WRITE_D,pid,a,bkptr->ins);
248 				FI
249 			FI
250 		OD
251 		bpstate=BPOUT;
252 	FI
253 }
254 
255 #ifdef pdp11
256 help -- I left my architecture manual at home
257 #endif
258 
259 #ifdef vax
260 #define	SETBP(ins)	(BPT | ((ins) &~ 0xFF))
261 #endif
262 
263 #ifdef mc68000
264 #define	SETBP(ins)	((BPT << 16) | ((ins) & 0xFFFF))
265 #endif
266 
267 #if !pdp11 && !vax && !mc68000
268 
269 edit this file to handle your machines breakpoint indication
270 
271 #endif
272 
273 setbp()
274 {
275 	REG ADDR		a;
276 	REG BKPTR	bkptr;
277 
278 	IF bpstate!=BPIN
279 	THEN
280 		FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
281 		DO IF bkptr->flag
282 		   THEN a = bkptr->loc;
283 			IF a < txtmap.e1 THEN
284 				bkptr->ins = ptrace(PT_READ_I, pid, a, 0);
285 				ptrace(PT_WRITE_I, pid, a, SETBP(bkptr->ins));
286 			ELSE
287 				bkptr->ins = ptrace(PT_READ_D, pid, a, 0);
288 				ptrace(PT_WRITE_D, pid, a, SETBP(bkptr->ins));
289 			FI
290 			IF errno
291 			THEN prints("cannot set breakpoint: ");
292 			     psymoff(bkptr->loc,ISYM,"\n");
293 			FI
294 		   FI
295 		OD
296 		bpstate=BPIN;
297 	FI
298 }
299 
300 bpwait()
301 {
302 	REG ADDR w;
303 	union wait stat;
304 
305 	signal(SIGINT, 1);
306 	WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
307 	signal(SIGINT,sigint);
308 	IF w == -1
309 	THEN pid=0;
310 	     errflg=BADWAIT;
311 	ELIF !WIFSTOPPED(stat)
312 	THEN sigcode = 0;
313 	     IF signo = stat.w_termsig
314 	     THEN sigprint();
315 	     FI
316 	     IF stat.w_coredump
317 	     THEN prints(" - core dumped");
318 		  close(fcor);
319 		  setcor();
320 	     FI
321 	     pid=0;
322 	     errflg=ENDPCS;
323 	ELSE signo = stat.w_stopsig;
324 	     sigcode = ptrace(PT_READ_U, pid, &((struct user *)0)->u_code, 0);
325 	     IF signo!=SIGTRAP
326 	     THEN sigprint();
327 	     ELSE signo=0;
328 	     FI
329 	     flushbuf();
330 	FI
331 }
332 
333 readregs()
334 {
335 	/*get REG values from pcs*/
336 	REG i;
337 	L_INT radj = getradj(1);
338 	L_INT offset;
339 
340 	FOR i=nregs; --i>=0;
341 	DO	IF (offset = reglist[i].roffs) >= sizeof (struct user)
342 		THEN	offset -= radj;
343 		FI
344 		*(ADDR *)(((ADDR)&u) + offset) =
345 		    ptrace(PT_READ_U, pid, offset, 0);
346 #ifdef hp300
347 		/* XXX: 68881/68882 FP regs are 3 longwords */
348 		IF reglist[i].rtype == XPFLOAT
349 		THEN	offset += sizeof (ADDR);
350 			*(ADDR *)(((ADDR)&u) + offset) =
351 				ptrace(PT_READ_U, pid, offset, 0);
352 			offset += sizeof (ADDR);
353 			*(ADDR *)(((ADDR)&u) + offset) =
354 				ptrace(PT_READ_U, pid, offset, 0);
355 		FI
356 #endif
357 	OD
358  	userpc= *(ADDR *)(((ADDR)&u) + PC - radj);
359 }
360 
361 #ifdef hp300
362 L_INT
363 getradj(running)
364 INT	running;
365 {
366 	L_INT	radj;
367 
368 	/* this code assumes that u_ap always points to u_arg */
369 	IF running
370 	THEN	u.u_ar0 = (int *) ptrace(PT_READ_U, pid,
371 			(ADDR)&u.u_ar0 - (ADDR) &u, 0);
372 #if 0
373 		u.u_ap = (int *) ptrace(PT_READ_U, pid,
374 			(ADDR)&u.u_ap - (ADDR) &u, 0);
375 #endif
376 		IF u.u_ar0 == -1
377 #if 0
378 		ORF u.u_ap == -1
379 #endif
380 		THEN	endpcs();
381 			error("can't read from running process");
382 			return (0);
383 		FI
384 	FI
385 	IF !kcore
386 	THEN
387 #if 0
388 		radj = (ADDR) &u.u_arg - (ADDR) &u;	/* offset of u_arg */
389 		radj = (ADDR) u.u_ap - radj;		/* address of u */
390 #endif
391 		radj = (ADDR) 0xfff00000;
392 		radj = (ADDR) u.u_ar0 - radj;		/* offset of d0 */
393 		radj = D0 - radj;	/* difference from expected offset */
394 	ELSE
395 		radj = 0;
396 	FI
397 	return (radj);
398 }
399 #endif
400