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