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