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