1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)resume.c 1.4 02/07/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 
80 typedef struct {
81     int fr_handler;
82     unsigned int fr_psw : 16;   /* saved psw */
83     unsigned int fr_mask : 12;  /* register save mask */
84     unsigned int fr_unused : 1;
85     unsigned int fr_s : 1;      /* call was a calls, not callg */
86     unsigned int fr_spa : 2;    /* stack pointer alignment */
87     unsigned int fr_savap;      /* saved arg pointer */
88     unsigned int fr_savfp;      /* saved frame pointer */
89     int fr_savpc;           /* saved program counter */
90 } Vaxframe;
91 
92 LOCAL ADDRESS fetchpc(framep)
93 ADDRESS *framep;
94 {
95     register PROCESS *p;
96     Vaxframe vframe;
97     ADDRESS *savfp;
98     ADDRESS r;
99 
100     p = process;
101     if (p->fp == (ADDRESS) framep) {
102 	return(p->reg[11]);
103     }
104     savfp = (ADDRESS *) p->fp;
105     dread(&vframe, savfp, sizeof(vframe));
106     while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) {
107 	savfp = (ADDRESS *) vframe.fr_savfp;
108 	dread(&vframe, savfp, sizeof(vframe));
109     }
110     if (vframe.fr_savfp == 0) {
111 	panic("resume: can't find interpreter frame 0x%x", framep);
112     }
113     if (vframe.fr_mask == 0) {
114 	r = p->reg[11];
115     } else {
116 	dread(&r, savfp + 5, sizeof(r));
117 	r -= sizeof(char);
118     }
119     return(r);
120 }
121 
122 /*
123  * Under the -r option, we offer the opportunity to just get
124  * the px traceback and not actually enter the debugger.
125  */
126 
127 LOCAL choose()
128 {
129     register int c;
130 
131     fprintf(stderr, "\nProgram error");
132     if (errnum != 0) {
133 	fprintf(stderr, " -- %s", pxerrmsg[errnum]);
134     }
135     fprintf(stderr, "\nDo you wish to enter the debugger? ");
136     c = getchar();
137     if (c == 'n') {
138 	unsetsigtraces(process);
139 	pcont(process);
140 	quit(process->exitval);
141     }
142     while (c != '\n') {
143 	c = getchar();
144     }
145     fprintf(stderr, "\nEntering debugger ...");
146     init();
147     option('r') = FALSE;
148     fprintf(stderr, " type 'help' for help.\n");
149 }
150 
151 # endif
152