15508Slinton /* Copyright (c) 1982 Regents of the University of California */ 25508Slinton 3*11061Slinton static char sccsid[] = "@(#)resume.c 1.9 02/14/83"; 45508Slinton 55508Slinton /* 6*11061Slinton * 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 17*11061Slinton #include "machine/pxerrors.h" 18*11061Slinton #include "pxinfo.h" 195508Slinton 2010766Slinton #ifdef vax 21*11061Slinton LOCAL ADDRESS fetchpc(); 2210766Slinton #endif 235508Slinton 2410766Slinton LOCAL ADDRESS *pcaddr; 2510766Slinton 265508Slinton /* 2710766Slinton * Resume execution, set (get) pcode location counter before (after) resuming. 285508Slinton */ 295508Slinton 305508Slinton resume() 315508Slinton { 325714Slinton register PROCESS *p; 335714Slinton int oldsigno; 345508Slinton 355714Slinton p = process; 365714Slinton do { 375714Slinton if (option('e')) { 385714Slinton printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc); 395714Slinton fflush(stdout); 405714Slinton } 415714Slinton pcont(p); 42*11061Slinton # ifdef sun 43*11061Slinton if (pcaddr == 0) { 44*11061Slinton dread(&pcaddr, PCADDRP, sizeof(pcaddr)); 45*11061Slinton } 46*11061Slinton dread(&pc, pcaddr, sizeof(pc)); 47*11061Slinton # else ifdef vax 48*11061Slinton if (p->status == STOPPED) { 49*11061Slinton if (isbperr()) { 50*11061Slinton pc = p->reg[11]; 51*11061Slinton } else { 52*11061Slinton dread(&pcframe, PCADDRP, sizeof(pcframe)); 53*11061Slinton pcframe++; 54*11061Slinton pc = fetchpc(pcframe); 555508Slinton } 56*11061Slinton pc -= (sizeof(char) + ENDOFF); 57*11061Slinton } 585714Slinton # endif 595714Slinton if (option('e')) { 605714Slinton printf("execution stops at pc 0x%x, lc %d on sig %d\n", 615714Slinton process->pc, pc, p->signo); 625714Slinton fflush(stdout); 635714Slinton } 645714Slinton if (p->status == STOPPED) { 655714Slinton errnum = 0; 665714Slinton } 675714Slinton } while (p->signo == SIGCONT); 68*11061Slinton if (option('r') && p->signo != 0) { 69*11061Slinton choose(); 70*11061Slinton } 7110766Slinton 7210766Slinton /* 7310766Slinton * If px implements a breakpoint by executing a halt instruction 74*11061Slinton * the real pc must be incremented to skip over it. 75*11061Slinton * 76*11061Slinton * Currently, px sends itself a signal so no incrementing is needed. 77*11061Slinton * 78*11061Slinton if (isbperr()) { 79*11061Slinton p->pc++; 80*11061Slinton } 8110766Slinton */ 825508Slinton } 835508Slinton 84*11061Slinton #ifdef vax 855508Slinton 865508Slinton /* 875508Slinton * Find the location in the Pascal object where execution was suspended. 885875Slinton * 895875Slinton * We basically walk back through the frames looking for saved 905875Slinton * register 11's. Each time we find one, we remember it. When we reach 915875Slinton * the frame associated with the interpreter procedure, the most recently 925875Slinton * saved register 11 is the one we want. 935508Slinton */ 945508Slinton 955508Slinton typedef struct { 965714Slinton int fr_handler; 975714Slinton unsigned int fr_psw : 16; /* saved psw */ 985714Slinton unsigned int fr_mask : 12; /* register save mask */ 995714Slinton unsigned int fr_unused : 1; 1005714Slinton unsigned int fr_s : 1; /* call was a calls, not callg */ 1015714Slinton unsigned int fr_spa : 2; /* stack pointer alignment */ 1025714Slinton unsigned int fr_savap; /* saved arg pointer */ 1035714Slinton unsigned int fr_savfp; /* saved frame pointer */ 1045714Slinton int fr_savpc; /* saved program counter */ 1055508Slinton } Vaxframe; 1065508Slinton 1075875Slinton #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0) 1085875Slinton 1095508Slinton LOCAL ADDRESS fetchpc(framep) 1105508Slinton ADDRESS *framep; 1115508Slinton { 1125714Slinton register PROCESS *p; 1135714Slinton Vaxframe vframe; 1145714Slinton ADDRESS *savfp; 1155714Slinton ADDRESS r; 1165508Slinton 1175714Slinton p = process; 1185875Slinton r = p->reg[11]; 1195714Slinton if (p->fp == (ADDRESS) framep) { 1205875Slinton return r; 1215714Slinton } 1225714Slinton savfp = (ADDRESS *) p->fp; 1235714Slinton dread(&vframe, savfp, sizeof(vframe)); 1245714Slinton while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) { 1255875Slinton if (regsaved(vframe, 11)) { 1265875Slinton dread(&r, savfp + 5, sizeof(r)); 1275875Slinton r -= sizeof(char); 1285875Slinton } 1295714Slinton savfp = (ADDRESS *) vframe.fr_savfp; 1305508Slinton dread(&vframe, savfp, sizeof(vframe)); 1315714Slinton } 1325714Slinton if (vframe.fr_savfp == 0) { 1335714Slinton panic("resume: can't find interpreter frame 0x%x", framep); 1345714Slinton } 1355875Slinton if (regsaved(vframe, 11)) { 1365714Slinton dread(&r, savfp + 5, sizeof(r)); 1375714Slinton r -= sizeof(char); 1385714Slinton } 1395714Slinton return(r); 1405508Slinton } 1415508Slinton 142*11061Slinton #endif 14310766Slinton 1445508Slinton /* 1455508Slinton * Under the -r option, we offer the opportunity to just get 1465508Slinton * the px traceback and not actually enter the debugger. 1476074Slinton * 1486074Slinton * If the standard input is not a tty but standard error is, 1496074Slinton * change standard input to be /dev/tty. 1505508Slinton */ 1515508Slinton 1525508Slinton LOCAL choose() 1535508Slinton { 1545714Slinton register int c; 1555508Slinton 1566873Slinton if (!isterm(stdin)) { 1576873Slinton if (!isterm(stderr) || freopen("/dev/tty", "r", stdin) == NIL) { 1586074Slinton unsetsigtraces(process); 1596074Slinton pcont(process); 1606074Slinton quit(process->exitval); 1616074Slinton /* NOTREACHED */ 1626074Slinton } 1636074Slinton } 1645714Slinton fprintf(stderr, "\nProgram error"); 1655714Slinton if (errnum != 0) { 1665714Slinton fprintf(stderr, " -- %s", pxerrmsg[errnum]); 1675714Slinton } 1685714Slinton fprintf(stderr, "\nDo you wish to enter the debugger? "); 1695714Slinton c = getchar(); 1705714Slinton if (c == 'n') { 1715714Slinton unsetsigtraces(process); 1725714Slinton pcont(process); 1735714Slinton quit(process->exitval); 1745714Slinton } 1756074Slinton while (c != '\n' && c != EOF) { 1765508Slinton c = getchar(); 1775714Slinton } 1785714Slinton fprintf(stderr, "\nEntering debugger ..."); 1795714Slinton init(); 1805714Slinton option('r') = FALSE; 1815714Slinton fprintf(stderr, " type 'help' for help.\n"); 1825508Slinton } 183