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