Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-4]: src/sys/arch/m68k/m68k Add a check to my last 'fix' which e...



details:   https://anonhg.NetBSD.org/src/rev/f5cd5f0223e5
branches:  netbsd-1-4
changeset: 468071:f5cd5f0223e5
user:      scw <scw%NetBSD.org@localhost>
date:      Mon Apr 05 17:17:05 1999 +0000

description:
Add a check to my last 'fix' which ensures the fault really
did happen in kernel mode.

diffstat:

 sys/arch/m68k/m68k/db_trace.c |  619 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 619 insertions(+), 0 deletions(-)

diffs (truncated from 623 to 300 lines):

diff -r 88a7220d87bf -r f5cd5f0223e5 sys/arch/m68k/m68k/db_trace.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/m68k/m68k/db_trace.c     Mon Apr 05 17:17:05 1999 +0000
@@ -0,0 +1,619 @@
+/*     $NetBSD: db_trace.c,v 1.25.2.2 1999/04/05 17:17:05 scw Exp $    */
+
+/* 
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution%CS.CMU.EDU@localhost
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon 
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_interface.h>
+#include <ddb/db_output.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+
+extern label_t *db_recover;
+
+/*
+ * Register list
+ */
+static int db_var_short __P((struct db_variable *, db_expr_t *, int));
+
+struct db_variable db_regs[] = {
+       /* D0-D7 */
+       { "d0", (long *)&ddb_regs.tf_regs[0],   FCN_NULL },
+       { "d1", (long *)&ddb_regs.tf_regs[1],   FCN_NULL },
+       { "d2", (long *)&ddb_regs.tf_regs[2],   FCN_NULL },
+       { "d3", (long *)&ddb_regs.tf_regs[3],   FCN_NULL },
+       { "d4", (long *)&ddb_regs.tf_regs[4],   FCN_NULL },
+       { "d5", (long *)&ddb_regs.tf_regs[5],   FCN_NULL },
+       { "d6", (long *)&ddb_regs.tf_regs[6],   FCN_NULL },
+       { "d7", (long *)&ddb_regs.tf_regs[7],   FCN_NULL },
+       /* A0-A7 */
+       { "a0", (long *)&ddb_regs.tf_regs[8+0], FCN_NULL },
+       { "a1", (long *)&ddb_regs.tf_regs[8+1], FCN_NULL },
+       { "a2", (long *)&ddb_regs.tf_regs[8+2], FCN_NULL },
+       { "a3", (long *)&ddb_regs.tf_regs[8+3], FCN_NULL },
+       { "a4", (long *)&ddb_regs.tf_regs[8+4], FCN_NULL },
+       { "a5", (long *)&ddb_regs.tf_regs[8+5], FCN_NULL },
+       { "a6", (long *)&ddb_regs.tf_regs[8+6], FCN_NULL },
+       { "sp", (long *)&ddb_regs.tf_regs[8+7], FCN_NULL },
+       /* misc. */
+       { "pc", (long *)&ddb_regs.tf_pc,        FCN_NULL },
+       { "sr", (long *)&ddb_regs.tf_sr,        db_var_short }
+};
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+static int
+db_var_short(varp, valp, op)
+    struct db_variable *varp;
+    db_expr_t *valp;
+    int op;
+{
+    if (op == DB_VAR_GET)
+       *valp = (db_expr_t) *((short*)varp->valuep);
+    else
+       *((short*)varp->valuep) = (short) *valp;
+    return(0);
+}
+
+#define        MAXINT  0x7fffffff
+
+#if 0
+#define        INKERNEL(va)    (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS && \
+                        (((vm_offset_t)(va)) < (USRSTACK - MAXSSIZ) || \
+                         ((vm_offset_t)(va)) >= USRSTACK))
+#else
+/* XXX - Slight hack... */
+extern int curpcb;
+#define        INKERNEL(va)    (((int)(va) > curpcb) && \
+                        ((int)(va) < (curpcb + USPACE)))
+#endif
+
+#define        get(addr, space) \
+               (db_get_value((db_addr_t)(addr), sizeof(int), FALSE))
+#define        get16(addr, space) \
+               (db_get_value((db_addr_t)(addr), sizeof(u_short), FALSE))
+
+#define        offsetof(type, member)  ((size_t)(&((type *)0)->member))
+
+#define        NREGISTERS      16
+
+struct stackpos {
+        int    k_pc;
+        int    k_fp;
+        int    k_nargs;
+        int    k_entry;
+        int    k_caller;
+        int    k_flags;
+        int    k_regloc[NREGISTERS];
+};
+
+static void findentry __P((struct stackpos *));
+static void findregs __P((struct stackpos *, db_addr_t));
+static int  nextframe __P((struct stackpos *, int));
+static void stacktop __P((db_regs_t *, struct stackpos *));
+
+
+#define FR_SAVFP       0
+#define FR_SAVPC       4
+#define K_CALLTRAMP    1       /* for k_flags: caller is __sigtramp */
+#define K_SIGTRAMP     2       /* for k_flags: this is   __sigtramp */
+
+static void
+stacktop(regs, sp)
+       db_regs_t *regs;
+       struct stackpos *sp;
+{
+       int i;
+
+       /* Note: leave out a6, a7 */
+       for (i = 0; i < (8+6); i++) {
+               sp->k_regloc[i] = (int) &regs->tf_regs[i];
+       }
+
+       sp->k_fp = get(&regs->tf_regs[8+6], 0);
+       /* skip sp (a7) */
+       sp->k_pc = get(&regs->tf_pc, 0);
+       sp->k_flags = 0;
+
+       findentry(sp);
+}
+
+
+/*
+ * The VAX has a very nice calling convention, and it is quite easy to
+ * find saved registers, and the number of parameters. We are not nearly
+ * so lucky. We must grub around in code for much of this information
+ * (remember the PDP-11?), and the saved register list seems to be
+ * especially hard to find.
+ */
+
+#define HIWORD 0xffff0000
+#define LOWORD 0x0000ffff
+#define LINKLA6        0x480e0000      /* linkl a6,#x    */
+#define LINKWA6        0x4e560000      /* linkw a6,#x    */
+#define ADDLSP 0xdffc0000      /* addl #x,sp    */
+#define ADDWSP 0xdefc0000      /* addw #x,sp    */
+#define LEASP  0x4fef0000      /* lea  sp@(x),sp*/
+#define TSTBSP 0x4a2f0000      /* tstb sp@(x)   */
+#define INSMSK 0xfff80000
+#define MOVLSP 0x2e800000      /* movl dx,sp@   */
+#define MOVLD0 0x20000000      /* movl d0,dx    */
+#define MOVLA0 0x20400000      /* movl d0,ax    */
+#define MVLMSK 0xf1ff0000
+#define MOVEML 0x48d70000      /* moveml #x,sp@ */
+#define JSR    0x4eb80000      /* jsr x.[WL]    */
+#define JSRPC  0x4eba0000      /* jsr PC@( )    */
+#define LONGBIT 0x00010000
+#define BSR    0x61000000      /* bsr x         */
+#define BSRL   0x61ff0000      /* bsrl x        */
+#define BYTE3  0x0000ff00
+#define LOBYTE 0x000000ff
+#define ADQMSK 0xf1ff0000
+#define ADDQSP 0x508f0000      /* addql #x,sp   */
+#define ADDQWSP        0x504f0000      /* addqw #x,sp   */
+
+struct nlist * trampsym = 0;
+struct nlist * funcsym = 0;
+
+static int
+nextframe(sp, kerneltrace)
+       struct stackpos *sp;
+       int kerneltrace;
+{
+       int             i;
+       db_addr_t       addr;
+       db_addr_t       calladdr;
+       db_addr_t       oldfp = sp->k_fp;
+
+       /*
+        * Find our entry point. Then find out
+        * which registers we saved, and map them.
+        * Our entry point is the address our caller called.
+        */
+
+       calladdr = sp->k_caller;
+       addr     = sp->k_entry;
+       if (sp->k_flags & K_CALLTRAMP) {
+#if    0
+       /* we never set CALLTRAMP */
+               /*
+                * Caller was sigtramp.  Therefore:
+                *   - no registers were saved;
+                *   - no new frame-pointer
+                *   - caller found in sigcontext structure.
+                *   - WE become sigtramp
+                *   - we have no parameters
+                * MUCH MAGIC USED IN FINDING CALLER'S PC.
+                */
+               sp->k_pc = sp->k_caller;
+               sp->k_entry = trampsym->n_value;
+               sp->k_flags = 0;
+               addr = get(sp->k_fp + sizeof(int) * 11, DSP);
+               sp->k_nargs = 0;
+#if DEBUG
+               db_printf("nextframe: sigcontext at 0x%x, signaled at 0x%x\n",
+                   addr, sp->k_caller);
+#endif
+               errflg = 0;
+#endif 0
+       } else {
+               if (addr == MAXINT) {
+                       /* we don't know what registers are involved here--
+                          invalidate all */
+                       for (i = 0; i < NREGISTERS; i++)
+                               sp->k_regloc[i] = -1;
+               } else
+                       findregs(sp, addr);
+
+               /* find caller's pc and fp */
+               sp->k_pc = calladdr;
+               sp->k_fp = get(sp->k_fp + FR_SAVFP, DSP);
+
+               /* 
+                * Now that we have assumed the identity of our caller, find
+                * how many longwords of argument WE were called with.
+                */
+               sp->k_flags = 0;
+
+               /*
+                * Don't dig around in user stack to find no. of args and
+                * entry point if just tracing the kernel
+                */
+               if (kerneltrace && !INKERNEL(sp->k_fp)) {
+                       sp->k_nargs = 0;
+                       sp->k_entry = MAXINT;
+               } else
+                       findentry(sp);
+       }
+
+       if (sp->k_fp == 0 || oldfp == sp->k_fp)
+               return 0;
+       return (sp->k_fp);
+}
+
+static void
+findentry(sp)
+       struct stackpos *sp;
+{ 
+       /* 
+        * Set the k_nargs and k_entry fields in the stackpos structure.  This
+        * is called from stacktop() and from nextframe().  Our caller will do
+        * an addq or addl or addw to sp just after we return to pop off our
+        * arguments.  Find that instruction and extract the value.
+        */
+       int             instruc;
+       int             val;
+       db_addr_t       addr, nextword;
+       label_t         db_jmpbuf;
+       label_t         *savejmp;
+
+       savejmp = db_recover;
+       db_recover = &db_jmpbuf;
+       if (setjmp(&db_jmpbuf)) {
+               /* oops -- we touched something we ought not to have */
+               /* cannot trace caller of "start" */
+               sp->k_entry = MAXINT;
+               sp->k_nargs = 0;
+               db_recover = savejmp;
+               return;
+       }
+
+       addr = get(sp->k_fp + FR_SAVPC, DSP);
+       if (addr == 0) {
+               /* oops -- we touched something we ought not to have */
+               /* cannot trace caller of "start" */
+               sp->k_entry = MAXINT;
+               sp->k_nargs = 0;
+               db_recover = savejmp;
+               return;



Home | Main Index | Thread Index | Old Index