|
|
1.1 root 1: /* Copyright (c) 1982 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)resume.c 1.9 2/14/83";
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: #include "machine/pxerrors.h"
18: #include "pxinfo.h"
19:
20: #ifdef vax
21: LOCAL ADDRESS fetchpc();
22: #endif
23:
24: LOCAL ADDRESS *pcaddr;
25:
26: /*
27: * Resume execution, set (get) pcode location counter before (after) resuming.
28: */
29:
30: resume()
31: {
32: register PROCESS *p;
33: int oldsigno;
34:
35: p = process;
36: do {
37: if (option('e')) {
38: printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc);
39: fflush(stdout);
40: }
41: pcont(p);
42: # ifdef sun
43: if (pcaddr == 0) {
44: dread(&pcaddr, PCADDRP, sizeof(pcaddr));
45: }
46: dread(&pc, pcaddr, sizeof(pc));
47: # else ifdef vax
48: if (p->status == STOPPED) {
49: if (isbperr()) {
50: pc = p->reg[11];
51: } else {
52: dread(&pcframe, PCADDRP, sizeof(pcframe));
53: pcframe++;
54: pc = fetchpc(pcframe);
55: }
56: pc -= (sizeof(char) + ENDOFF);
57: }
58: # endif
59: if (option('e')) {
60: printf("execution stops at pc 0x%x, lc %d on sig %d\n",
61: process->pc, pc, p->signo);
62: fflush(stdout);
63: }
64: if (p->status == STOPPED) {
65: errnum = 0;
66: }
67: } while (p->signo == SIGCONT);
68: if (option('r') && p->signo != 0) {
69: choose();
70: }
71:
72: /*
73: * If px implements a breakpoint by executing a halt instruction
74: * the real pc must be incremented to skip over it.
75: *
76: * Currently, px sends itself a signal so no incrementing is needed.
77: *
78: if (isbperr()) {
79: p->pc++;
80: }
81: */
82: }
83:
84: #ifdef vax
85:
86: /*
87: * Find the location in the Pascal object where execution was suspended.
88: *
89: * We basically walk back through the frames looking for saved
90: * register 11's. Each time we find one, we remember it. When we reach
91: * the frame associated with the interpreter procedure, the most recently
92: * saved register 11 is the one we want.
93: */
94:
95: typedef struct {
96: int fr_handler;
97: unsigned int fr_psw : 16; /* saved psw */
98: unsigned int fr_mask : 12; /* register save mask */
99: unsigned int fr_unused : 1;
100: unsigned int fr_s : 1; /* call was a calls, not callg */
101: unsigned int fr_spa : 2; /* stack pointer alignment */
102: unsigned int fr_savap; /* saved arg pointer */
103: unsigned int fr_savfp; /* saved frame pointer */
104: int fr_savpc; /* saved program counter */
105: } Vaxframe;
106:
107: #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0)
108:
109: LOCAL ADDRESS fetchpc(framep)
110: ADDRESS *framep;
111: {
112: register PROCESS *p;
113: Vaxframe vframe;
114: ADDRESS *savfp;
115: ADDRESS r;
116:
117: p = process;
118: r = p->reg[11];
119: if (p->fp == (ADDRESS) framep) {
120: return r;
121: }
122: savfp = (ADDRESS *) p->fp;
123: dread(&vframe, savfp, sizeof(vframe));
124: while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) {
125: if (regsaved(vframe, 11)) {
126: dread(&r, savfp + 5, sizeof(r));
127: r -= sizeof(char);
128: }
129: savfp = (ADDRESS *) vframe.fr_savfp;
130: dread(&vframe, savfp, sizeof(vframe));
131: }
132: if (vframe.fr_savfp == 0) {
133: panic("resume: can't find interpreter frame 0x%x", framep);
134: }
135: if (regsaved(vframe, 11)) {
136: dread(&r, savfp + 5, sizeof(r));
137: r -= sizeof(char);
138: }
139: return(r);
140: }
141:
142: #endif
143:
144: /*
145: * Under the -r option, we offer the opportunity to just get
146: * the px traceback and not actually enter the debugger.
147: *
148: * If the standard input is not a tty but standard error is,
149: * change standard input to be /dev/tty.
150: */
151:
152: LOCAL choose()
153: {
154: register int c;
155:
156: if (!isterm(stdin)) {
157: if (!isterm(stderr) || freopen("/dev/tty", "r", stdin) == NIL) {
158: unsetsigtraces(process);
159: pcont(process);
160: quit(process->exitval);
161: /* NOTREACHED */
162: }
163: }
164: fprintf(stderr, "\nProgram error");
165: if (errnum != 0) {
166: fprintf(stderr, " -- %s", pxerrmsg[errnum]);
167: }
168: fprintf(stderr, "\nDo you wish to enter the debugger? ");
169: c = getchar();
170: if (c == 'n') {
171: unsetsigtraces(process);
172: pcont(process);
173: quit(process->exitval);
174: }
175: while (c != '\n' && c != EOF) {
176: c = getchar();
177: }
178: fprintf(stderr, "\nEntering debugger ...");
179: init();
180: option('r') = FALSE;
181: fprintf(stderr, " type 'help' for help.\n");
182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.