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