|
|
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.