1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)resume.c 1.7 05/19/82";
4 
5 /*
6  * resume execution, first setting appropriate registers
7  */
8 
9 #include "defs.h"
10 #include <signal.h>
11 #include "process.h"
12 #include "machine.h"
13 #include "main.h"
14 #include "process.rep"
15 #include "runtime/frame.rep"
16 
17 #   if (isvaxpx)
18 #       include "machine/pxerrors.h"
19 #       include "pxinfo.h"
20 #   endif
21 
22 LOCAL ADDRESS fetchpc();
23 
24 /*
25  * If we hit a breakpoint, px's pc points at a halt instruction,
26  * this must be avoided when restarting.
27  */
28 
29 resume()
30 {
31     register PROCESS *p;
32     int oldsigno;
33 
34     p = process;
35     do {
36 	if (option('e')) {
37 	    printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc);
38 	    fflush(stdout);
39 	}
40 	pcont(p);
41 #       if (isvaxpx)
42 	    if (p->status == STOPPED) {
43 		if (isbperr()) {
44 		    pc = p->reg[11];
45 		} else {
46 		    dread(&pcframe, PCADDRP, sizeof(pcframe));
47 		    pcframe++;
48 		    pc = fetchpc(pcframe);
49 		}
50 		pc -= (sizeof(char) + ENDOFF);
51 	    }
52 #       else
53 	    pc = process->pc;
54 #       endif
55 	if (option('e')) {
56 	    printf("execution stops at pc 0x%x, lc %d on sig %d\n",
57 		process->pc, pc, p->signo);
58 	    fflush(stdout);
59 	}
60 	if (p->status == STOPPED) {
61 	    errnum = 0;
62 	}
63     } while (p->signo == SIGCONT);
64 #   if (isvaxpx)
65 	if (option('r') && p->signo != 0) {
66 	    choose();
67 	}
68 	if (isbperr()) {
69 	    p->pc++;
70 	}
71 #   endif
72 }
73 
74 # if (isvaxpx)
75 
76 /*
77  * Find the location in the Pascal object where execution was suspended.
78  *
79  * We basically walk back through the frames looking for saved
80  * register 11's.  Each time we find one, we remember it.  When we reach
81  * the frame associated with the interpreter procedure, the most recently
82  * saved register 11 is the one we want.
83  */
84 
85 typedef struct {
86     int fr_handler;
87     unsigned int fr_psw : 16;   /* saved psw */
88     unsigned int fr_mask : 12;  /* register save mask */
89     unsigned int fr_unused : 1;
90     unsigned int fr_s : 1;      /* call was a calls, not callg */
91     unsigned int fr_spa : 2;    /* stack pointer alignment */
92     unsigned int fr_savap;      /* saved arg pointer */
93     unsigned int fr_savfp;      /* saved frame pointer */
94     int fr_savpc;           /* saved program counter */
95 } Vaxframe;
96 
97 #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0)
98 
99 LOCAL ADDRESS fetchpc(framep)
100 ADDRESS *framep;
101 {
102     register PROCESS *p;
103     Vaxframe vframe;
104     ADDRESS *savfp;
105     ADDRESS r;
106 
107     p = process;
108     r = p->reg[11];
109     if (p->fp == (ADDRESS) framep) {
110 	return r;
111     }
112     savfp = (ADDRESS *) p->fp;
113     dread(&vframe, savfp, sizeof(vframe));
114     while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) {
115 	if (regsaved(vframe, 11)) {
116 	    dread(&r, savfp + 5, sizeof(r));
117 	    r -= sizeof(char);
118 	}
119 	savfp = (ADDRESS *) vframe.fr_savfp;
120 	dread(&vframe, savfp, sizeof(vframe));
121     }
122     if (vframe.fr_savfp == 0) {
123 	panic("resume: can't find interpreter frame 0x%x", framep);
124     }
125     if (regsaved(vframe, 11)) {
126 	dread(&r, savfp + 5, sizeof(r));
127 	r -= sizeof(char);
128     }
129     return(r);
130 }
131 
132 /*
133  * Under the -r option, we offer the opportunity to just get
134  * the px traceback and not actually enter the debugger.
135  *
136  * If the standard input is not a tty but standard error is,
137  * change standard input to be /dev/tty.
138  */
139 
140 LOCAL choose()
141 {
142     register int c;
143 
144     if (!isterm(stdin)) {
145 	if (!isterm(stderr) || freopen("/dev/tty", "r", stdin) == NIL) {
146 	    unsetsigtraces(process);
147 	    pcont(process);
148 	    quit(process->exitval);
149 	    /* NOTREACHED */
150 	}
151     }
152     fprintf(stderr, "\nProgram error");
153     if (errnum != 0) {
154 	fprintf(stderr, " -- %s", pxerrmsg[errnum]);
155     }
156     fprintf(stderr, "\nDo you wish to enter the debugger? ");
157     c = getchar();
158     if (c == 'n') {
159 	unsetsigtraces(process);
160 	pcont(process);
161 	quit(process->exitval);
162     }
163     while (c != '\n' && c != EOF) {
164 	c = getchar();
165     }
166     fprintf(stderr, "\nEntering debugger ...");
167     init();
168     option('r') = FALSE;
169     fprintf(stderr, " type 'help' for help.\n");
170 }
171 
172 # endif
173