1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)resume.c 1.9 02/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 } 183