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) 06/06/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 } 188