fixing -r option
[unix-history] / usr / src / usr.bin / pascal / pdx / process / resume.c
/* Copyright (c) 1982 Regents of the University of California */
static char sccsid[] = "@(#)resume.c 1.2 %G%";
/*
* resume execution, first setting appropriate registers
*/
#include "defs.h"
#include <signal.h>
#include "process.h"
#include "machine.h"
#include "main.h"
#include "process.rep"
#include "runtime/frame.rep"
# if (isvaxpx)
# include "machine/pxerrors.h"
# include "pxinfo.h"
# endif
LOCAL ADDRESS fetchpc();
/*
* If we hit a breakpoint, px's pc points at a halt instruction,
* this must be avoided when restarting.
*/
resume()
{
register PROCESS *p;
int oldsigno;
p = process;
do {
if (option('e')) {
printf("execution resumes at pc 0x%x, lc %d\n", process->pc, pc);
fflush(stdout);
}
pcont(p);
# if (isvaxpx)
if (p->status == STOPPED) {
if (pcframe == NIL) {
dread(&pcframe, PCADDRP, sizeof(pcframe));
pcframe++;
}
if (isbperr()) {
pc = p->reg[11];
} else {
pc = fetchpc(pcframe);
}
pc -= (sizeof(char) + ENDOFF);
}
# else
pc = process->pc;
# endif
if (option('e')) {
printf("execution stops at pc 0x%x, lc %d on sig %d\n",
process->pc, pc, p->signo);
fflush(stdout);
}
if (p->status == STOPPED) {
errnum = 0;
}
} while (p->signo == SIGCONT);
# if (isvaxpx)
oldsigno = p->signo;
switch (p->signo) {
case SIGFPE:
errnum = EOVERFLOW;
p->signo = ESIGNAL;
break;
case SIGSEGV:
errnum = ESTKOVER;
p->signo = ESIGNAL;
break;
}
if (option('r') && oldsigno != 0) {
p->signo = oldsigno;
choose();
p->signo = ESIGNAL;
}
if (isbperr()) {
p->pc++;
}
# endif
}
# if (isvaxpx)
/*
* Find the location in the Pascal object where execution was suspended.
*/
typedef struct {
int fr_handler;
unsigned int fr_psw : 16; /* saved psw */
unsigned int fr_mask : 12; /* register save mask */
unsigned int fr_unused : 1;
unsigned int fr_s : 1; /* call was a calls, not callg */
unsigned int fr_spa : 2; /* stack pointer alignment */
unsigned int fr_savap; /* saved arg pointer */
unsigned int fr_savfp; /* saved frame pointer */
int fr_savpc; /* saved program counter */
} Vaxframe;
LOCAL ADDRESS fetchpc(framep)
ADDRESS *framep;
{
register PROCESS *p;
Vaxframe vframe;
ADDRESS *savfp;
ADDRESS r;
p = process;
if (p->fp == (ADDRESS) framep) {
return(p->reg[11]);
}
savfp = (ADDRESS *) p->fp;
dread(&vframe, savfp, sizeof(vframe));
while (vframe.fr_savfp != (int) framep && vframe.fr_savfp != 0) {
savfp = (ADDRESS *) vframe.fr_savfp;
dread(&vframe, savfp, sizeof(vframe));
}
if (vframe.fr_savfp == 0) {
panic("resume: can't find interpreter frame 0x%x", framep);
}
if (vframe.fr_mask == 0) {
r = p->reg[11];
} else {
dread(&r, savfp + 5, sizeof(r));
r -= sizeof(char);
}
return(r);
}
/*
* Under the -r option, we offer the opportunity to just get
* the px traceback and not actually enter the debugger.
*/
LOCAL choose()
{
register int c;
fprintf(stderr, "\nProgram error");
if (errnum != 0) {
fprintf(stderr, " -- %s", pxerrmsg[errnum]);
}
fprintf(stderr, "\nDo you wish to enter the debugger? ");
c = getchar();
if (c == 'n') {
unsetsigtraces(process);
pcont(process);
exit(0);
}
while (c != '\n') {
c = getchar();
}
fprintf(stderr, "\nEntering debugger, type 'help' for help\n");
}
# endif