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