date and time created 83/08/05 13:35:28 by sam
[unix-history] / usr / src / old / dbx / runtime.vax.c
index 08799d5..698cd2d 100644 (file)
@@ -1,6 +1,7 @@
+
 /* Copyright (c) 1982 Regents of the University of California */
 
 /* Copyright (c) 1982 Regents of the University of California */
 
-static char sccsid[] = "@(#)runtime.vax.c 1.3 %G%";
+static char sccsid[] = "@(#)runtime.vax.c 1.7 %G%";
 
 /*
  * Runtime organization dependent routines, mostly dealing with
 
 /*
  * Runtime organization dependent routines, mostly dealing with
@@ -18,6 +19,7 @@ static char sccsid[] = "@(#)runtime.vax.c 1.3 %G%";
 #include "eval.h"
 #include "operators.h"
 #include "object.h"
 #include "eval.h"
 #include "operators.h"
 #include "object.h"
+#include <sys/param.h>
 
 #ifndef public
 typedef struct Frame *Frame;
 
 #ifndef public
 typedef struct Frame *Frame;
@@ -51,7 +53,7 @@ register Frame frp;
     frp->mask = reg(NREG);
     frp->save_ap = reg(ARGP);
     frp->save_fp = reg(FRP);
     frp->mask = reg(NREG);
     frp->save_ap = reg(ARGP);
     frp->save_fp = reg(FRP);
-    frp->save_pc = reg(PROGCTR);
+    frp->save_pc = reg(PROGCTR) + 1;
     for (i = 0; i < NSAVEREG; i++) {
        frp->save_reg[i] = reg(i);
     }
     for (i = 0; i < NSAVEREG; i++) {
        frp->save_reg[i] = reg(i);
     }
@@ -71,12 +73,50 @@ Frame frp;
     register Frame newfrp;
     struct Frame frame;
     register Integer i, j, mask;
     register Frame newfrp;
     struct Frame frame;
     register Integer i, j, mask;
+    Address prev_frame, callpc; 
+    static Integer ntramp = 0;
 
     newfrp = frp;
 
     newfrp = frp;
-    dread(&frame, newfrp->save_fp, sizeof(struct Frame));
+    prev_frame = frp->save_fp;
+
+/*
+ *  The check for interrupt generated frames is taken from adb with only
+ *  partial understanding.  If you're in "sub" and on a sigxxx "sigsub"
+ *  gets control, then the stack does NOT look like <main, sub, sigsub>.
+ *
+ *  As best I can make out it looks like:
+ *
+ *     <main, (machine check exception block + sub), sysframe, sigsub>.
+ *
+ *  When the signal occurs an exception block and a frame for the routine
+ *  in which it occured are pushed on the user stack.  Then another frame
+ *  is pushed corresponding to a call from the kernel to sigsub.
+ *
+ *  The addr in sub at which the exception occured is not in sub.save_pc
+ *  but in the machine check exception block.  It is at the magic address
+ *  fp + 76.
+ *
+ *  The current approach ignores the sys_frame (what adb reports as sigtramp)
+ *  and takes the pc for sub from the exception block.  This allows the
+ *  "where" command to report <main, sub, sigsub>, which seems reasonable.
+ */
+
+nextf:
+    dread(&frame, prev_frame, sizeof(struct Frame));
+    if (ntramp == 1) {
+       dread(&callpc, prev_frame + 76, sizeof(callpc));
+    } else {
+       callpc = frame.save_pc;
+    }
     if (frame.save_fp == nil) {
        newfrp = nil;
     if (frame.save_fp == nil) {
        newfrp = nil;
+    } else if (callpc > 0x80000000 - 0x200 * UPAGES ) {
+        ntramp++;
+        prev_frame = frame.save_fp;
+        goto nextf;
     } else {
     } else {
+       frame.save_pc = callpc;
+        ntramp = 0;
        mask = ((frame.mask >> 16) & 0x0fff);
        j = 0;
        for (i = 0; i < NSAVEREG; i++) {
        mask = ((frame.mask >> 16) & 0x0fff);
        j = 0;
        for (i = 0; i < NSAVEREG; i++) {
@@ -106,13 +146,27 @@ Symbol f;
 {
     register Frame frp;
     static struct Frame frame;
 {
     register Frame frp;
     static struct Frame frame;
+    Symbol p;
+    Boolean done;
 
     frp = &frame;
     getcurframe(frp);
     if (f != nil) {
 
     frp = &frame;
     getcurframe(frp);
     if (f != nil) {
-       while (frp != nil and whatblock(frp->save_pc) != f) {
-           frp = nextframe(frp);
-       }
+       done = false;
+       do {
+           p = whatblock(frp->save_pc);
+           if (p == f) {
+               done = true;
+           } else if (p == program) {
+               done = true;
+               frp = nil;
+           } else {
+               frp = nextframe(frp);
+               if (frp == nil) {
+                   done = true;
+               }
+           }
+       } while (not done);
     }
     return frp;
 }
     }
     return frp;
 }
@@ -286,8 +340,6 @@ public dump()
  * about each active procedure.
  */
 
  * about each active procedure.
  */
 
-#define lastfunc(f)     (f == program)
-
 private walkstack(dumpvariables)
 Boolean dumpvariables;
 {
 private walkstack(dumpvariables)
 Boolean dumpvariables;
 {
@@ -323,7 +375,7 @@ Boolean dumpvariables;
            if (frp != nil) {
                f = whatblock(frp->save_pc);
            }
            if (frp != nil) {
                f = whatblock(frp->save_pc);
            }
-       } while (frp != nil and not lastfunc(f));
+       } while (frp != nil and f != program);
        if (dumpvariables) {
            printf("in \"%s\":\n", symname(program));
            dumpvars(program, nil);
        if (dumpvariables) {
            printf("in \"%s\":\n", symname(program));
            dumpvars(program, nil);