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