15508Slinton /* Copyright (c) 1982 Regents of the University of California */ 25508Slinton 3*6074Slinton static char sccsid[] = "@(#)resume.c 1.6 03/08/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. 785875Slinton * 795875Slinton * We basically walk back through the frames looking for saved 805875Slinton * register 11's. Each time we find one, we remember it. When we reach 815875Slinton * the frame associated with the interpreter procedure, the most recently 825875Slinton * 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 975875Slinton #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0) 985875Slinton 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; 1085875Slinton r = p->reg[11]; 1095714Slinton if (p->fp == (ADDRESS) framep) { 1105875Slinton 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) { 1155875Slinton if (regsaved(vframe, 11)) { 1165875Slinton dread(&r, savfp + 5, sizeof(r)); 1175875Slinton r -= sizeof(char); 1185875Slinton } 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 } 1255875Slinton 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. 135*6074Slinton * 136*6074Slinton * If the standard input is not a tty but standard error is, 137*6074Slinton * change standard input to be /dev/tty. 1385508Slinton */ 1395508Slinton 1405508Slinton LOCAL choose() 1415508Slinton { 1425714Slinton register int c; 1435508Slinton 144*6074Slinton if (!isatty(fileno(stdin))) { 145*6074Slinton if (!isatty(fileno(stderr)) || freopen("/dev/tty", "r", stdin) == NIL) { 146*6074Slinton unsetsigtraces(process); 147*6074Slinton pcont(process); 148*6074Slinton quit(process->exitval); 149*6074Slinton /* NOTREACHED */ 150*6074Slinton } 151*6074Slinton } 1525714Slinton fprintf(stderr, "\nProgram error"); 1535714Slinton if (errnum != 0) { 1545714Slinton fprintf(stderr, " -- %s", pxerrmsg[errnum]); 1555714Slinton } 1565714Slinton fprintf(stderr, "\nDo you wish to enter the debugger? "); 1575714Slinton c = getchar(); 1585714Slinton if (c == 'n') { 1595714Slinton unsetsigtraces(process); 1605714Slinton pcont(process); 1615714Slinton quit(process->exitval); 1625714Slinton } 163*6074Slinton while (c != '\n' && c != EOF) { 1645508Slinton c = getchar(); 1655714Slinton } 1665714Slinton fprintf(stderr, "\nEntering debugger ..."); 1675714Slinton init(); 1685714Slinton option('r') = FALSE; 1695714Slinton fprintf(stderr, " type 'help' for help.\n"); 1705508Slinton } 1715508Slinton 1725508Slinton # endif 173