date and time created 82/01/18 19:19:54 by linton
authorMark Linton <linton@ucbvax.Berkeley.EDU>
Tue, 19 Jan 1982 11:19:54 +0000 (03:19 -0800)
committerMark Linton <linton@ucbvax.Berkeley.EDU>
Tue, 19 Jan 1982 11:19:54 +0000 (03:19 -0800)
SCCS-vsn: usr.bin/pascal/pdx/breakpoint/bpact.c 1.1

usr/src/usr.bin/pascal/pdx/breakpoint/bpact.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/pascal/pdx/breakpoint/bpact.c b/usr/src/usr.bin/pascal/pdx/breakpoint/bpact.c
new file mode 100644 (file)
index 0000000..f1893bd
--- /dev/null
@@ -0,0 +1,315 @@
+/* Copyright (c) 1982 Regents of the University of California */
+
+static char sccsid[] = "@(#)bpact.c 1.1 %G%";
+
+/*
+ * Routines for doing the right thing when a breakpoint is reached.
+ */
+
+#include "defs.h"
+#include "breakpoint.h"
+#include "sym.h"
+#include "tree.h"
+#include "source.h"
+#include "mappings.h"
+#include "runtime.h"
+#include "process.h"
+#include "machine.h"
+#include "main.h"
+#include "bp.rep"
+#include "tree/tree.rep"
+
+typedef enum { SAVE, NOSAVE } SAVEBP;
+
+LOCAL SAVEBP handlebp();
+
+/*
+ * A "delayed" breakpoint is one that has an action involving execution
+ * of code, e.g. at a CALL we want to step from the beginning of the
+ * procedure to the first line before printing parameters.
+ */
+
+LOCAL short delayed;
+
+#define NONE 0
+#define DELAY_CALL 1
+#define DELAY_STOP 2
+
+/*
+ * Take action at a breakpoint; if it's not a breakpoint return FALSE.
+ *
+ * As we go through the list of breakpoints, we have to remember
+ * the previous one so that "handlebp" can delete breakpoints on
+ * the fly if necessary.
+ *
+ * If the breakpoint is a STOP_BP, handlebp will set "isstopped".  After
+ * going through the loop, bpact checks if "isstopped" is set and calls
+ * printstatus if it is.  This is so multiple breakpoints at the same
+ * address, one of which is a STOP_BP, still work.
+ */
+
+#define isswitch(bptype) ( \
+       bptype == ALL_ON || bptype == ALL_OFF || \
+       bptype == TERM_ON || bptype == TERM_OFF || \
+       bptype == BLOCK_ON || bptype == BLOCK_OFF || \
+       bptype == STOP_ON || bptype == STOP_OFF \
+)
+
+BOOLEAN bpact()
+{
+       register BPINFO *p;
+       BPINFO *prev, *next;
+       BOOLEAN found;
+       ADDRESS oldpc;
+
+       delayed = NONE;
+       found = FALSE;
+       prev = NIL;
+       for (p = bphead; p != NIL; p = next) {
+               next = p->bpnext;
+               if (p->bpaddr == pc) {
+                       prbpfound(p);
+                       found = TRUE;
+                       if (p->bpcond == NIL || isswitch(p->bptype) || cond(p->bpcond)) {
+                               prbphandled();
+                               if (handlebp(p) == NOSAVE) {
+                                       prbpnosave();
+                                       if (prev == NIL) {
+                                               bphead = next;
+                                       } else {
+                                               prev->bpnext = next;
+                                       }
+                                       dispose(p);
+                               } else {
+                                       prbpsave();
+                                       prev = p;
+                               }
+                       } else {
+                               prev = p;
+                       }
+               } else {
+                       prev = p;
+               }
+       }
+       if (delayed != NONE) {
+               oldpc = pc;
+               runtofirst();
+               if ((delayed&DELAY_CALL) == DELAY_CALL) {
+                       SYM *s, *t;
+
+                       s = curfunc;
+                       t = whatblock(return_addr());
+                       if (t == NIL) {
+                               panic("can't find block for caller addr %d", caller_addr());
+                       }
+                       printcall(s, t);
+                       addbp(return_addr(), RETURN, s, NIL, NIL, 0);
+               }
+               if (pc != oldpc) {
+                       bpact();
+               }
+               if (isstopped) {
+                       printstatus();
+               }
+       } else {
+               if (isstopped) {
+                       printstatus();
+               }
+       }
+       fflush(stdout);
+       return(found);
+}
+
+/*
+ * Handle an expected breakpoint appropriately, return whether
+ * or not to save the breakpoint.
+ */
+
+LOCAL SAVEBP handlebp(p)
+BPINFO *p;
+{
+       register SYM *s, *t;
+       SAVEBP r;
+
+       r = SAVE;
+       switch(p->bptype) {
+               case ALL_ON:
+                       curfunc = p->bpblock;
+                       addcond(TRPRINT, p->bpcond);
+                       if (p->bpline >= 0) {
+                               tracing++;
+                       } else {
+                               inst_tracing++;
+                       }
+                       addbp(return_addr(), ALL_OFF, curfunc, p->bpcond, NIL, 0);
+                       break;
+
+               case ALL_OFF:
+                       r = NOSAVE;
+                       if (p->bpline >= 0) {
+                               tracing--;
+                       } else {
+                               inst_tracing--;
+                       }
+                       delcond(TRPRINT, p->bpcond);
+                       curfunc = p->bpblock;
+                       break;
+
+               case STOP_ON:
+                       var_tracing++;
+                       curfunc = p->bpblock;
+                       if (p->bpnode != NIL) {
+                               addvar(TRSTOP, p->bpnode, p->bpcond);
+                       } else if (p->bpcond != NIL) {
+                               addcond(TRSTOP, p->bpcond);
+                       }
+                       addbp(return_addr(), STOP_OFF, curfunc, p->bpcond, p->bpnode, 0);
+                       break;
+
+               case STOP_OFF:
+                       r = NOSAVE;
+                       delcond(TRSTOP, p->bpcond);
+                       var_tracing--;
+                       curfunc = p->bpblock;
+                       break;
+
+               case INST:
+                       curline = p->bpline;
+                       if (curline > 0) {
+                               printf("trace:  ");
+                               printlines(curline, curline);
+                       } else {
+                               printf("inst trace:     ");
+                               printinst(pc, pc);
+                       }
+                       break;
+
+               case STOP_BP:
+                       if (p->bpblock != NIL) {
+                               delayed |= DELAY_STOP;
+                               curfunc = p->bpblock;
+                       }
+                       curline = p->bpline;
+                       isstopped = TRUE;
+                       break;
+
+               case BLOCK_ON: {
+                       BPINFO *nbp;
+
+                       s = p->bpblock;
+                       t = p->bpnode->nameval;
+                       nbp = newbp(codeloc(t), CALL, t, p->bpcond, NIL, 0);
+                       addbp(return_addr(), BLOCK_OFF, (SYM *) nbp, NIL, NIL, 0);
+                       break;
+               }
+
+               case BLOCK_OFF: {
+                       BPINFO *oldbp;
+
+                       r = NOSAVE;
+                       oldbp = (BPINFO *) p->bpblock;
+                       delbp(oldbp->bpid);
+                       break;
+               }
+
+               case CALL:
+                       delayed |= DELAY_CALL;
+                       curfunc = p->bpblock;
+                       break;
+
+               case RETURN:
+                       r = NOSAVE;
+                       s = p->bpblock;
+                       printrtn(s);
+                       break;
+
+               case TERM_ON: {
+                       ADDRESS addr;
+
+                       curfunc = p->bpblock;
+                       addvar(TRPRINT, p->bpnode, p->bpcond);
+                       addr = return_addr();
+                       addbp(addr, TERM_OFF, curfunc, p->bpcond, p->bpnode, 0);
+                       var_tracing++;
+                       break;
+               }
+
+               case TERM_OFF:
+                       r = NOSAVE;
+                       var_tracing--;
+                       delvar(TRPRINT, p->bpnode, p->bpcond);
+                       curfunc = p->bpblock;
+                       break;
+
+               case AT_BP:
+                       printf("at line %d: ", p->bpline);
+                       eval(p->bpnode);
+                       prtree(p->bpnode);
+                       printf(" = ");
+                       printval(p->bpnode->nodetype);
+                       putchar('\n');
+                       break;
+
+               /*
+                * Returning from a called procedure.
+                * Further breakpoint processing is not done, since if
+                * there were any it wouldn't be associated with the call.
+                */
+               case CALLPROC:
+                       procreturn(p->bpblock);
+                       delbp(p->bpid);
+                       erecover();
+                       /* NOTREACHED */
+
+               case END_BP:
+                       r = NOSAVE;
+                       endprogram();
+
+               default:
+                       panic("unknown bptype %d in cont", p->bptype);
+                       /* NOTREACHED */
+       }
+       return(r);
+}
+
+/*
+ * Internal trace routines.
+ */
+
+LOCAL char *prbptype[] ={
+       "ALL_ON", "ALL_OFF", "INST", "CALL", "RETURN", "BLOCK_ON", "BLOCK_OFF",
+       "TERM_ON", "TERM_OFF", "AT_BP", "STOP_BP", "CALLPROC", "END_BP",
+       "STOP_ON", "STOP_OFF",
+};
+
+LOCAL prbpfound(p)
+BPINFO *p;
+{
+       if (option('b')) {
+               printf("%s breakpoint found at pc %d, line %d -- ",
+                       prbptype[(int) p->bptype], p->bpaddr, p->bpline);
+       }
+}
+
+LOCAL prbphandled()
+{
+       if (option('b')) {
+               printf("handled, ");
+       }
+}
+
+LOCAL prbpnosave()
+{
+       if (option('b')) {
+               printf("not saved\n");
+               fflush(stdout);
+       }
+}
+
+LOCAL prbpsave()
+{
+       if (option('b')) {
+               printf("saved\n");
+               fflush(stdout);
+       }
+}