15508Slinton /* Copyright (c) 1982 Regents of the University of California */ 25508Slinton 3*5875Slinton static char sccsid[] = "@(#)resume.c 1.5 02/17/82"; 45508Slinton 55508Slinton /* 65508Slinton * resume execution, first setting appropriate registers 75508Slinton */ 85508Slinton 95508Slinton #include "defs.h" 105508Slinton #include <signal.h> 115508Slinton #include "process.h" 125508Slinton #include "machine.h" 135508Slinton #include "main.h" 145508Slinton #include "process.rep" 155508Slinton #include "runtime/frame.rep" 165508Slinton 175714Slinton # if (isvaxpx) 185714Slinton # include "machine/pxerrors.h" 195714Slinton # include "pxinfo.h" 205714Slinton # endif 215508Slinton 225508Slinton LOCAL ADDRESS fetchpc(); 235508Slinton 245508Slinton /* 255508Slinton * If we hit a breakpoint, px's pc points at a halt instruction, 265508Slinton * this must be avoided when restarting. 275508Slinton */ 285508Slinton 295508Slinton resume() 305508Slinton { 315714Slinton register PROCESS *p; 325714Slinton int oldsigno; 335508Slinton 345714Slinton p = process; 355714Slinton do { 365714Slinton if (option('e')) { 375714Slinton printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc); 385714Slinton fflush(stdout); 395714Slinton } 405714Slinton pcont(p); 415714Slinton # if (isvaxpx) 425714Slinton if (p->status == STOPPED) { 435508Slinton if (isbperr()) { 445714Slinton pc = p->reg[11]; 455714Slinton } else { 465714Slinton dread(&pcframe, PCADDRP, sizeof(pcframe)); 475714Slinton pcframe++; 485714Slinton pc = fetchpc(pcframe); 495508Slinton } 505714Slinton pc -= (sizeof(char) + ENDOFF); 515714Slinton } 525714Slinton # else 535714Slinton pc = process->pc; 545714Slinton # endif 555714Slinton if (option('e')) { 565714Slinton printf("execution stops at pc 0x%x, lc %d on sig %d\n", 575714Slinton process->pc, pc, p->signo); 585714Slinton fflush(stdout); 595714Slinton } 605714Slinton if (p->status == STOPPED) { 615714Slinton errnum = 0; 625714Slinton } 635714Slinton } while (p->signo == SIGCONT); 645714Slinton # if (isvaxpx) 655714Slinton if (option('r') && p->signo != 0) { 665714Slinton choose(); 675714Slinton } 685714Slinton if (isbperr()) { 695714Slinton p->pc++; 705714Slinton } 715714Slinton # endif 725508Slinton } 735508Slinton 745508Slinton # if (isvaxpx) 755508Slinton 765508Slinton /* 775508Slinton * Find the location in the Pascal object where execution was suspended. 78*5875Slinton * 79*5875Slinton * We basically walk back through the frames looking for saved 80*5875Slinton * register 11's. Each time we find one, we remember it. When we reach 81*5875Slinton * the frame associated with the interpreter procedure, the most recently 82*5875Slinton * saved register 11 is the one we want. 835508Slinton */ 845508Slinton 855508Slinton typedef struct { 865714Slinton int fr_handler; 875714Slinton unsigned int fr_psw : 16; /* saved psw */ 885714Slinton unsigned int fr_mask : 12; /* register save mask */ 895714Slinton unsigned int fr_unused : 1; 905714Slinton unsigned int fr_s : 1; /* call was a calls, not callg */ 915714Slinton unsigned int fr_spa : 2; /* stack pointer alignment */ 925714Slinton unsigned int fr_savap; /* saved arg pointer */ 935714Slinton unsigned int fr_savfp; /* saved frame pointer */ 945714Slinton int fr_savpc; /* saved program counter */ 955508Slinton } Vaxframe; 965508Slinton 97*5875Slinton #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0) 98*5875Slinton 995508Slinton LOCAL ADDRESS fetchpc(framep) 1005508Slinton ADDRESS *framep; 1015508Slinton { 1025714Slinton register PROCESS *p; 1035714Slinton Vaxframe vframe; 1045714Slinton ADDRESS *savfp; 1055714Slinton ADDRESS r; 1065508Slinton 1075714Slinton p = process; 108*5875Slinton r = p->reg[11]; 1095714Slinton if (p->fp == (ADDRESS) framep) { 110*5875Slinton return r; 1115714Slinton } 1125714Slinton savfp = (ADDRESS *) p->fp; 1135714Slinton dread(&vframe, savfp, sizeof(vframe)); 1145714Slinton while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) { 115*5875Slinton if (regsaved(vframe, 11)) { 116*5875Slinton dread(&r, savfp + 5, sizeof(r)); 117*5875Slinton r -= sizeof(char); 118*5875Slinton } 1195714Slinton savfp = (ADDRESS *) vframe.fr_savfp; 1205508Slinton dread(&vframe, savfp, sizeof(vframe)); 1215714Slinton } 1225714Slinton if (vframe.fr_savfp == 0) { 1235714Slinton panic("resume: can't find interpreter frame 0x%x", framep); 1245714Slinton } 125*5875Slinton if (regsaved(vframe, 11)) { 1265714Slinton dread(&r, savfp + 5, sizeof(r)); 1275714Slinton r -= sizeof(char); 1285714Slinton } 1295714Slinton return(r); 1305508Slinton } 1315508Slinton 1325508Slinton /* 1335508Slinton * Under the -r option, we offer the opportunity to just get 1345508Slinton * the px traceback and not actually enter the debugger. 1355508Slinton */ 1365508Slinton 1375508Slinton LOCAL choose() 1385508Slinton { 1395714Slinton register int c; 1405508Slinton 1415714Slinton fprintf(stderr, "\nProgram error"); 1425714Slinton if (errnum != 0) { 1435714Slinton fprintf(stderr, " -- %s", pxerrmsg[errnum]); 1445714Slinton } 1455714Slinton fprintf(stderr, "\nDo you wish to enter the debugger? "); 1465714Slinton c = getchar(); 1475714Slinton if (c == 'n') { 1485714Slinton unsetsigtraces(process); 1495714Slinton pcont(process); 1505714Slinton quit(process->exitval); 1515714Slinton } 1525714Slinton while (c != '\n') { 1535508Slinton c = getchar(); 1545714Slinton } 1555714Slinton fprintf(stderr, "\nEntering debugger ..."); 1565714Slinton init(); 1575714Slinton option('r') = FALSE; 1585714Slinton fprintf(stderr, " type 'help' for help.\n"); 1595508Slinton } 1605508Slinton 1615508Slinton # endif 162