15508Slinton /* Copyright (c) 1982 Regents of the University of California */ 25508Slinton 3*10766Slinton static char sccsid[] = "@(#)resume.c 1.8 02/08/83"; 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 22*10766Slinton #ifdef vax 235508Slinton LOCAL ADDRESS fetchpc(); 24*10766Slinton #endif 255508Slinton 26*10766Slinton LOCAL ADDRESS *pcaddr; 27*10766Slinton 285508Slinton /* 29*10766Slinton * Resume execution, set (get) pcode location counter before (after) resuming. 305508Slinton */ 315508Slinton 325508Slinton resume() 335508Slinton { 345714Slinton register PROCESS *p; 355714Slinton int oldsigno; 365508Slinton 375714Slinton p = process; 385714Slinton do { 395714Slinton if (option('e')) { 405714Slinton printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc); 415714Slinton fflush(stdout); 425714Slinton } 435714Slinton pcont(p); 445714Slinton # if (isvaxpx) 45*10766Slinton # ifdef sun 46*10766Slinton if (pcaddr == 0) { 47*10766Slinton dread(&pcaddr, PCADDRP, sizeof(pcaddr)); 485508Slinton } 49*10766Slinton dread(&pc, pcaddr, sizeof(pc)); 50*10766Slinton # else ifdef vax 51*10766Slinton if (p->status == STOPPED) { 52*10766Slinton if (isbperr()) { 53*10766Slinton pc = p->reg[11]; 54*10766Slinton } else { 55*10766Slinton dread(&pcframe, PCADDRP, sizeof(pcframe)); 56*10766Slinton pcframe++; 57*10766Slinton pc = fetchpc(pcframe); 58*10766Slinton } 59*10766Slinton pc -= (sizeof(char) + ENDOFF); 60*10766Slinton } 61*10766Slinton # endif 62*10766Slinton # else /* compiled code */ 635714Slinton pc = process->pc; 645714Slinton # endif 655714Slinton if (option('e')) { 665714Slinton printf("execution stops at pc 0x%x, lc %d on sig %d\n", 675714Slinton process->pc, pc, p->signo); 685714Slinton fflush(stdout); 695714Slinton } 705714Slinton if (p->status == STOPPED) { 715714Slinton errnum = 0; 725714Slinton } 735714Slinton } while (p->signo == SIGCONT); 745714Slinton # if (isvaxpx) 755714Slinton if (option('r') && p->signo != 0) { 765714Slinton choose(); 775714Slinton } 78*10766Slinton 79*10766Slinton /* 80*10766Slinton * If px implements a breakpoint by executing a halt instruction 81*10766Slinton * (which is true on the VAX), the real pc must be incremented to 82*10766Slinton * skip over it. On other machines (such as SUNs), px sends itself 83*10766Slinton * a signal and no incrementing is needed. 84*10766Slinton */ 85*10766Slinton # ifdef vax 86*10766Slinton if (isbperr()) { 87*10766Slinton p->pc++; 88*10766Slinton } 89*10766Slinton # endif 905714Slinton # endif 915508Slinton } 925508Slinton 935508Slinton # if (isvaxpx) 94*10766Slinton # ifdef vax 955508Slinton 965508Slinton /* 975508Slinton * Find the location in the Pascal object where execution was suspended. 985875Slinton * 995875Slinton * We basically walk back through the frames looking for saved 1005875Slinton * register 11's. Each time we find one, we remember it. When we reach 1015875Slinton * the frame associated with the interpreter procedure, the most recently 1025875Slinton * saved register 11 is the one we want. 1035508Slinton */ 1045508Slinton 1055508Slinton typedef struct { 1065714Slinton int fr_handler; 1075714Slinton unsigned int fr_psw : 16; /* saved psw */ 1085714Slinton unsigned int fr_mask : 12; /* register save mask */ 1095714Slinton unsigned int fr_unused : 1; 1105714Slinton unsigned int fr_s : 1; /* call was a calls, not callg */ 1115714Slinton unsigned int fr_spa : 2; /* stack pointer alignment */ 1125714Slinton unsigned int fr_savap; /* saved arg pointer */ 1135714Slinton unsigned int fr_savfp; /* saved frame pointer */ 1145714Slinton int fr_savpc; /* saved program counter */ 1155508Slinton } Vaxframe; 1165508Slinton 1175875Slinton #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0) 1185875Slinton 1195508Slinton LOCAL ADDRESS fetchpc(framep) 1205508Slinton ADDRESS *framep; 1215508Slinton { 1225714Slinton register PROCESS *p; 1235714Slinton Vaxframe vframe; 1245714Slinton ADDRESS *savfp; 1255714Slinton ADDRESS r; 1265508Slinton 1275714Slinton p = process; 1285875Slinton r = p->reg[11]; 1295714Slinton if (p->fp == (ADDRESS) framep) { 1305875Slinton return r; 1315714Slinton } 1325714Slinton savfp = (ADDRESS *) p->fp; 1335714Slinton dread(&vframe, savfp, sizeof(vframe)); 1345714Slinton while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) { 1355875Slinton if (regsaved(vframe, 11)) { 1365875Slinton dread(&r, savfp + 5, sizeof(r)); 1375875Slinton r -= sizeof(char); 1385875Slinton } 1395714Slinton savfp = (ADDRESS *) vframe.fr_savfp; 1405508Slinton dread(&vframe, savfp, sizeof(vframe)); 1415714Slinton } 1425714Slinton if (vframe.fr_savfp == 0) { 1435714Slinton panic("resume: can't find interpreter frame 0x%x", framep); 1445714Slinton } 1455875Slinton if (regsaved(vframe, 11)) { 1465714Slinton dread(&r, savfp + 5, sizeof(r)); 1475714Slinton r -= sizeof(char); 1485714Slinton } 1495714Slinton return(r); 1505508Slinton } 1515508Slinton 152*10766Slinton # endif 153*10766Slinton 1545508Slinton /* 1555508Slinton * Under the -r option, we offer the opportunity to just get 1565508Slinton * the px traceback and not actually enter the debugger. 1576074Slinton * 1586074Slinton * If the standard input is not a tty but standard error is, 1596074Slinton * change standard input to be /dev/tty. 1605508Slinton */ 1615508Slinton 1625508Slinton LOCAL choose() 1635508Slinton { 1645714Slinton register int c; 1655508Slinton 1666873Slinton if (!isterm(stdin)) { 1676873Slinton if (!isterm(stderr) || freopen("/dev/tty", "r", stdin) == NIL) { 1686074Slinton unsetsigtraces(process); 1696074Slinton pcont(process); 1706074Slinton quit(process->exitval); 1716074Slinton /* NOTREACHED */ 1726074Slinton } 1736074Slinton } 1745714Slinton fprintf(stderr, "\nProgram error"); 1755714Slinton if (errnum != 0) { 1765714Slinton fprintf(stderr, " -- %s", pxerrmsg[errnum]); 1775714Slinton } 1785714Slinton fprintf(stderr, "\nDo you wish to enter the debugger? "); 1795714Slinton c = getchar(); 1805714Slinton if (c == 'n') { 1815714Slinton unsetsigtraces(process); 1825714Slinton pcont(process); 1835714Slinton quit(process->exitval); 1845714Slinton } 1856074Slinton while (c != '\n' && c != EOF) { 1865508Slinton c = getchar(); 1875714Slinton } 1885714Slinton fprintf(stderr, "\nEntering debugger ..."); 1895714Slinton init(); 1905714Slinton option('r') = FALSE; 1915714Slinton fprintf(stderr, " type 'help' for help.\n"); 1925508Slinton } 1935508Slinton 1945508Slinton # endif 195