1 /*-
2  * Copyright (c) 1980, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)ptrace.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 /*
13  * routines for tracing the execution of a process
14  *
15  * The system call "ptrace" does all the work, these
16  * routines just try to interface easily to it.
17  */
18 
19 #include "defs.h"
20 #include <signal.h>
21 #include <sys/param.h>
22 #include <machine/reg.h>
23 #include "process.h"
24 #include "object.h"
25 #include "process.rep"
26 
27 #       include "pxinfo.h"
28 
29 #ifdef mc68000
30 #	define U_PAGE 0x2400
31 #	define U_AR0  (14*sizeof(int))
32 	LOCAL int ar0val = -1;
33 #endif
34 
35 /*
36  * This magic macro enables us to look at the process' registers
37  * in its user structure.  Very gross.
38  */
39 
40 #if defined(vax) || defined(tahoe)
41 #	define regloc(reg)     (ctob(UPAGES) + ( sizeof(int) * (reg) ))
42 #else
43 #	define regloc(reg)     (ar0val + ( sizeof(int) * (reg) ))
44 #endif
45 
46 #define WMASK           (~(sizeof(WORD) - 1))
47 #define cachehash(addr) ((unsigned) ((addr >> 2) % CSIZE))
48 
49 #define ischild(pid)    ((pid) == 0)
50 #define traceme()       ptrace(0, 0, 0, 0)
51 #define setrep(n)       (1 << ((n)-1))
52 #define istraced(p)     (p->sigset&setrep(p->signo))
53 
54 /*
55  * ptrace options (specified in first argument)
56  */
57 
58 #define UREAD   3       /* read from process's user structure */
59 #define UWRITE  6       /* write to process's user structure */
60 #define IREAD   1       /* read from process's instruction space */
61 #define IWRITE  4       /* write to process's instruction space */
62 #define DREAD   2       /* read from process's data space */
63 #define DWRITE  5       /* write to process's data space */
64 #define CONT    7       /* continue stopped process */
65 #define SSTEP   9       /* continue for approximately one instruction */
66 #define PKILL   8       /* terminate the process */
67 
68 /*
69  * Start up a new process by forking and exec-ing the
70  * given argument list, returning when the process is loaded
71  * and ready to execute.  The PROCESS information (pointed to
72  * by the first argument) is appropriately filled.
73  *
74  * If the given PROCESS structure is associated with an already running
75  * process, we terminate it.
76  */
77 
78 /* VARARGS2 */
79 pstart(p, cmd, argv, infile, outfile)
80 PROCESS *p;
81 char *cmd;
82 char **argv;
83 char *infile;
84 char *outfile;
85 {
86     int status;
87     FILE *in, *out;
88 
89     if (p->pid != 0) {                  /* child already running? */
90 	ptrace(PKILL, p->pid, 0, 0);    /* ... kill it! */
91     }
92 #ifdef tahoe
93     INTFP = (ADDRESS)0;
94 #endif tahoe
95     psigtrace(p, SIGTRAP, TRUE);
96     if ((p->pid = fork()) == -1) {
97 	panic("can't fork");
98     }
99     if (ischild(p->pid)) {
100 	traceme();
101 	if (infile != NIL) {
102 	    if ((in = fopen(infile, "r")) == NIL) {
103 		printf("can't read %s\n", infile);
104 		exit(1);
105 	    }
106 	    fswap(0, fileno(in));
107 	}
108 	if (outfile != NIL) {
109 	    if ((out = fopen(outfile, "w")) == NIL) {
110 		printf("can't write %s\n", outfile);
111 		exit(1);
112 	    }
113 	    fswap(1, fileno(out));
114 	}
115 	execvp(cmd, argv);
116 	panic("can't exec %s", argv[0]);
117     }
118     pwait(p->pid, &status);
119     getinfo(p, status);
120 }
121 
122 /*
123  * Continue a stopped process.  The argument points to a PROCESS structure.
124  * Before the process is restarted it's user area is modified according to
125  * the values in the structure.  When this routine finishes,
126  * the structure has the new values from the process's user area.
127  *
128  * Pcont terminates when the process stops with a signal pending that
129  * is being traced (via psigtrace), or when the process terminates.
130  */
131 
132 pcont(p)
133 PROCESS *p;
134 {
135     int status;
136 
137     if (p->pid == 0) {
138 	error("program not active");
139     }
140     do {
141 	setinfo(p);
142 	sigs_off();
143 	if (ptrace(CONT, p->pid, p->pc, p->signo) < 0) {
144 	    panic("can't continue process");
145 	}
146 	pwait(p->pid, &status);
147 	sigs_on();
148 	getinfo(p, status);
149     } while (p->status == STOPPED && !istraced(p));
150 }
151 
152 /*
153  * single step as best ptrace can
154  */
155 
156 pstep(p)
157 PROCESS *p;
158 {
159     int status;
160 
161     setinfo(p);
162     sigs_off();
163     ptrace(SSTEP, p->pid, p->pc, p->signo);
164     pwait(p->pid, &status);
165     sigs_on();
166     getinfo(p, status);
167 }
168 
169 /*
170  * Return from execution when the given signal is pending.
171  */
172 
173 psigtrace(p, sig, sw)
174 PROCESS *p;
175 int sig;
176 int sw;
177 {
178     if (sw) {
179 	p->sigset |= setrep(sig);
180     } else {
181 	p->sigset &= ~setrep(sig);
182     }
183 }
184 
185 /*
186  * Don't catch any signals.
187  * Particularly useful when letting a process finish uninhibited (i.e. px).
188  */
189 
190 unsetsigtraces(p)
191 PROCESS *p;
192 {
193     p->sigset = 0;
194 }
195 
196 /*
197  * turn off attention to signals not being caught
198  */
199 
200 LOCAL void *onintr, *onquit;
201 
202 LOCAL sigs_off()
203 {
204     onintr = signal(SIGINT, SIG_IGN);
205     onquit = signal(SIGQUIT, SIG_IGN);
206 }
207 
208 /*
209  * turn back on attention to signals
210  */
211 
212 LOCAL sigs_on()
213 {
214     (void) signal(SIGINT, onintr);
215     (void) signal(SIGQUIT, onquit);
216 }
217 
218 /*
219  * get PROCESS information from process's user area
220  */
221 
222 #if vax
223     LOCAL int rloc[] ={
224 	R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11,
225     };
226 #endif
227 #if tahoe
228     LOCAL int rloc[] ={
229 	R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
230     };
231 #endif
232 #if mc68000
233     LOCAL int rloc[] ={
234 	R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5,
235     };
236 #endif
237 
238 LOCAL getinfo(p, status)
239 register PROCESS *p;
240 register int status;
241 {
242     register int i;
243 
244     p->signo = (status&0177);
245     p->exitval = ((status >> 8)&0377);
246     if (p->signo == STOPPED) {
247 	p->status = p->signo;
248 	p->signo = p->exitval;
249 	p->exitval = 0;
250     } else {
251 	p->status = FINISHED;
252 	return;
253     }
254 #if !defined(vax) && !defined(tahoe)
255     if (ar0val < 0){
256 	ar0val = ptrace(UREAD, p->pid, U_AR0, 0);
257 	ar0val -= U_PAGE;
258     }
259 #endif
260     for (i = 0; i < NREG; i++) {
261 	p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0);
262 	p->oreg[i] = p->reg[i];
263     }
264 #if defined(vax) || defined(tahoe)
265     p->fp = p->ofp = ptrace(UREAD, p->pid, regloc(FP), 0);
266     p->sp = p->osp = ptrace(UREAD, p->pid, regloc(SP), 0);
267     p->pc = p->opc = ptrace(UREAD, p->pid, regloc(PC), 0);
268 #endif
269 #ifdef vax
270     p->ap = p->oap = ptrace(UREAD, p->pid, regloc(AP), 0);
271 #endif
272 #ifdef mc68000
273     p->fp = p->ofp = ptrace(UREAD, p->pid, regloc(AR6), 0);
274     p->ap = p->oap = p->fp;
275     p->sp = p->osp = ptrace(UREAD, p->pid, regloc(SP), 0);
276     p->pc = p->opc = ptrace(UREAD, p->pid, regloc(PC), 0);
277 #endif
278 }
279 
280 /*
281  * set process's user area information from given PROCESS structure
282  */
283 
284 LOCAL setinfo(p)
285 register PROCESS *p;
286 {
287     register int i;
288     register int r;
289 
290     if (istraced(p)) {
291 	p->signo = 0;
292     }
293     for (i = 0; i < NREG; i++) {
294 	if ((r = p->reg[i]) != p->oreg[i]) {
295 	    ptrace(UWRITE, p->pid, regloc(rloc[i]), r);
296 	}
297     }
298 #if vax || tahoe
299     if ((r = p->fp) != p->ofp) {
300 	ptrace(UWRITE, p->pid, regloc(FP), r);
301     }
302 #endif
303 #if vax
304     if ((r = p->ap) != p->oap) {
305 	ptrace(UWRITE, p->pid, regloc(AP), r);
306     }
307 #endif
308 #if mc68000
309     if ((r = p->fp) != p->ofp) {
310 	ptrace(UWRITE, p->pid, regloc(AR6), r);
311     }
312 #endif
313     if ((r = p->sp) != p->osp) {
314 	ptrace(UWRITE, p->pid, regloc(SP), r);
315     }
316     if ((r = p->pc) != p->opc) {
317 	ptrace(UWRITE, p->pid, regloc(PC), r);
318     }
319 }
320 
321 /*
322  * Structure for reading and writing by words, but dealing with bytes.
323  */
324 
325 typedef union {
326     WORD pword;
327     BYTE pbyte[sizeof(WORD)];
328 } PWORD;
329 
330 /*
331  * Read (write) from (to) the process' address space.
332  * We must deal with ptrace's inability to look anywhere other
333  * than at a word boundary.
334  */
335 
336 LOCAL WORD fetch();
337 LOCAL store();
338 
339 pio(p, op, seg, buff, addr, nbytes)
340 PROCESS *p;
341 PIO_OP op;
342 PIO_SEG seg;
343 char *buff;
344 ADDRESS addr;
345 int nbytes;
346 {
347     register int i, k;
348     register ADDRESS newaddr;
349     register char *cp;
350     char *bufend;
351     PWORD w;
352     ADDRESS wordaddr;
353     int byteoff;
354 
355     if (p->status != STOPPED) {
356 	error("program is not active");
357     }
358     cp = buff;
359     newaddr = addr;
360     wordaddr = (newaddr&WMASK);
361     if (wordaddr != newaddr) {
362 	w.pword = fetch(p, seg, wordaddr);
363 	for (i = newaddr - wordaddr; i<sizeof(WORD) && nbytes>0; i++) {
364 	    if (op == PREAD) {
365 		*cp++ = w.pbyte[i];
366 	    } else {
367 		w.pbyte[i] = *cp++;
368 	    }
369 	    nbytes--;
370 	}
371 	if (op == PWRITE) {
372 	    store(p, seg, wordaddr, w.pword);
373 	}
374 	newaddr = wordaddr + sizeof(WORD);
375     }
376     byteoff = (nbytes&(~WMASK));
377     nbytes -= byteoff;
378     bufend = cp + nbytes;
379     while (cp < bufend) {
380 	if (op == PREAD) {
381 	    w.pword = fetch(p, seg, newaddr);
382 	    for (k = 0; k < sizeof(WORD); k++) {
383 		*cp++ = w.pbyte[k];
384 	    }
385 	} else {
386 	    for (k = 0; k < sizeof(WORD); k++) {
387 		w.pbyte[k] = *cp++;
388 	    }
389 	    store(p, seg, newaddr, w.pword);
390 	}
391 	newaddr += sizeof(WORD);
392     }
393     if (byteoff > 0) {
394 	w.pword = fetch(p, seg, newaddr);
395 	for (i = 0; i < byteoff; i++) {
396 	    if (op == PREAD) {
397 		*cp++ = w.pbyte[i];
398 	    } else {
399 		w.pbyte[i] = *cp++;
400 	    }
401 	}
402 	if (op == PWRITE) {
403 	    store(p, seg, newaddr, w.pword);
404 	}
405     }
406 }
407 
408 /*
409  * Get a word from a process at the given address.
410  * The address is assumed to be on a word boundary.
411  *
412  * We use a simple cache scheme to avoid redundant references to
413  * the instruction space (which is assumed to be pure).  In the
414  * case of px, the "instruction" space lies between ENDOFF and
415  * ENDOFF + objsize.
416  *
417  * It is necessary to use a write-through scheme so that
418  * breakpoints right next to each other don't interfere.
419  */
420 
421 LOCAL WORD fetch(p, seg, addr)
422 PROCESS *p;
423 PIO_SEG seg;
424 register int addr;
425 {
426     register CACHEWORD *wp;
427     register WORD w;
428 
429     switch (seg) {
430 	case TEXTSEG:
431 	    panic("tried to fetch from px i-space");
432 	    /* NOTREACHED */
433 
434 	case DATASEG:
435 	    if (addr >= ENDOFF && addr < ENDOFF + objsize) {
436 		wp = &p->word[cachehash(addr)];
437 		if (addr == 0 || wp->addr != addr) {
438 		    w = ptrace(DREAD, p->pid, addr, 0);
439 		    wp->addr = addr;
440 		    wp->val = w;
441 		} else {
442 		    w = wp->val;
443 		}
444 	    } else {
445 		w = ptrace(DREAD, p->pid, addr, 0);
446 	    }
447 	    break;
448 
449 	default:
450 	    panic("fetch: bad seg %d", seg);
451 	    /* NOTREACHED */
452     }
453     return(w);
454 }
455 
456 /*
457  * Put a word into the process' address space at the given address.
458  * The address is assumed to be on a word boundary.
459  */
460 
461 LOCAL store(p, seg, addr, data)
462 PROCESS *p;
463 PIO_SEG seg;
464 int addr;
465 WORD data;
466 {
467     register CACHEWORD *wp;
468 
469     switch (seg) {
470 	case TEXTSEG:
471 	    wp = &p->word[cachehash(addr)];
472 	    wp->addr = addr;
473 	    wp->val = data;
474 	    ptrace(IWRITE, p->pid, addr, data);
475 	    break;
476 
477 	case DATASEG:
478 	    if (addr >= ENDOFF && addr < ENDOFF + objsize) {
479 		wp = &p->word[cachehash(addr)];
480 		wp->addr = addr;
481 		wp->val = data;
482 	    }
483 	    ptrace(DWRITE, p->pid, addr, data);
484 	    break;
485 
486 	default:
487 	    panic("store: bad seg %d", seg);
488 	    /*NOTREACHED*/
489     }
490 }
491 
492 /*
493  * Initialize the instruction cache for a process.
494  * This is particularly necessary after the program has been remade.
495  */
496 
497 initcache(process)
498 PROCESS *process;
499 {
500     register int i;
501 
502     for (i = 0; i < CSIZE; i++) {
503 	process->word[i].addr = 0;
504     }
505 }
506 
507 /*
508  * Swap file numbers so as to redirect standard input and output.
509  */
510 
511 LOCAL fswap(oldfd, newfd)
512 int oldfd;
513 int newfd;
514 {
515     if (oldfd != newfd) {
516 	close(oldfd);
517 	dup(newfd);
518 	close(newfd);
519     }
520 }
521 
522 #ifdef tahoe
523 BOOLEAN didret;
524 
525 void
526 chkret(p, status)
527 PROCESS *p;
528 int status;
529 {
530 	if (((status == (SIGILL << 8) | STOPPED) ||
531 	    (status == (SIGTRAP << 8) | STOPPED))) {
532 		didret = FALSE;
533 	} else {
534 		didret = TRUE;
535 	}
536 }
537 
538 void
539 doret(p)
540 PROCESS *p;
541 {
542 	register count = 0;
543 
544 	if (!didret) {
545 	    do {
546 		if (++count > 5) {
547 		    panic("px would not return to interpreter");
548 		}
549 		p->pc = RETLOC;
550 		pstep(p);
551 	    } while(INTFP && p->fp != INTFP);
552 	    didret = TRUE;
553 	}
554 }
555 #endif
556