1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)resume.c 1.3 02/02/82"; 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 LOCAL ADDRESS fetchpc(); 23 24 /* 25 * If we hit a breakpoint, px's pc points at a halt instruction, 26 * this must be avoided when restarting. 27 */ 28 29 resume() 30 { 31 register PROCESS *p; 32 int oldsigno; 33 34 p = process; 35 do { 36 if (option('e')) { 37 printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc); 38 fflush(stdout); 39 } 40 pcont(p); 41 # if (isvaxpx) 42 if (p->status == STOPPED) { 43 if (isbperr()) { 44 pc = p->reg[11]; 45 } else { 46 dread(&pcframe, PCADDRP, sizeof(pcframe)); 47 pcframe++; 48 pc = fetchpc(pcframe); 49 } 50 pc -= (sizeof(char) + ENDOFF); 51 } 52 # else 53 pc = process->pc; 54 # endif 55 if (option('e')) { 56 printf("execution stops at pc 0x%x, lc %d on sig %d\n", 57 process->pc, pc, p->signo); 58 fflush(stdout); 59 } 60 if (p->status == STOPPED) { 61 errnum = 0; 62 } 63 } while (p->signo == SIGCONT); 64 # if (isvaxpx) 65 oldsigno = p->signo; 66 switch (p->signo) { 67 case SIGFPE: 68 errnum = EOVERFLOW; 69 p->signo = ESIGNAL; 70 break; 71 72 case SIGSEGV: 73 errnum = ESTKOVER; 74 p->signo = ESIGNAL; 75 break; 76 } 77 if (option('r') && oldsigno != 0) { 78 p->signo = oldsigno; 79 choose(); 80 p->signo = ESIGNAL; 81 } 82 if (isbperr()) { 83 p->pc++; 84 } 85 # endif 86 } 87 88 # if (isvaxpx) 89 90 /* 91 * Find the location in the Pascal object where execution was suspended. 92 */ 93 94 typedef struct { 95 int fr_handler; 96 unsigned int fr_psw : 16; /* saved psw */ 97 unsigned int fr_mask : 12; /* register save mask */ 98 unsigned int fr_unused : 1; 99 unsigned int fr_s : 1; /* call was a calls, not callg */ 100 unsigned int fr_spa : 2; /* stack pointer alignment */ 101 unsigned int fr_savap; /* saved arg pointer */ 102 unsigned int fr_savfp; /* saved frame pointer */ 103 int fr_savpc; /* saved program counter */ 104 } Vaxframe; 105 106 LOCAL ADDRESS fetchpc(framep) 107 ADDRESS *framep; 108 { 109 register PROCESS *p; 110 Vaxframe vframe; 111 ADDRESS *savfp; 112 ADDRESS r; 113 114 p = process; 115 if (p->fp == (ADDRESS) framep) { 116 return(p->reg[11]); 117 } 118 savfp = (ADDRESS *) p->fp; 119 dread(&vframe, savfp, sizeof(vframe)); 120 while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) { 121 savfp = (ADDRESS *) vframe.fr_savfp; 122 dread(&vframe, savfp, sizeof(vframe)); 123 } 124 if (vframe.fr_savfp == 0) { 125 panic("resume: can't find interpreter frame 0x%x", framep); 126 } 127 if (vframe.fr_mask == 0) { 128 r = p->reg[11]; 129 } else { 130 dread(&r, savfp + 5, sizeof(r)); 131 r -= sizeof(char); 132 } 133 return(r); 134 } 135 136 /* 137 * Under the -r option, we offer the opportunity to just get 138 * the px traceback and not actually enter the debugger. 139 */ 140 141 LOCAL choose() 142 { 143 register int c; 144 145 fprintf(stderr, "\nProgram error"); 146 if (errnum != 0) { 147 fprintf(stderr, " -- %s", pxerrmsg[errnum]); 148 } 149 fprintf(stderr, "\nDo you wish to enter the debugger? "); 150 c = getchar(); 151 if (c == 'n') { 152 unsetsigtraces(process); 153 pcont(process); 154 quit(process->exitval); 155 } 156 while (c != '\n') { 157 c = getchar(); 158 } 159 fprintf(stderr, "\nEntering debugger ..."); 160 init(); 161 option('r') = FALSE; 162 fprintf(stderr, " type 'help' for help.\n"); 163 } 164 165 # endif 166