15508Slinton /* Copyright (c) 1982 Regents of the University of California */
25508Slinton 
3*5714Slinton static char sccsid[] = "@(#)resume.c 1.4 02/07/82";
45508Slinton 
55508Slinton /*
65508Slinton  * resume execution, first setting appropriate registers
75508Slinton  */
85508Slinton 
95508Slinton #include "defs.h"
105508Slinton #include <signal.h>
115508Slinton #include "process.h"
125508Slinton #include "machine.h"
135508Slinton #include "main.h"
145508Slinton #include "process.rep"
155508Slinton #include "runtime/frame.rep"
165508Slinton 
17*5714Slinton #   if (isvaxpx)
18*5714Slinton #       include "machine/pxerrors.h"
19*5714Slinton #       include "pxinfo.h"
20*5714Slinton #   endif
215508Slinton 
225508Slinton LOCAL ADDRESS fetchpc();
235508Slinton 
245508Slinton /*
255508Slinton  * If we hit a breakpoint, px's pc points at a halt instruction,
265508Slinton  * this must be avoided when restarting.
275508Slinton  */
285508Slinton 
295508Slinton resume()
305508Slinton {
31*5714Slinton     register PROCESS *p;
32*5714Slinton     int oldsigno;
335508Slinton 
34*5714Slinton     p = process;
35*5714Slinton     do {
36*5714Slinton 	if (option('e')) {
37*5714Slinton 	    printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc);
38*5714Slinton 	    fflush(stdout);
39*5714Slinton 	}
40*5714Slinton 	pcont(p);
41*5714Slinton #       if (isvaxpx)
42*5714Slinton 	    if (p->status == STOPPED) {
435508Slinton 		if (isbperr()) {
44*5714Slinton 		    pc = p->reg[11];
45*5714Slinton 		} else {
46*5714Slinton 		    dread(&pcframe, PCADDRP, sizeof(pcframe));
47*5714Slinton 		    pcframe++;
48*5714Slinton 		    pc = fetchpc(pcframe);
495508Slinton 		}
50*5714Slinton 		pc -= (sizeof(char) + ENDOFF);
51*5714Slinton 	    }
52*5714Slinton #       else
53*5714Slinton 	    pc = process->pc;
54*5714Slinton #       endif
55*5714Slinton 	if (option('e')) {
56*5714Slinton 	    printf("execution stops at pc 0x%x, lc %d on sig %d\n",
57*5714Slinton 		process->pc, pc, p->signo);
58*5714Slinton 	    fflush(stdout);
59*5714Slinton 	}
60*5714Slinton 	if (p->status == STOPPED) {
61*5714Slinton 	    errnum = 0;
62*5714Slinton 	}
63*5714Slinton     } while (p->signo == SIGCONT);
64*5714Slinton #   if (isvaxpx)
65*5714Slinton 	if (option('r') && p->signo != 0) {
66*5714Slinton 	    choose();
67*5714Slinton 	}
68*5714Slinton 	if (isbperr()) {
69*5714Slinton 	    p->pc++;
70*5714Slinton 	}
71*5714Slinton #   endif
725508Slinton }
735508Slinton 
745508Slinton # if (isvaxpx)
755508Slinton 
765508Slinton /*
775508Slinton  * Find the location in the Pascal object where execution was suspended.
785508Slinton  */
795508Slinton 
805508Slinton typedef struct {
81*5714Slinton     int fr_handler;
82*5714Slinton     unsigned int fr_psw : 16;   /* saved psw */
83*5714Slinton     unsigned int fr_mask : 12;  /* register save mask */
84*5714Slinton     unsigned int fr_unused : 1;
85*5714Slinton     unsigned int fr_s : 1;      /* call was a calls, not callg */
86*5714Slinton     unsigned int fr_spa : 2;    /* stack pointer alignment */
87*5714Slinton     unsigned int fr_savap;      /* saved arg pointer */
88*5714Slinton     unsigned int fr_savfp;      /* saved frame pointer */
89*5714Slinton     int fr_savpc;           /* saved program counter */
905508Slinton } Vaxframe;
915508Slinton 
925508Slinton LOCAL ADDRESS fetchpc(framep)
935508Slinton ADDRESS *framep;
945508Slinton {
95*5714Slinton     register PROCESS *p;
96*5714Slinton     Vaxframe vframe;
97*5714Slinton     ADDRESS *savfp;
98*5714Slinton     ADDRESS r;
995508Slinton 
100*5714Slinton     p = process;
101*5714Slinton     if (p->fp == (ADDRESS) framep) {
102*5714Slinton 	return(p->reg[11]);
103*5714Slinton     }
104*5714Slinton     savfp = (ADDRESS *) p->fp;
105*5714Slinton     dread(&vframe, savfp, sizeof(vframe));
106*5714Slinton     while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) {
107*5714Slinton 	savfp = (ADDRESS *) vframe.fr_savfp;
1085508Slinton 	dread(&vframe, savfp, sizeof(vframe));
109*5714Slinton     }
110*5714Slinton     if (vframe.fr_savfp == 0) {
111*5714Slinton 	panic("resume: can't find interpreter frame 0x%x", framep);
112*5714Slinton     }
113*5714Slinton     if (vframe.fr_mask == 0) {
114*5714Slinton 	r = p->reg[11];
115*5714Slinton     } else {
116*5714Slinton 	dread(&r, savfp + 5, sizeof(r));
117*5714Slinton 	r -= sizeof(char);
118*5714Slinton     }
119*5714Slinton     return(r);
1205508Slinton }
1215508Slinton 
1225508Slinton /*
1235508Slinton  * Under the -r option, we offer the opportunity to just get
1245508Slinton  * the px traceback and not actually enter the debugger.
1255508Slinton  */
1265508Slinton 
1275508Slinton LOCAL choose()
1285508Slinton {
129*5714Slinton     register int c;
1305508Slinton 
131*5714Slinton     fprintf(stderr, "\nProgram error");
132*5714Slinton     if (errnum != 0) {
133*5714Slinton 	fprintf(stderr, " -- %s", pxerrmsg[errnum]);
134*5714Slinton     }
135*5714Slinton     fprintf(stderr, "\nDo you wish to enter the debugger? ");
136*5714Slinton     c = getchar();
137*5714Slinton     if (c == 'n') {
138*5714Slinton 	unsetsigtraces(process);
139*5714Slinton 	pcont(process);
140*5714Slinton 	quit(process->exitval);
141*5714Slinton     }
142*5714Slinton     while (c != '\n') {
1435508Slinton 	c = getchar();
144*5714Slinton     }
145*5714Slinton     fprintf(stderr, "\nEntering debugger ...");
146*5714Slinton     init();
147*5714Slinton     option('r') = FALSE;
148*5714Slinton     fprintf(stderr, " type 'help' for help.\n");
1495508Slinton }
1505508Slinton 
1515508Slinton # endif
152