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