xref: /csrg-svn/old/dbx/process.c (revision 17253)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static	char sccsid[] = "@(#)process.c	1.16 (Berkeley) 10/13/84";
4 
5 /*
6  * Process management.
7  *
8  * This module contains the routines to manage the execution and
9  * tracing of the debuggee process.
10  */
11 
12 #include "defs.h"
13 #include "process.h"
14 #include "machine.h"
15 #include "events.h"
16 #include "tree.h"
17 #include "eval.h"
18 #include "operators.h"
19 #include "source.h"
20 #include "object.h"
21 #include "mappings.h"
22 #include "main.h"
23 #include "coredump.h"
24 #include <signal.h>
25 #include <errno.h>
26 #include <ptrace.h>
27 #include <sys/param.h>
28 #include <sys/dir.h>
29 #include <sys/user.h>
30 #include <machine/reg.h>
31 #include <sys/stat.h>
32 
33 #ifndef public
34 
35 typedef struct Process *Process;
36 
37 Process process;
38 
39 #define DEFSIG -1
40 
41 #include "machine.h"
42 
43 #endif
44 
45 #define NOTSTARTED 1
46 #define STOPPED 0177
47 #define FINISHED 0
48 
49 /*
50  * A cache of the instruction segment is kept to reduce the number
51  * of system calls.  Might be better just to read the entire
52  * code space into memory.
53  */
54 
55 #define CSIZE 1003       /* size of instruction cache */
56 
57 typedef struct {
58     Word addr;
59     Word val;
60 } CacheWord;
61 
62 /*
63  * This structure holds the information we need from the user structure.
64  */
65 
66 struct Process {
67     int pid;			/* process being traced */
68     int mask;			/* process status word */
69     Word reg[NREG];		/* process' registers */
70     Word oreg[NREG];		/* registers when process last stopped */
71     short status;		/* either STOPPED or FINISHED */
72     short signo;		/* signal that stopped process */
73     short sigcode;		/* auxiliary signal info code */
74     int exitval;		/* return value from exit() */
75     long sigset;		/* bit array of traced signals */
76     CacheWord word[CSIZE];	/* text segment cache */
77     Ttyinfo ttyinfo;		/* process' terminal characteristics */
78     Address sigstatus;		/* process' handler for current signal */
79 };
80 
81 /*
82  * These definitions are for the arguments to "pio".
83  */
84 
85 typedef enum { PREAD, PWRITE } PioOp;
86 typedef enum { TEXTSEG, DATASEG } PioSeg;
87 
88 private struct Process pbuf;
89 
90 #define MAXNCMDARGS 100         /* maximum number of arguments to RUN */
91 
92 extern int errno;
93 
94 private Boolean just_started;
95 private int argc;
96 private String argv[MAXNCMDARGS];
97 private String infile, outfile;
98 
99 /*
100  * Initialize process information.
101  */
102 
103 public process_init()
104 {
105     register Integer i;
106     Char buf[10];
107 
108     process = &pbuf;
109     process->status = (coredump) ? STOPPED : NOTSTARTED;
110     setsigtrace();
111     for (i = 0; i < NREG; i++) {
112 	sprintf(buf, "$r%d", i);
113 	defregname(identname(buf, false), i);
114     }
115     defregname(identname("$ap", true), ARGP);
116     defregname(identname("$fp", true), FRP);
117     defregname(identname("$sp", true), STKP);
118     defregname(identname("$pc", true), PROGCTR);
119     if (coredump) {
120 	coredump_readin(process->mask, process->reg, process->signo);
121 	pc = process->reg[PROGCTR];
122 	getsrcpos();
123     }
124     arginit();
125 }
126 
127 /*
128  * Routines to get at process information from outside this module.
129  */
130 
131 public Word reg(n)
132 Integer n;
133 {
134     register Word w;
135 
136     if (n == NREG) {
137 	w = process->mask;
138     } else {
139 	w = process->reg[n];
140     }
141     return w;
142 }
143 
144 public setreg(n, w)
145 Integer n;
146 Word w;
147 {
148     process->reg[n] = w;
149 }
150 
151 /*
152  * Begin execution.
153  *
154  * We set a breakpoint at the end of the code so that the
155  * process data doesn't disappear after the program terminates.
156  */
157 
158 private Boolean remade();
159 
160 public start(argv, infile, outfile)
161 String argv[];
162 String infile, outfile;
163 {
164     String pargv[4];
165     Node cond;
166 
167     if (coredump) {
168 	coredump = false;
169 	fclose(corefile);
170 	coredump_close();
171     }
172     if (argv == nil) {
173 	argv = pargv;
174 	pargv[0] = objname;
175 	pargv[1] = nil;
176     } else {
177 	argv[argc] = nil;
178     }
179     if (remade(objname)) {
180 	reinit(argv, infile, outfile);
181     }
182     pstart(process, argv, infile, outfile);
183     if (process->status == STOPPED) {
184 	pc = 0;
185 	setcurfunc(program);
186 	if (objsize != 0) {
187 	    cond = build(O_EQ, build(O_SYM, pcsym), build(O_LCON, lastaddr()));
188 	    event_once(cond, buildcmdlist(build(O_ENDX)));
189 	}
190     }
191 }
192 
193 /*
194  * Check to see if the object file has changed since the symbolic
195  * information last was read.
196  */
197 
198 private time_t modtime;
199 
200 private Boolean remade(filename)
201 String filename;
202 {
203     struct stat s;
204     Boolean b;
205 
206     stat(filename, &s);
207     b = (Boolean) (modtime != 0 and modtime < s.st_mtime);
208     modtime = s.st_mtime;
209     return b;
210 }
211 
212 /*
213  * Set up what signals we want to trace.
214  */
215 
216 private setsigtrace()
217 {
218     register Integer i;
219     register Process p;
220 
221     p = process;
222     for (i = 1; i <= NSIG; i++) {
223 	psigtrace(p, i, true);
224     }
225     psigtrace(p, SIGHUP, false);
226     psigtrace(p, SIGKILL, false);
227     psigtrace(p, SIGALRM, false);
228     psigtrace(p, SIGTSTP, false);
229     psigtrace(p, SIGCONT, false);
230     psigtrace(p, SIGCHLD, false);
231 }
232 
233 /*
234  * Initialize the argument list.
235  */
236 
237 public arginit()
238 {
239     infile = nil;
240     outfile = nil;
241     argv[0] = objname;
242     argc = 1;
243 }
244 
245 /*
246  * Add an argument to the list for the debuggee.
247  */
248 
249 public newarg(arg)
250 String arg;
251 {
252     if (argc >= MAXNCMDARGS) {
253 	error("too many arguments");
254     }
255     argv[argc++] = arg;
256 }
257 
258 /*
259  * Set the standard input for the debuggee.
260  */
261 
262 public inarg(filename)
263 String filename;
264 {
265     if (infile != nil) {
266 	error("multiple input redirects");
267     }
268     infile = filename;
269 }
270 
271 /*
272  * Set the standard output for the debuggee.
273  * Probably should check to avoid overwriting an existing file.
274  */
275 
276 public outarg(filename)
277 String filename;
278 {
279     if (outfile != nil) {
280 	error("multiple output redirect");
281     }
282     outfile = filename;
283 }
284 
285 /*
286  * Start debuggee executing.
287  */
288 
289 public run()
290 {
291     process->status = STOPPED;
292     fixbps();
293     curline = 0;
294     start(argv, infile, outfile);
295     just_started = true;
296     isstopped = false;
297     cont(0);
298 }
299 
300 /*
301  * Continue execution wherever we left off.
302  *
303  * Note that this routine never returns.  Eventually bpact() will fail
304  * and we'll call printstatus or step will call it.
305  */
306 
307 typedef int Intfunc();
308 
309 private Intfunc *dbintr;
310 private intr();
311 
312 #define succeeds    == true
313 #define fails       == false
314 
315 public cont(signo)
316 integer signo;
317 {
318     integer s;
319 
320     dbintr = signal(SIGINT, intr);
321     if (just_started) {
322 	just_started = false;
323     } else {
324 	if (not isstopped) {
325 	    error("can't continue execution");
326 	}
327 	isstopped = false;
328 	stepover();
329     }
330     s = signo;
331     for (;;) {
332 	if (single_stepping) {
333 	    printnews();
334 	} else {
335 	    setallbps();
336 	    resume(s);
337 	    unsetallbps();
338 	    s = DEFSIG;
339 	    if (bpact() fails) {
340 		printstatus();
341 	    }
342 	}
343 	stepover();
344     }
345     /* NOTREACHED */
346 }
347 
348 /*
349  * This routine is called if we get an interrupt while "running" px
350  * but actually in the debugger.  Could happen, for example, while
351  * processing breakpoints.
352  *
353  * We basically just want to keep going; the assumption is
354  * that when the process resumes it will get the interrupt
355  * which will then be handled.
356  */
357 
358 private intr()
359 {
360     signal(SIGINT, intr);
361 }
362 
363 public fixintr()
364 {
365     signal(SIGINT, dbintr);
366 }
367 
368 /*
369  * Resume execution.
370  */
371 
372 public resume(signo)
373 int signo;
374 {
375     register Process p;
376 
377     p = process;
378     pcont(p, signo);
379     pc = process->reg[PROGCTR];
380     if (p->status != STOPPED) {
381 	if (p->signo != 0) {
382 	    error("program terminated by signal %d", p->signo);
383 	} else if (not runfirst) {
384 	    error("program unexpectedly exited with %d", p->exitval);
385 	}
386     }
387 }
388 
389 /*
390  * Continue execution up to the next source line.
391  *
392  * There are two ways to define the next source line depending on what
393  * is desired when a procedure or function call is encountered.  Step
394  * stops at the beginning of the procedure or call; next skips over it.
395  */
396 
397 /*
398  * Stepc is what is called when the step command is given.
399  * It has to play with the "isstopped" information.
400  */
401 
402 public stepc()
403 {
404     if (not isstopped) {
405 	error("can't continue execution");
406     }
407     isstopped = false;
408     dostep(false);
409     isstopped = true;
410 }
411 
412 public next()
413 {
414     Address oldfrp, newfrp;
415 
416     if (not isstopped) {
417 	error("can't continue execution");
418     }
419     isstopped = false;
420     oldfrp = reg(FRP);
421     do {
422 	dostep(true);
423 	pc = reg(PROGCTR);
424 	newfrp = reg(FRP);
425     } while (newfrp < oldfrp and newfrp != 0);
426     isstopped = true;
427 }
428 
429 /*
430  * Continue execution until the current function returns, or,
431  * if the given argument is non-nil, until execution returns to
432  * somewhere within the given function.
433  */
434 
435 public rtnfunc (f)
436 Symbol f;
437 {
438     Address addr;
439     Symbol t;
440 
441     if (not isstopped) {
442 	error("can't continue execution");
443     } else if (f != nil and not isactive(f)) {
444 	error("%s is not active", symname(f));
445     } else {
446 	addr = return_addr();
447 	if (addr == nil) {
448 	    error("no place to return to");
449 	} else {
450 	    isstopped = false;
451 	    contto(addr);
452 	    if (f != nil) {
453 		for (;;) {
454 		    t = whatblock(pc);
455 		    addr = return_addr();
456 		if (t == f or addr == nil) break;
457 		    contto(addr);
458 		}
459 	    }
460 	    if (bpact() fails) {
461 		isstopped = true;
462 		printstatus();
463 	    }
464 	}
465     }
466 }
467 
468 /*
469  * Single-step over the current machine instruction.
470  *
471  * If we're single-stepping by source line we want to step to the
472  * next source line.  Otherwise we're going to continue so there's
473  * no reason to do all the work necessary to single-step to the next
474  * source line.
475  */
476 
477 public stepover()
478 {
479     Boolean b;
480 
481     if (traceexec) {
482 	printf("!! stepping over 0x%x\n", process->reg[PROGCTR]);
483     }
484     if (single_stepping) {
485 	dostep(false);
486     } else {
487 	b = inst_tracing;
488 	inst_tracing = true;
489 	dostep(false);
490 	inst_tracing = b;
491     }
492     if (traceexec) {
493 	printf("!! stepped over to 0x%x\n", process->reg[PROGCTR]);
494     }
495 }
496 
497 /*
498  * Resume execution up to the given address.  It is assumed that
499  * no breakpoints exist between the current address and the one
500  * we're stepping to.  This saves us from setting all the breakpoints.
501  */
502 
503 public stepto(addr)
504 Address addr;
505 {
506     xto(addr, false);
507 }
508 
509 private contto (addr)
510 Address addr;
511 {
512     xto(addr, true);
513 }
514 
515 private xto (addr, catchbps)
516 Address addr;
517 boolean catchbps;
518 {
519     Address curpc;
520 
521     if (catchbps) {
522 	stepover();
523     }
524     curpc = process->reg[PROGCTR];
525     if (addr != curpc) {
526 	if (traceexec) {
527 	    printf("!! stepping from 0x%x to 0x%x\n", curpc, addr);
528 	}
529 	if (catchbps) {
530 	    setallbps();
531 	}
532 	setbp(addr);
533 	resume(DEFSIG);
534 	unsetbp(addr);
535 	if (catchbps) {
536 	    unsetallbps();
537 	}
538 	if (not isbperr()) {
539 	    printstatus();
540 	}
541     }
542 }
543 
544 /*
545  * Print the status of the process.
546  * This routine does not return.
547  */
548 
549 public printstatus()
550 {
551     int status;
552 
553     if (process->status == FINISHED) {
554 	exit(0);
555     } else {
556 	setcurfunc(whatblock(pc));
557 	getsrcpos();
558 	if (process->signo == SIGINT) {
559 	    isstopped = true;
560 	    printerror();
561 	} else if (isbperr() and isstopped) {
562 	    printf("stopped ");
563 	    printloc();
564 	    putchar('\n');
565 	    if (curline > 0) {
566 		printlines(curline, curline);
567 	    } else {
568 		printinst(pc, pc);
569 	    }
570 	    erecover();
571 	} else {
572 	    fixintr();
573 	    isstopped = true;
574 	    printerror();
575 	}
576     }
577 }
578 
579 /*
580  * Print out the current location in the debuggee.
581  */
582 
583 public printloc()
584 {
585     printf("in ");
586     printname(stdout, curfunc);
587     putchar(' ');
588     if (curline > 0 and not useInstLoc) {
589 	printsrcpos();
590     } else {
591 	useInstLoc = false;
592 	curline = 0;
593 	printf("at 0x%x", pc);
594     }
595 }
596 
597 /*
598  * Some functions for testing the state of the process.
599  */
600 
601 public Boolean notstarted(p)
602 Process p;
603 {
604     return (Boolean) (p->status == NOTSTARTED);
605 }
606 
607 public Boolean isfinished(p)
608 Process p;
609 {
610     return (Boolean) (p->status == FINISHED);
611 }
612 
613 /*
614  * Return the signal number which stopped the process.
615  */
616 
617 public Integer errnum(p)
618 Process p;
619 {
620     return p->signo;
621 }
622 
623 public Integer errcode(p)
624 Process p;
625 {
626     return p->sigcode;
627 }
628 
629 /*
630  * Return the termination code of the process.
631  */
632 
633 public Integer exitcode(p)
634 Process p;
635 {
636     return p->exitval;
637 }
638 
639 /*
640  * These routines are used to access the debuggee process from
641  * outside this module.
642  *
643  * They invoke "pio" which eventually leads to a call to "ptrace".
644  * The system generates an I/O error when a ptrace fails.  During reads
645  * these are ignored, during writes they are reported as an error, and
646  * for anything else they cause a fatal error.
647  */
648 
649 extern Intfunc *onsyserr();
650 
651 private badaddr;
652 private read_err(), write_err();
653 
654 /*
655  * Read from the process' instruction area.
656  */
657 
658 public iread(buff, addr, nbytes)
659 char *buff;
660 Address addr;
661 int nbytes;
662 {
663     Intfunc *f;
664 
665     f = onsyserr(EIO, read_err);
666     badaddr = addr;
667     if (coredump) {
668 	coredump_readtext(buff, addr, nbytes);
669     } else {
670 	pio(process, PREAD, TEXTSEG, buff, addr, nbytes);
671     }
672     onsyserr(EIO, f);
673 }
674 
675 /*
676  * Write to the process' instruction area, usually in order to set
677  * or unset a breakpoint.
678  */
679 
680 public iwrite(buff, addr, nbytes)
681 char *buff;
682 Address addr;
683 int nbytes;
684 {
685     Intfunc *f;
686 
687     if (coredump) {
688 	error("no process to write to");
689     }
690     f = onsyserr(EIO, write_err);
691     badaddr = addr;
692     pio(process, PWRITE, TEXTSEG, buff, addr, nbytes);
693     onsyserr(EIO, f);
694 }
695 
696 /*
697  * Read for the process' data area.
698  */
699 
700 public dread(buff, addr, nbytes)
701 char *buff;
702 Address addr;
703 int nbytes;
704 {
705     Intfunc *f;
706 
707     f = onsyserr(EIO, read_err);
708     badaddr = addr;
709     if (coredump) {
710 	coredump_readdata(buff, addr, nbytes);
711     } else {
712 	pio(process, PREAD, DATASEG, buff, addr, nbytes);
713     }
714     onsyserr(EIO, f);
715 }
716 
717 /*
718  * Write to the process' data area.
719  */
720 
721 public dwrite(buff, addr, nbytes)
722 char *buff;
723 Address addr;
724 int nbytes;
725 {
726     Intfunc *f;
727 
728     if (coredump) {
729 	error("no process to write to");
730     }
731     f = onsyserr(EIO, write_err);
732     badaddr = addr;
733     pio(process, PWRITE, DATASEG, buff, addr, nbytes);
734     onsyserr(EIO, f);
735 }
736 
737 /*
738  * Trap for errors in reading or writing to a process.
739  * The current approach is to "ignore" read errors and complain
740  * bitterly about write errors.
741  */
742 
743 private read_err()
744 {
745     /*
746      * Ignore.
747      */
748 }
749 
750 private write_err()
751 {
752     error("can't write to process (address 0x%x)", badaddr);
753 }
754 
755 /*
756  * Ptrace interface.
757  */
758 
759 /*
760  * This magic macro enables us to look at the process' registers
761  * in its user structure.
762  */
763 
764 #define regloc(reg)     (ctob(UPAGES) + ( sizeof(int) * (reg) ))
765 
766 #define WMASK           (~(sizeof(Word) - 1))
767 #define cachehash(addr) ((unsigned) ((addr >> 2) % CSIZE))
768 
769 #define FIRSTSIG        SIGINT
770 #define LASTSIG         SIGQUIT
771 #define ischild(pid)    ((pid) == 0)
772 #define traceme()       ptrace(PT_TRACE_ME, 0, 0, 0)
773 #define setrep(n)       (1 << ((n)-1))
774 #define istraced(p)     (p->sigset&setrep(p->signo))
775 
776 /*
777  * Start up a new process by forking and exec-ing the
778  * given argument list, returning when the process is loaded
779  * and ready to execute.  The PROCESS information (pointed to
780  * by the first argument) is appropriately filled.
781  *
782  * If the given PROCESS structure is associated with an already running
783  * process, we terminate it.
784  */
785 
786 /* VARARGS2 */
787 private pstart(p, argv, infile, outfile)
788 Process p;
789 String argv[];
790 String infile;
791 String outfile;
792 {
793     int status;
794 
795     if (p->pid != 0) {
796 	pterm(p);
797     }
798     psigtrace(p, SIGTRAP, true);
799     p->pid = vfork();
800     if (p->pid == -1) {
801 	panic("can't fork");
802     }
803     if (ischild(p->pid)) {
804 	traceme();
805 	if (infile != nil) {
806 	    infrom(infile);
807 	}
808 	if (outfile != nil) {
809 	    outto(outfile);
810 	}
811 	execv(argv[0], argv);
812 	write(2, "can't exec ", 11);
813 	write(2, argv[0], strlen(argv[0]));
814 	write(2, "\n", 1);
815 	_exit(1);
816     }
817     pwait(p->pid, &status);
818     getinfo(p, status);
819     if (p->status != STOPPED) {
820 	error("program could not begin execution");
821     }
822     ptraced(p->pid);
823 }
824 
825 /*
826  * Terminate a ptrace'd process.
827  */
828 
829 public pterm (p)
830 Process p;
831 {
832     integer status;
833 
834     if (p != nil and p->pid != 0) {
835 	ptrace(PT_KILL, p->pid, 0, 0);
836 	pwait(p->pid, &status);
837 	unptraced(p->pid);
838     }
839 }
840 
841 /*
842  * Continue a stopped process.  The first argument points to a Process
843  * structure.  Before the process is restarted it's user area is modified
844  * according to the values in the structure.  When this routine finishes,
845  * the structure has the new values from the process's user area.
846  *
847  * Pcont terminates when the process stops with a signal pending that
848  * is being traced (via psigtrace), or when the process terminates.
849  */
850 
851 private pcont(p, signo)
852 Process p;
853 int signo;
854 {
855     int s, status;
856 
857     if (p->pid == 0) {
858 	error("program not active");
859     }
860     s = signo;
861     do {
862 	setinfo(p, s);
863 	if (traceexec) {
864 	    printf("!! pcont from 0x%x with signal %d (%d)\n",
865 		p->reg[PROGCTR], s, p->signo);
866 	    fflush(stdout);
867 	}
868 	sigs_off();
869 	if (ptrace(PT_CONTINUE, p->pid, p->reg[PROGCTR], p->signo) < 0) {
870 	    panic("error %d trying to continue process", errno);
871 	}
872 	pwait(p->pid, &status);
873 	sigs_on();
874 	getinfo(p, status);
875 	if (traceexec and not istraced(p)) {
876 	    printf("!! ignored signal %d at 0x%x\n", p->signo, p->reg[PROGCTR]);
877 	    fflush(stdout);
878 	}
879 	s = p->signo;
880     } while (p->status == STOPPED and not istraced(p));
881     if (traceexec) {
882 	printf("!! pcont to 0x%x on signal %d\n", p->reg[PROGCTR], p->signo);
883 	fflush(stdout);
884     }
885 }
886 
887 /*
888  * Single step as best ptrace can.
889  */
890 
891 public pstep(p, signo)
892 Process p;
893 integer signo;
894 {
895     int status;
896 
897     setinfo(p, signo);
898     if (traceexec) {
899 	printf("!! pstep from pc 0x%x with signal %d (%d)\n",
900 	    p->reg[PROGCTR], signo, p->signo);
901 	fflush(stdout);
902     }
903     sigs_off();
904     if (ptrace(PT_STEP, p->pid, p->reg[PROGCTR], p->signo) < 0) {
905 	panic("error %d trying to step process", errno);
906     }
907     pwait(p->pid, &status);
908     sigs_on();
909     getinfo(p, status);
910     if (traceexec) {
911 	printf("!! pstep to pc 0x%x on signal %d\n", p->reg[PROGCTR], p->signo);
912 	fflush(stdout);
913     }
914     if (p->status != STOPPED) {
915 	error("program unexpectedly exited with %d\n", p->exitval);
916     }
917 }
918 
919 /*
920  * Return from execution when the given signal is pending.
921  */
922 
923 public psigtrace(p, sig, sw)
924 Process p;
925 int sig;
926 Boolean sw;
927 {
928     if (sw) {
929 	p->sigset |= setrep(sig);
930     } else {
931 	p->sigset &= ~setrep(sig);
932     }
933 }
934 
935 /*
936  * Don't catch any signals.
937  * Particularly useful when letting a process finish uninhibited.
938  */
939 
940 public unsetsigtraces(p)
941 Process p;
942 {
943     p->sigset = 0;
944 }
945 
946 /*
947  * Turn off attention to signals not being caught.
948  */
949 
950 private Intfunc *sigfunc[NSIG];
951 
952 private sigs_off()
953 {
954     register int i;
955 
956     for (i = FIRSTSIG; i < LASTSIG; i++) {
957 	if (i != SIGKILL) {
958 	    sigfunc[i] = signal(i, SIG_IGN);
959 	}
960     }
961 }
962 
963 /*
964  * Turn back on attention to signals.
965  */
966 
967 private sigs_on()
968 {
969     register int i;
970 
971     for (i = FIRSTSIG; i < LASTSIG; i++) {
972 	if (i != SIGKILL) {
973 	    signal(i, sigfunc[i]);
974 	}
975     }
976 }
977 
978 /*
979  * Get process information from user area.
980  */
981 
982 private int rloc[] ={
983     R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC
984 };
985 
986 private getinfo(p, status)
987 register Process p;
988 register int status;
989 {
990     register int i;
991     Address addr;
992 
993     p->signo = (status&0177);
994     p->exitval = ((status >> 8)&0377);
995     if (p->signo != STOPPED) {
996 	p->status = FINISHED;
997 	p->pid = 0;
998 	p->reg[PROGCTR] = 0;
999     } else {
1000 	p->status = p->signo;
1001 	p->signo = p->exitval;
1002 	p->sigcode = ptrace(PT_READ_U, p->pid, &((struct user *)0)->u_code, 0);
1003 	p->exitval = 0;
1004 	p->mask = ptrace(PT_READ_U, p->pid, regloc(PS), 0);
1005 	for (i = 0; i < NREG; i++) {
1006 	    p->reg[i] = ptrace(PT_READ_U, p->pid, regloc(rloc[i]), 0);
1007 	    p->oreg[i] = p->reg[i];
1008 	}
1009 	savetty(stdout, &(p->ttyinfo));
1010 	addr = (Address) &(((struct user *) 0)->u_signal[p->signo]);
1011 	p->sigstatus = (Address) ptrace(PT_READ_U, p->pid, addr, 0);
1012     }
1013 }
1014 
1015 /*
1016  * Set process's user area information from given process structure.
1017  */
1018 
1019 private setinfo(p, signo)
1020 register Process p;
1021 int signo;
1022 {
1023     register int i;
1024     register int r;
1025 
1026     if (signo == DEFSIG) {
1027 	if (istraced(p) and (p->sigstatus == 0 or p->sigstatus == 1)) {
1028 	    p->signo = 0;
1029 	}
1030     } else {
1031 	p->signo = signo;
1032     }
1033     for (i = 0; i < NREG; i++) {
1034 	if ((r = p->reg[i]) != p->oreg[i]) {
1035 	    ptrace(PT_WRITE_U, p->pid, regloc(rloc[i]), r);
1036 	}
1037     }
1038     restoretty(stdout, &(p->ttyinfo));
1039 }
1040 
1041 /*
1042  * Return the address associated with the current signal.
1043  * (Plus two since the address points to the beginning of a procedure).
1044  */
1045 
1046 public Address usignal (p)
1047 Process p;
1048 {
1049     Address r;
1050 
1051     r = p->sigstatus;
1052     if (r != 0 and r != 1) {
1053 	r += 2;
1054     }
1055     return r;
1056 }
1057 
1058 /*
1059  * Structure for reading and writing by words, but dealing with bytes.
1060  */
1061 
1062 typedef union {
1063     Word pword;
1064     Byte pbyte[sizeof(Word)];
1065 } Pword;
1066 
1067 /*
1068  * Read (write) from (to) the process' address space.
1069  * We must deal with ptrace's inability to look anywhere other
1070  * than at a word boundary.
1071  */
1072 
1073 private Word fetch();
1074 private store();
1075 
1076 private pio(p, op, seg, buff, addr, nbytes)
1077 Process p;
1078 PioOp op;
1079 PioSeg seg;
1080 char *buff;
1081 Address addr;
1082 int nbytes;
1083 {
1084     register int i;
1085     register Address newaddr;
1086     register char *cp;
1087     char *bufend;
1088     Pword w;
1089     Address wordaddr;
1090     int byteoff;
1091 
1092     if (p->status != STOPPED) {
1093 	error("program is not active");
1094     }
1095     cp = buff;
1096     newaddr = addr;
1097     wordaddr = (newaddr&WMASK);
1098     if (wordaddr != newaddr) {
1099 	w.pword = fetch(p, seg, wordaddr);
1100 	for (i = newaddr - wordaddr; i < sizeof(Word) and nbytes > 0; i++) {
1101 	    if (op == PREAD) {
1102 		*cp++ = w.pbyte[i];
1103 	    } else {
1104 		w.pbyte[i] = *cp++;
1105 	    }
1106 	    nbytes--;
1107 	}
1108 	if (op == PWRITE) {
1109 	    store(p, seg, wordaddr, w.pword);
1110 	}
1111 	newaddr = wordaddr + sizeof(Word);
1112     }
1113     byteoff = (nbytes&(~WMASK));
1114     nbytes -= byteoff;
1115     bufend = cp + nbytes;
1116     while (cp < bufend) {
1117 	if (op == PREAD) {
1118 	    *((Word *) cp) = fetch(p, seg, newaddr);
1119 	} else {
1120 	    store(p, seg, newaddr, *((Word *) cp));
1121 	}
1122 	cp += sizeof(Word);
1123 	newaddr += sizeof(Word);
1124     }
1125     if (byteoff > 0) {
1126 	w.pword = fetch(p, seg, newaddr);
1127 	for (i = 0; i < byteoff; i++) {
1128 	    if (op == PREAD) {
1129 		*cp++ = w.pbyte[i];
1130 	    } else {
1131 		w.pbyte[i] = *cp++;
1132 	    }
1133 	}
1134 	if (op == PWRITE) {
1135 	    store(p, seg, newaddr, w.pword);
1136 	}
1137     }
1138 }
1139 
1140 /*
1141  * Get a word from a process at the given address.
1142  * The address is assumed to be on a word boundary.
1143  *
1144  * A simple cache scheme is used to avoid redundant ptrace calls
1145  * to the instruction space since it is assumed to be pure.
1146  *
1147  * It is necessary to use a write-through scheme so that
1148  * breakpoints right next to each other don't interfere.
1149  */
1150 
1151 private Integer nfetchs, nreads, nwrites;
1152 
1153 private Word fetch(p, seg, addr)
1154 Process p;
1155 PioSeg seg;
1156 register int addr;
1157 {
1158     register CacheWord *wp;
1159     register Word w;
1160 
1161     switch (seg) {
1162 	case TEXTSEG:
1163 	    ++nfetchs;
1164 	    wp = &p->word[cachehash(addr)];
1165 	    if (addr == 0 or wp->addr != addr) {
1166 		++nreads;
1167 		w = ptrace(PT_READ_I, p->pid, addr, 0);
1168 		wp->addr = addr;
1169 		wp->val = w;
1170 	    } else {
1171 		w = wp->val;
1172 	    }
1173 	    break;
1174 
1175 	case DATASEG:
1176 	    w = ptrace(PT_READ_D, p->pid, addr, 0);
1177 	    break;
1178 
1179 	default:
1180 	    panic("fetch: bad seg %d", seg);
1181 	    /* NOTREACHED */
1182     }
1183     return w;
1184 }
1185 
1186 /*
1187  * Put a word into the process' address space at the given address.
1188  * The address is assumed to be on a word boundary.
1189  */
1190 
1191 private store(p, seg, addr, data)
1192 Process p;
1193 PioSeg seg;
1194 int addr;
1195 Word data;
1196 {
1197     register CacheWord *wp;
1198 
1199     switch (seg) {
1200 	case TEXTSEG:
1201 	    ++nwrites;
1202 	    wp = &p->word[cachehash(addr)];
1203 	    wp->addr = addr;
1204 	    wp->val = data;
1205 	    ptrace(PT_WRITE_I, p->pid, addr, data);
1206 	    break;
1207 
1208 	case DATASEG:
1209 	    ptrace(PT_WRITE_D, p->pid, addr, data);
1210 	    break;
1211 
1212 	default:
1213 	    panic("store: bad seg %d", seg);
1214 	    /* NOTREACHED */
1215     }
1216 }
1217 
1218 public printptraceinfo()
1219 {
1220     printf("%d fetchs, %d reads, %d writes\n", nfetchs, nreads, nwrites);
1221 }
1222 
1223 /*
1224  * Redirect input.
1225  * Assuming this is called from a child, we should be careful to avoid
1226  * (possibly) shared standard I/O buffers.
1227  */
1228 
1229 private infrom (filename)
1230 String filename;
1231 {
1232     Fileid in;
1233 
1234     in = open(filename, 0);
1235     if (in == -1) {
1236 	write(2, "can't read ", 11);
1237 	write(2, filename, strlen(filename));
1238 	write(2, "\n", 1);
1239 	_exit(1);
1240     }
1241     fswap(0, in);
1242 }
1243 
1244 /*
1245  * Redirect standard output.
1246  * Same assumptions as for "infrom" above.
1247  */
1248 
1249 private outto (filename)
1250 String filename;
1251 {
1252     Fileid out;
1253 
1254     out = creat(filename, 0666);
1255     if (out == -1) {
1256 	write(2, "can't write ", 12);
1257 	write(2, filename, strlen(filename));
1258 	write(2, "\n", 1);
1259 	_exit(1);
1260     }
1261     fswap(1, out);
1262 }
1263 
1264 /*
1265  * Swap file numbers, useful for redirecting standard input or output.
1266  */
1267 
1268 private fswap(oldfd, newfd)
1269 Fileid oldfd;
1270 Fileid newfd;
1271 {
1272     if (oldfd != newfd) {
1273 	close(oldfd);
1274 	dup(newfd);
1275 	close(newfd);
1276     }
1277 }
1278 
1279 #define	bit(i)		(1 << ((i)-1))
1280 /*
1281  * Signal manipulation routines.
1282  */
1283 static String signames[NSIG] = {
1284 	0,
1285 	"HUP",
1286 	"INT",
1287 	"QUIT",
1288 	"ILL",
1289 	"TRAP",
1290 	"IOT",
1291 	"EMT",
1292 	"FPE",
1293 	"KILL",
1294 	"BUS",
1295 	"SEGV",
1296 	"SYS",
1297 	"PIPE",
1298 	"ALRM",
1299 	"TERM",
1300 	0,
1301 	"STOP",
1302 	"TSTP",
1303 	"CONT",
1304 	"CHLD",
1305 	"TTIN",
1306 	"TTOU",
1307 	"TINT",
1308 	"XCPU",
1309 	"XFSZ",
1310 };
1311 
1312 /*
1313  * Map a signal name to a number.
1314  */
1315 public signalname(s)
1316 String s;
1317 {
1318 	register String *p;
1319 
1320 	if (strneq(s, "SIG", 3))
1321 	    s += 3;
1322 	for (p = signames; p < &signames[NSIG]; p++)
1323 		if (*p && streq(*p, s))
1324 			return (p - signames);
1325 	error("%s: Unknown signal.", s);
1326 }
1327 
1328 /*
1329  * Print all signals being ignored by the
1330  * debugger.  These signals are auotmatically
1331  * passed on to the debugged process.
1332  */
1333 public printsigsignored(p)
1334 Process p;
1335 {
1336 
1337     printsigs(~p->sigset);
1338 }
1339 
1340 /*
1341  * Print all signals being intercepted by
1342  * the debugger for the specified process.
1343  */
1344 public printsigscaught(p)
1345 Process p;
1346 {
1347 
1348     printsigs(p->sigset);
1349 }
1350 
1351 private printsigs(vec)
1352 register Integer vec;
1353 {
1354     register Integer s;
1355     String sep = "";
1356 
1357     for (s = 1; s < NSIG; s++)
1358 	if (vec & bit(s) && signames[s]) {
1359 	    printf("%s%s", sep, signames[s]);
1360 	    sep = " ";
1361 	}
1362     if (*sep != '\0') {
1363 	putchar('\n');
1364 	fflush(stdout);
1365     }
1366 }
1367