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