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