1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)ptrace.c	5.1 (Berkeley) 06/06/85";
9 #endif not lint
10 
11 /*
12  * routines for tracing the execution of a process
13  *
14  * The system call "ptrace" does all the work, these
15  * routines just try to interface easily to it.
16  */
17 
18 #include "defs.h"
19 #include <signal.h>
20 #include <sys/param.h>
21 #include <machine/reg.h>
22 #include "process.h"
23 #include "object.h"
24 #include "process.rep"
25 
26 #   if (isvaxpx)
27 #       include "pxinfo.h"
28 #   endif
29 
30 #ifndef vax
31 #	define U_PAGE 0x2400
32 #	define U_AR0  (14*sizeof(int))
33 	LOCAL int ar0val = -1;
34 #endif
35 
36 /*
37  * This magic macro enables us to look at the process' registers
38  * in its user structure.  Very gross.
39  */
40 
41 #ifdef vax
42 #	define regloc(reg)     (ctob(UPAGES) + ( sizeof(int) * (reg) ))
43 #else
44 #	define regloc(reg)     (ar0val + ( sizeof(int) * (reg) ))
45 #endif
46 
47 #define WMASK           (~(sizeof(WORD) - 1))
48 #define cachehash(addr) ((unsigned) ((addr >> 2) % CSIZE))
49 
50 #define FIRSTSIG        SIGINT
51 #define LASTSIG         SIGQUIT
52 #define ischild(pid)    ((pid) == 0)
53 #define traceme()       ptrace(0, 0, 0, 0)
54 #define setrep(n)       (1 << ((n)-1))
55 #define istraced(p)     (p->sigset&setrep(p->signo))
56 
57 /*
58  * ptrace options (specified in first argument)
59  */
60 
61 #define UREAD   3       /* read from process's user structure */
62 #define UWRITE  6       /* write to process's user structure */
63 #define IREAD   1       /* read from process's instruction space */
64 #define IWRITE  4       /* write to process's instruction space */
65 #define DREAD   2       /* read from process's data space */
66 #define DWRITE  5       /* write to process's data space */
67 #define CONT    7       /* continue stopped process */
68 #define SSTEP   9       /* continue for approximately one instruction */
69 #define PKILL   8       /* terminate the process */
70 
71 /*
72  * Start up a new process by forking and exec-ing the
73  * given argument list, returning when the process is loaded
74  * and ready to execute.  The PROCESS information (pointed to
75  * by the first argument) is appropriately filled.
76  *
77  * If the given PROCESS structure is associated with an already running
78  * process, we terminate it.
79  */
80 
81 /* VARARGS2 */
82 pstart(p, cmd, argv, infile, outfile)
83 PROCESS *p;
84 char *cmd;
85 char **argv;
86 char *infile;
87 char *outfile;
88 {
89     int status;
90     FILE *in, *out;
91 
92     if (p->pid != 0) {                  /* child already running? */
93 	ptrace(PKILL, p->pid, 0, 0);    /* ... kill it! */
94     }
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 typedef int INTFUNC();
201 
202 LOCAL INTFUNC *sigfunc[NSIG];
203 
204 LOCAL sigs_off()
205 {
206     register int i;
207 
208     for (i = FIRSTSIG; i < LASTSIG; i++) {
209 	if (i != SIGKILL) {
210 	    sigfunc[i] = signal(i, SIG_IGN);
211 	}
212     }
213 }
214 
215 /*
216  * turn back on attention to signals
217  */
218 
219 LOCAL sigs_on()
220 {
221     register int i;
222 
223     for (i = FIRSTSIG; i < LASTSIG; i++) {
224 	if (i != SIGKILL) {
225 	    signal(i, sigfunc[i]);
226 	}
227     }
228 }
229 
230 /*
231  * get PROCESS information from process's user area
232  */
233 
234 #if vax
235     LOCAL int rloc[] ={
236 	R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11,
237     };
238 #else
239     LOCAL int rloc[] ={
240 	R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5,
241     };
242 #endif
243 
244 LOCAL getinfo(p, status)
245 register PROCESS *p;
246 register int status;
247 {
248     register int i;
249 
250     p->signo = (status&0177);
251     p->exitval = ((status >> 8)&0377);
252     if (p->signo == STOPPED) {
253 	p->status = p->signo;
254 	p->signo = p->exitval;
255 	p->exitval = 0;
256     } else {
257 	p->status = FINISHED;
258 	return;
259     }
260 #ifndef vax
261     if (ar0val < 0){
262 	ar0val = ptrace(UREAD, p->pid, U_AR0, 0);
263 	ar0val -= U_PAGE;
264     }
265 #endif
266     for (i = 0; i < NREG; i++) {
267 	p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0);
268 	p->oreg[i] = p->reg[i];
269     }
270 #ifdef vax
271     p->fp = p->ofp = ptrace(UREAD, p->pid, regloc(FP), 0);
272     p->ap = p->oap = ptrace(UREAD, p->pid, regloc(AP), 0);
273     p->sp = p->osp = ptrace(UREAD, p->pid, regloc(SP), 0);
274     p->pc = p->opc = ptrace(UREAD, p->pid, regloc(PC), 0);
275 #else
276     p->fp = p->ofp = ptrace(UREAD, p->pid, regloc(AR6), 0);
277     p->ap = p->oap = p->fp;
278     p->sp = p->osp = ptrace(UREAD, p->pid, regloc(SP), 0);
279     p->pc = p->opc = ptrace(UREAD, p->pid, regloc(PC), 0);
280 #endif
281 }
282 
283 /*
284  * set process's user area information from given PROCESS structure
285  */
286 
287 LOCAL setinfo(p)
288 register PROCESS *p;
289 {
290     register int i;
291     register int r;
292 
293     if (istraced(p)) {
294 	p->signo = 0;
295     }
296     for (i = 0; i < NREG; i++) {
297 	if ((r = p->reg[i]) != p->oreg[i]) {
298 	    ptrace(UWRITE, p->pid, regloc(rloc[i]), r);
299 	}
300     }
301 #if vax
302     if ((r = p->fp) != p->ofp) {
303 	ptrace(UWRITE, p->pid, regloc(FP), r);
304     }
305     if ((r = p->sp) != p->osp) {
306 	ptrace(UWRITE, p->pid, regloc(SP), r);
307     }
308     if ((r = p->ap) != p->oap) {
309 	ptrace(UWRITE, p->pid, regloc(AP), r);
310     }
311 #else
312     if ((r = p->fp) != p->ofp) {
313 	ptrace(UWRITE, p->pid, regloc(AR6), r);
314     }
315     if ((r = p->sp) != p->osp) {
316 	ptrace(UWRITE, p->pid, regloc(SP), r);
317     }
318 #endif
319     if ((r = p->pc) != p->opc) {
320 	ptrace(UWRITE, p->pid, regloc(PC), r);
321     }
322 }
323 
324 /*
325  * Structure for reading and writing by words, but dealing with bytes.
326  */
327 
328 typedef union {
329     WORD pword;
330     BYTE pbyte[sizeof(WORD)];
331 } PWORD;
332 
333 /*
334  * Read (write) from (to) the process' address space.
335  * We must deal with ptrace's inability to look anywhere other
336  * than at a word boundary.
337  */
338 
339 LOCAL WORD fetch();
340 LOCAL store();
341 
342 pio(p, op, seg, buff, addr, nbytes)
343 PROCESS *p;
344 PIO_OP op;
345 PIO_SEG seg;
346 char *buff;
347 ADDRESS addr;
348 int nbytes;
349 {
350     register int i;
351     register ADDRESS newaddr;
352     register char *cp;
353     char *bufend;
354     PWORD w;
355     ADDRESS wordaddr;
356     int byteoff;
357 
358     if (p->status != STOPPED) {
359 	error("program is not active");
360     }
361     cp = buff;
362     newaddr = addr;
363     wordaddr = (newaddr&WMASK);
364     if (wordaddr != newaddr) {
365 	w.pword = fetch(p, seg, wordaddr);
366 	for (i = newaddr - wordaddr; i<sizeof(WORD) && nbytes>0; i++) {
367 	    if (op == PREAD) {
368 		*cp++ = w.pbyte[i];
369 	    } else {
370 		w.pbyte[i] = *cp++;
371 	    }
372 	    nbytes--;
373 	}
374 	if (op == PWRITE) {
375 	    store(p, seg, wordaddr, w.pword);
376 	}
377 	newaddr = wordaddr + sizeof(WORD);
378     }
379     byteoff = (nbytes&(~WMASK));
380     nbytes -= byteoff;
381     bufend = cp + nbytes;
382     while (cp < bufend) {
383 	if (op == PREAD) {
384 	    *((WORD *) cp) = fetch(p, seg, newaddr);
385 	} else {
386 	    store(p, seg, newaddr, *((WORD *) cp));
387 	}
388 	cp += sizeof(WORD);
389 	newaddr += sizeof(WORD);
390     }
391     if (byteoff > 0) {
392 	w.pword = fetch(p, seg, newaddr);
393 	for (i = 0; i < byteoff; i++) {
394 	    if (op == PREAD) {
395 		*cp++ = w.pbyte[i];
396 	    } else {
397 		w.pbyte[i] = *cp++;
398 	    }
399 	}
400 	if (op == PWRITE) {
401 	    store(p, seg, newaddr, w.pword);
402 	}
403     }
404 }
405 
406 /*
407  * Get a word from a process at the given address.
408  * The address is assumed to be on a word boundary.
409  *
410  * We use a simple cache scheme to avoid redundant references to
411  * the instruction space (which is assumed to be pure).  In the
412  * case of px, the "instruction" space lies between ENDOFF and
413  * ENDOFF + objsize.
414  *
415  * It is necessary to use a write-through scheme so that
416  * breakpoints right next to each other don't interfere.
417  */
418 
419 LOCAL WORD fetch(p, seg, addr)
420 PROCESS *p;
421 PIO_SEG seg;
422 register int addr;
423 {
424     register CACHEWORD *wp;
425     register WORD w;
426 
427     switch (seg) {
428 	case TEXTSEG:
429 #           if (isvaxpx)
430 		panic("tried to fetch from px i-space");
431 		/* NOTREACHED */
432 #           else
433 		wp = &p->word[cachehash(addr)];
434 		if (addr == 0 || wp->addr != addr) {
435 		    w = ptrace(IREAD, p->pid, addr, 0);
436 		    wp->addr = addr;
437 		    wp->val = w;
438 		} else {
439 		    w = wp->val;
440 		}
441 		break;
442 #           endif
443 
444 	case DATASEG:
445 #           if (isvaxpx)
446 		if (addr >= ENDOFF && addr < ENDOFF + objsize) {
447 		    wp = &p->word[cachehash(addr)];
448 		    if (addr == 0 || wp->addr != addr) {
449 			w = ptrace(DREAD, p->pid, addr, 0);
450 			wp->addr = addr;
451 			wp->val = w;
452 		    } else {
453 			w = wp->val;
454 		    }
455 		} else {
456 		    w = ptrace(DREAD, p->pid, addr, 0);
457 		}
458 #           else
459 		w = ptrace(DREAD, p->pid, addr, 0);
460 #           endif
461 	    break;
462 
463 	default:
464 	    panic("fetch: bad seg %d", seg);
465 	    /* NOTREACHED */
466     }
467     return(w);
468 }
469 
470 /*
471  * Put a word into the process' address space at the given address.
472  * The address is assumed to be on a word boundary.
473  */
474 
475 LOCAL store(p, seg, addr, data)
476 PROCESS *p;
477 PIO_SEG seg;
478 int addr;
479 WORD data;
480 {
481     register CACHEWORD *wp;
482 
483     switch (seg) {
484 	case TEXTSEG:
485 	    wp = &p->word[cachehash(addr)];
486 	    wp->addr = addr;
487 	    wp->val = data;
488 	    ptrace(IWRITE, p->pid, addr, data);
489 	    break;
490 
491 	case DATASEG:
492 #           if (isvaxpx)
493 		if (addr >= ENDOFF && addr < ENDOFF + objsize) {
494 		    wp = &p->word[cachehash(addr)];
495 		    wp->addr = addr;
496 		    wp->val = data;
497 		}
498 #           endif
499 	    ptrace(DWRITE, p->pid, addr, data);
500 	    break;
501 
502 	default:
503 	    panic("store: bad seg %d", seg);
504 	    /*NOTREACHED*/
505     }
506 }
507 
508 /*
509  * Initialize the instruction cache for a process.
510  * This is particularly necessary after the program has been remade.
511  */
512 
513 initcache(process)
514 PROCESS *process;
515 {
516     register int i;
517 
518     for (i = 0; i < CSIZE; i++) {
519 	process->word[i].addr = 0;
520     }
521 }
522 
523 /*
524  * Swap file numbers so as to redirect standard input and output.
525  */
526 
527 LOCAL fswap(oldfd, newfd)
528 int oldfd;
529 int newfd;
530 {
531     if (oldfd != newfd) {
532 	close(oldfd);
533 	dup(newfd);
534 	close(newfd);
535     }
536 }
537