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) ®s->tf_regs[i];
+ }
+
+ sp->k_fp = get(®s->tf_regs[8+6], 0);
+ /* skip sp (a7) */
+ sp->k_pc = get(®s->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