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