Commit | Line | Data |
---|---|---|
4a4056d7 ML |
1 | /* Copyright (c) 1982 Regents of the University of California */ |
2 | ||
7354fb10 | 3 | static char sccsid[] = "@(#)resume.c 1.2 %G%"; |
4a4056d7 ML |
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 | } | |
7354fb10 | 79 | if (option('r') && oldsigno != 0) { |
4a4056d7 ML |
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 |