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