1*22512Sdist /*
2*22512Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22512Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22512Sdist  * specifies the terms and conditions for redistribution.
5*22512Sdist  */
65508Slinton 
7*22512Sdist #ifndef lint
8*22512Sdist static char sccsid[] = "@(#)resume.c	5.1 (Berkeley) 06/06/85";
9*22512Sdist #endif not lint
105508Slinton /*
1111061Slinton  * Resume execution, first setting appropriate registers.
125508Slinton  */
135508Slinton 
145508Slinton #include "defs.h"
155508Slinton #include <signal.h>
165508Slinton #include "process.h"
175508Slinton #include "machine.h"
185508Slinton #include "main.h"
195508Slinton #include "process.rep"
205508Slinton #include "runtime/frame.rep"
215508Slinton 
2211061Slinton #include "machine/pxerrors.h"
2311061Slinton #include "pxinfo.h"
245508Slinton 
2510766Slinton #ifdef vax
2611061Slinton     LOCAL ADDRESS fetchpc();
2710766Slinton #endif
285508Slinton 
2910766Slinton LOCAL ADDRESS *pcaddr;
3010766Slinton 
315508Slinton /*
3210766Slinton  * Resume execution, set (get) pcode location counter before (after) resuming.
335508Slinton  */
345508Slinton 
355508Slinton resume()
365508Slinton {
375714Slinton     register PROCESS *p;
385714Slinton     int oldsigno;
395508Slinton 
405714Slinton     p = process;
415714Slinton     do {
425714Slinton 	if (option('e')) {
435714Slinton 	    printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc);
445714Slinton 	    fflush(stdout);
455714Slinton 	}
465714Slinton 	pcont(p);
4711061Slinton #       ifdef sun
4811061Slinton 	    if (pcaddr == 0) {
4911061Slinton 		dread(&pcaddr, PCADDRP, sizeof(pcaddr));
5011061Slinton 	    }
5111061Slinton 	    dread(&pc, pcaddr, sizeof(pc));
5211061Slinton #       else ifdef vax
5311061Slinton 	    if (p->status == STOPPED) {
5411061Slinton 		if (isbperr()) {
5511061Slinton 		    pc = p->reg[11];
5611061Slinton 		} else {
5711061Slinton 		    dread(&pcframe, PCADDRP, sizeof(pcframe));
5811061Slinton 		    pcframe++;
5911061Slinton 		    pc = fetchpc(pcframe);
605508Slinton 		}
6111061Slinton 		pc -= (sizeof(char) + ENDOFF);
6211061Slinton 	    }
635714Slinton #       endif
645714Slinton 	if (option('e')) {
655714Slinton 	    printf("execution stops at pc 0x%x, lc %d on sig %d\n",
665714Slinton 		process->pc, pc, p->signo);
675714Slinton 	    fflush(stdout);
685714Slinton 	}
695714Slinton 	if (p->status == STOPPED) {
705714Slinton 	    errnum = 0;
715714Slinton 	}
725714Slinton     } while (p->signo == SIGCONT);
7311061Slinton     if (option('r') && p->signo != 0) {
7411061Slinton 	choose();
7511061Slinton     }
7610766Slinton 
7710766Slinton     /*
7810766Slinton      * If px implements a breakpoint by executing a halt instruction
7911061Slinton      * the real pc must be incremented to skip over it.
8011061Slinton      *
8111061Slinton      * Currently, px sends itself a signal so no incrementing is needed.
8211061Slinton      *
8311061Slinton 	if (isbperr()) {
8411061Slinton 	    p->pc++;
8511061Slinton 	}
8610766Slinton      */
875508Slinton }
885508Slinton 
8911061Slinton #ifdef vax
905508Slinton 
915508Slinton /*
925508Slinton  * Find the location in the Pascal object where execution was suspended.
935875Slinton  *
945875Slinton  * We basically walk back through the frames looking for saved
955875Slinton  * register 11's.  Each time we find one, we remember it.  When we reach
965875Slinton  * the frame associated with the interpreter procedure, the most recently
975875Slinton  * saved register 11 is the one we want.
985508Slinton  */
995508Slinton 
1005508Slinton typedef struct {
1015714Slinton     int fr_handler;
1025714Slinton     unsigned int fr_psw : 16;   /* saved psw */
1035714Slinton     unsigned int fr_mask : 12;  /* register save mask */
1045714Slinton     unsigned int fr_unused : 1;
1055714Slinton     unsigned int fr_s : 1;      /* call was a calls, not callg */
1065714Slinton     unsigned int fr_spa : 2;    /* stack pointer alignment */
1075714Slinton     unsigned int fr_savap;      /* saved arg pointer */
1085714Slinton     unsigned int fr_savfp;      /* saved frame pointer */
1095714Slinton     int fr_savpc;           /* saved program counter */
1105508Slinton } Vaxframe;
1115508Slinton 
1125875Slinton #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0)
1135875Slinton 
1145508Slinton LOCAL ADDRESS fetchpc(framep)
1155508Slinton ADDRESS *framep;
1165508Slinton {
1175714Slinton     register PROCESS *p;
1185714Slinton     Vaxframe vframe;
1195714Slinton     ADDRESS *savfp;
1205714Slinton     ADDRESS r;
1215508Slinton 
1225714Slinton     p = process;
1235875Slinton     r = p->reg[11];
1245714Slinton     if (p->fp == (ADDRESS) framep) {
1255875Slinton 	return r;
1265714Slinton     }
1275714Slinton     savfp = (ADDRESS *) p->fp;
1285714Slinton     dread(&vframe, savfp, sizeof(vframe));
1295714Slinton     while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) {
1305875Slinton 	if (regsaved(vframe, 11)) {
1315875Slinton 	    dread(&r, savfp + 5, sizeof(r));
1325875Slinton 	    r -= sizeof(char);
1335875Slinton 	}
1345714Slinton 	savfp = (ADDRESS *) vframe.fr_savfp;
1355508Slinton 	dread(&vframe, savfp, sizeof(vframe));
1365714Slinton     }
1375714Slinton     if (vframe.fr_savfp == 0) {
1385714Slinton 	panic("resume: can't find interpreter frame 0x%x", framep);
1395714Slinton     }
1405875Slinton     if (regsaved(vframe, 11)) {
1415714Slinton 	dread(&r, savfp + 5, sizeof(r));
1425714Slinton 	r -= sizeof(char);
1435714Slinton     }
1445714Slinton     return(r);
1455508Slinton }
1465508Slinton 
14711061Slinton #endif
14810766Slinton 
1495508Slinton /*
1505508Slinton  * Under the -r option, we offer the opportunity to just get
1515508Slinton  * the px traceback and not actually enter the debugger.
1526074Slinton  *
1536074Slinton  * If the standard input is not a tty but standard error is,
1546074Slinton  * change standard input to be /dev/tty.
1555508Slinton  */
1565508Slinton 
1575508Slinton LOCAL choose()
1585508Slinton {
1595714Slinton     register int c;
1605508Slinton 
1616873Slinton     if (!isterm(stdin)) {
1626873Slinton 	if (!isterm(stderr) || freopen("/dev/tty", "r", stdin) == NIL) {
1636074Slinton 	    unsetsigtraces(process);
1646074Slinton 	    pcont(process);
1656074Slinton 	    quit(process->exitval);
1666074Slinton 	    /* NOTREACHED */
1676074Slinton 	}
1686074Slinton     }
1695714Slinton     fprintf(stderr, "\nProgram error");
1705714Slinton     if (errnum != 0) {
1715714Slinton 	fprintf(stderr, " -- %s", pxerrmsg[errnum]);
1725714Slinton     }
1735714Slinton     fprintf(stderr, "\nDo you wish to enter the debugger? ");
1745714Slinton     c = getchar();
1755714Slinton     if (c == 'n') {
1765714Slinton 	unsetsigtraces(process);
1775714Slinton 	pcont(process);
1785714Slinton 	quit(process->exitval);
1795714Slinton     }
1806074Slinton     while (c != '\n' && c != EOF) {
1815508Slinton 	c = getchar();
1825714Slinton     }
1835714Slinton     fprintf(stderr, "\nEntering debugger ...");
1845714Slinton     init();
1855714Slinton     option('r') = FALSE;
1865714Slinton     fprintf(stderr, " type 'help' for help.\n");
1875508Slinton }
188