122512Sdist /*
222512Sdist  * Copyright (c) 1980 Regents of the University of California.
322512Sdist  * All rights reserved.  The Berkeley software License Agreement
422512Sdist  * specifies the terms and conditions for redistribution.
522512Sdist  */
65508Slinton 
722512Sdist #ifndef lint
8*30848Smckusick static char sccsid[] = "@(#)resume.c	5.2 (Berkeley) 04/07/87";
922512Sdist #endif not lint
10*30848Smckusick 
115508Slinton /*
1211061Slinton  * Resume execution, first setting appropriate registers.
135508Slinton  */
145508Slinton 
155508Slinton #include "defs.h"
165508Slinton #include <signal.h>
175508Slinton #include "process.h"
185508Slinton #include "machine.h"
195508Slinton #include "main.h"
205508Slinton #include "process.rep"
215508Slinton #include "runtime/frame.rep"
225508Slinton 
2311061Slinton #include "machine/pxerrors.h"
2411061Slinton #include "pxinfo.h"
255508Slinton 
26*30848Smckusick #if defined(vax) || defined(tahoe)
2711061Slinton     LOCAL ADDRESS fetchpc();
2810766Slinton #endif
29*30848Smckusick #ifdef vax
30*30848Smckusick #define	PCREG	11	/* where px holds virtual pc (see interp.sed) */
31*30848Smckusick #endif
32*30848Smckusick #ifdef tahoe
33*30848Smckusick #define	PCREG	12	/* where px holds virtual pc (see interp.sed) */
34*30848Smckusick #endif
355508Slinton 
36*30848Smckusick #ifdef sun
3710766Slinton LOCAL ADDRESS *pcaddr;
38*30848Smckusick #endif
3910766Slinton 
405508Slinton /*
4110766Slinton  * Resume execution, set (get) pcode location counter before (after) resuming.
425508Slinton  */
435508Slinton 
445508Slinton resume()
455508Slinton {
465714Slinton     register PROCESS *p;
475508Slinton 
485714Slinton     p = process;
495714Slinton     do {
505714Slinton 	if (option('e')) {
515714Slinton 	    printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc);
525714Slinton 	    fflush(stdout);
535714Slinton 	}
545714Slinton 	pcont(p);
5511061Slinton #       ifdef sun
5611061Slinton 	    if (pcaddr == 0) {
5711061Slinton 		dread(&pcaddr, PCADDRP, sizeof(pcaddr));
5811061Slinton 	    }
5911061Slinton 	    dread(&pc, pcaddr, sizeof(pc));
60*30848Smckusick #       else vax || tahoe
6111061Slinton 	    if (p->status == STOPPED) {
6211061Slinton 		if (isbperr()) {
63*30848Smckusick 		    pc = p->reg[PCREG];
6411061Slinton 		} else {
6511061Slinton 		    dread(&pcframe, PCADDRP, sizeof(pcframe));
66*30848Smckusick #ifdef tahoe
67*30848Smckusick 		    pcframe += 14;
68*30848Smckusick #else
6911061Slinton 		    pcframe++;
70*30848Smckusick #endif
7111061Slinton 		    pc = fetchpc(pcframe);
725508Slinton 		}
7311061Slinton 		pc -= (sizeof(char) + ENDOFF);
7411061Slinton 	    }
755714Slinton #       endif
765714Slinton 	if (option('e')) {
775714Slinton 	    printf("execution stops at pc 0x%x, lc %d on sig %d\n",
785714Slinton 		process->pc, pc, p->signo);
795714Slinton 	    fflush(stdout);
805714Slinton 	}
815714Slinton     } while (p->signo == SIGCONT);
8211061Slinton     if (option('r') && p->signo != 0) {
8311061Slinton 	choose();
8411061Slinton     }
8510766Slinton 
8610766Slinton     /*
8710766Slinton      * If px implements a breakpoint by executing a halt instruction
8811061Slinton      * the real pc must be incremented to skip over it.
8911061Slinton      *
9011061Slinton      * Currently, px sends itself a signal so no incrementing is needed.
9111061Slinton      *
9211061Slinton 	if (isbperr()) {
9311061Slinton 	    p->pc++;
9411061Slinton 	}
9510766Slinton      */
965508Slinton }
975508Slinton 
98*30848Smckusick #if defined(vax) || defined(tahoe)
995508Slinton 
1005508Slinton /*
1015508Slinton  * Find the location in the Pascal object where execution was suspended.
1025875Slinton  *
1035875Slinton  * We basically walk back through the frames looking for saved
104*30848Smckusick  * register PCREG's.  Each time we find one, we remember it.  When we reach
1055875Slinton  * the frame associated with the interpreter procedure, the most recently
106*30848Smckusick  * saved register PCREG is the one we want.
1075508Slinton  */
1085508Slinton 
1095508Slinton typedef struct {
110*30848Smckusick #ifdef vax
1115714Slinton     int fr_handler;
1125714Slinton     unsigned int fr_psw : 16;   /* saved psw */
1135714Slinton     unsigned int fr_mask : 12;  /* register save mask */
1145714Slinton     unsigned int fr_unused : 1;
1155714Slinton     unsigned int fr_s : 1;      /* call was a calls, not callg */
1165714Slinton     unsigned int fr_spa : 2;    /* stack pointer alignment */
1175714Slinton     unsigned int fr_savap;      /* saved arg pointer */
1185714Slinton     unsigned int fr_savfp;      /* saved frame pointer */
1195714Slinton     int fr_savpc;           /* saved program counter */
120*30848Smckusick #endif
121*30848Smckusick #ifdef tahoe
122*30848Smckusick     int fr_savpc;           /* saved program counter */
123*30848Smckusick     unsigned short fr_mask;     /* register save mask */
124*30848Smckusick     unsigned short fr_removed;  /* (nargs+1)*4 */
125*30848Smckusick     unsigned int fr_savfp;      /* saved frame pointer */
126*30848Smckusick #endif
127*30848Smckusick } Stkframe;
1285508Slinton 
1295875Slinton #define regsaved(frame, n) ((frame.fr_mask&(1 << n)) != 0)
1305875Slinton 
1315508Slinton LOCAL ADDRESS fetchpc(framep)
1325508Slinton ADDRESS *framep;
1335508Slinton {
1345714Slinton     register PROCESS *p;
135*30848Smckusick     Stkframe sframe;
136*30848Smckusick #ifdef tahoe
137*30848Smckusick #define	PCREGLOC	(-1)
138*30848Smckusick #else
139*30848Smckusick #define	PCREGLOC	(sizeof sframe/sizeof(ADDRESS))
140*30848Smckusick #endif
1415714Slinton     ADDRESS *savfp;
1425714Slinton     ADDRESS r;
1435508Slinton 
1445714Slinton     p = process;
145*30848Smckusick     r = p->reg[PCREG];
1465714Slinton     if (p->fp == (ADDRESS) framep) {
1475875Slinton 	return r;
1485714Slinton     }
1495714Slinton     savfp = (ADDRESS *) p->fp;
150*30848Smckusick #ifdef tahoe
151*30848Smckusick     savfp -= 2;
152*30848Smckusick #endif
153*30848Smckusick     dread(&sframe, savfp, sizeof(sframe));
154*30848Smckusick     while (sframe.fr_savfp != (int) framep && sframe.fr_savfp != 0) {
155*30848Smckusick 	if (regsaved(sframe, PCREG)) {
156*30848Smckusick 	    dread(&r, savfp + PCREGLOC, sizeof(r));
1575875Slinton 	    r -= sizeof(char);
1585875Slinton 	}
159*30848Smckusick 	savfp = (ADDRESS *) sframe.fr_savfp;
160*30848Smckusick #ifdef tahoe
161*30848Smckusick 	savfp -= 2;
162*30848Smckusick #endif
163*30848Smckusick 	dread(&sframe, savfp, sizeof(sframe));
1645714Slinton     }
165*30848Smckusick     if (sframe.fr_savfp == 0) {
1665714Slinton 	panic("resume: can't find interpreter frame 0x%x", framep);
1675714Slinton     }
168*30848Smckusick     if (regsaved(sframe, PCREG)) {
169*30848Smckusick 	dread(&r, savfp + PCREGLOC, sizeof(r));
1705714Slinton 	r -= sizeof(char);
1715714Slinton     }
1725714Slinton     return(r);
1735508Slinton }
1745508Slinton 
17511061Slinton #endif
17610766Slinton 
1775508Slinton /*
1785508Slinton  * Under the -r option, we offer the opportunity to just get
1795508Slinton  * the px traceback and not actually enter the debugger.
1806074Slinton  *
1816074Slinton  * If the standard input is not a tty but standard error is,
1826074Slinton  * change standard input to be /dev/tty.
1835508Slinton  */
1845508Slinton 
1855508Slinton LOCAL choose()
1865508Slinton {
1875714Slinton     register int c;
1885508Slinton 
1896873Slinton     if (!isterm(stdin)) {
1906873Slinton 	if (!isterm(stderr) || freopen("/dev/tty", "r", stdin) == NIL) {
1916074Slinton 	    unsetsigtraces(process);
1926074Slinton 	    pcont(process);
1936074Slinton 	    quit(process->exitval);
1946074Slinton 	    /* NOTREACHED */
1956074Slinton 	}
1966074Slinton     }
1975714Slinton     fprintf(stderr, "\nProgram error");
1985714Slinton     fprintf(stderr, "\nDo you wish to enter the debugger? ");
1995714Slinton     c = getchar();
2005714Slinton     if (c == 'n') {
2015714Slinton 	unsetsigtraces(process);
2025714Slinton 	pcont(process);
2035714Slinton 	quit(process->exitval);
2045714Slinton     }
2056074Slinton     while (c != '\n' && c != EOF) {
2065508Slinton 	c = getchar();
2075714Slinton     }
2085714Slinton     fprintf(stderr, "\nEntering debugger ...");
2095714Slinton     init();
2105714Slinton     option('r') = FALSE;
2115714Slinton     fprintf(stderr, " type 'help' for help.\n");
2125508Slinton }
213