Module Name: src
Committed By: mrg
Date: Mon Aug 17 04:15:34 UTC 2020
Modified Files:
src/sys/arch/mips/include: pcb.h
src/sys/arch/mips/mips: db_trace.c mips_stacktrace.c
src/usr.sbin/crash: Makefile crash.c
Added Files:
src/usr.sbin/crash/arch: mips.c
Log Message:
mostly complete basic port of crash(8) to mips.
tested on mipsel and mips64eb. basic functionality works
on the running kernel, not yet tested on crash dumps.
To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/mips/include/pcb.h
cvs rdiff -u -r1.44 -r1.45 src/sys/arch/mips/mips/db_trace.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/mips/mips/mips_stacktrace.c
cvs rdiff -u -r1.44 -r1.45 src/usr.sbin/crash/Makefile
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/crash/crash.c
cvs rdiff -u -r0 -r1.1 src/usr.sbin/crash/arch/mips.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/include/pcb.h
diff -u src/sys/arch/mips/include/pcb.h:1.25 src/sys/arch/mips/include/pcb.h:1.26
--- src/sys/arch/mips/include/pcb.h:1.25 Mon Aug 17 03:19:35 2020
+++ src/sys/arch/mips/include/pcb.h Mon Aug 17 04:15:33 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.25 2020/08/17 03:19:35 mrg Exp $ */
+/* $NetBSD: pcb.h,v 1.26 2020/08/17 04:15:33 mrg Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -76,4 +76,10 @@ struct md_coredump {
#ifdef _KERNEL
#define PCB_FSR(pcb) ((pcb)->pcb_fpregs.r_regs[_R_FSR - _FPBASE])
#endif
+
+#ifndef _KERNEL
+/* Connect the dots for crash(8). */
+vaddr_t db_mach_addr_cpuswitch(void);
+#endif
+
#endif /*_MIPS_PCB_H_*/
Index: src/sys/arch/mips/mips/db_trace.c
diff -u src/sys/arch/mips/mips/db_trace.c:1.44 src/sys/arch/mips/mips/db_trace.c:1.45
--- src/sys/arch/mips/mips/db_trace.c:1.44 Sat Aug 15 07:42:07 2020
+++ src/sys/arch/mips/mips/db_trace.c Mon Aug 17 04:15:34 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.44 2020/08/15 07:42:07 mrg Exp $ */
+/* $NetBSD: db_trace.c,v 1.45 2020/08/17 04:15:34 mrg Exp $ */
/*
* Mach Operating System
@@ -27,9 +27,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.44 2020/08/15 07:42:07 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.45 2020/08/17 04:15:34 mrg Exp $");
+#ifdef _KERNEL_OPT
#include "opt_ddb.h"
+#endif
#include <sys/types.h>
#include <sys/param.h>
@@ -43,6 +45,8 @@ __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v
#include <machine/db_machdep.h>
#include <machine/locore.h>
+#include <ddb/db_access.h>
+#include <ddb/db_access.h>
#include <ddb/db_interface.h>
#include <ddb/db_output.h>
#include <ddb/db_variables.h>
@@ -81,54 +85,54 @@ int db_mips_variable_func(const struct d
#define DBREGS_REG()
const struct db_variable db_regs[] = {
- { "at", (long *)&ddb_regs.r_regs[_R_AST], DB_SETF_REGS },
- { "v0", (long *)&ddb_regs.r_regs[_R_V0], DB_SETF_REGS },
- { "v1", (long *)&ddb_regs.r_regs[_R_V1], DB_SETF_REGS },
- { "a0", (long *)&ddb_regs.r_regs[_R_A0], DB_SETF_REGS },
- { "a1", (long *)&ddb_regs.r_regs[_R_A1], DB_SETF_REGS },
- { "a2", (long *)&ddb_regs.r_regs[_R_A2], DB_SETF_REGS },
- { "a3", (long *)&ddb_regs.r_regs[_R_A3], DB_SETF_REGS },
+ { "at", (long *)&ddb_regs.r_regs[_R_AST], DB_SETF_REGS, NULL },
+ { "v0", (long *)&ddb_regs.r_regs[_R_V0], DB_SETF_REGS, NULL },
+ { "v1", (long *)&ddb_regs.r_regs[_R_V1], DB_SETF_REGS, NULL },
+ { "a0", (long *)&ddb_regs.r_regs[_R_A0], DB_SETF_REGS, NULL },
+ { "a1", (long *)&ddb_regs.r_regs[_R_A1], DB_SETF_REGS, NULL },
+ { "a2", (long *)&ddb_regs.r_regs[_R_A2], DB_SETF_REGS, NULL },
+ { "a3", (long *)&ddb_regs.r_regs[_R_A3], DB_SETF_REGS, NULL },
#if defined(__mips_n32) || defined(__mips_n64)
- { "a4", (long *)&ddb_regs.r_regs[_R_A4], DB_SETF_REGS },
- { "a5", (long *)&ddb_regs.r_regs[_R_A5], DB_SETF_REGS },
- { "a6", (long *)&ddb_regs.r_regs[_R_A6], DB_SETF_REGS },
- { "a7", (long *)&ddb_regs.r_regs[_R_A7], DB_SETF_REGS },
- { "t0", (long *)&ddb_regs.r_regs[_R_T0], DB_SETF_REGS },
- { "t1", (long *)&ddb_regs.r_regs[_R_T1], DB_SETF_REGS },
- { "t2", (long *)&ddb_regs.r_regs[_R_T2], DB_SETF_REGS },
- { "t3", (long *)&ddb_regs.r_regs[_R_T3], DB_SETF_REGS },
+ { "a4", (long *)&ddb_regs.r_regs[_R_A4], DB_SETF_REGS, NULL },
+ { "a5", (long *)&ddb_regs.r_regs[_R_A5], DB_SETF_REGS, NULL },
+ { "a6", (long *)&ddb_regs.r_regs[_R_A6], DB_SETF_REGS, NULL },
+ { "a7", (long *)&ddb_regs.r_regs[_R_A7], DB_SETF_REGS, NULL },
+ { "t0", (long *)&ddb_regs.r_regs[_R_T0], DB_SETF_REGS, NULL },
+ { "t1", (long *)&ddb_regs.r_regs[_R_T1], DB_SETF_REGS, NULL },
+ { "t2", (long *)&ddb_regs.r_regs[_R_T2], DB_SETF_REGS, NULL },
+ { "t3", (long *)&ddb_regs.r_regs[_R_T3], DB_SETF_REGS, NULL },
#else
- { "t0", (long *)&ddb_regs.r_regs[_R_T0], DB_SETF_REGS },
- { "t1", (long *)&ddb_regs.r_regs[_R_T1], DB_SETF_REGS },
- { "t2", (long *)&ddb_regs.r_regs[_R_T2], DB_SETF_REGS },
- { "t3", (long *)&ddb_regs.r_regs[_R_T3], DB_SETF_REGS },
- { "t4", (long *)&ddb_regs.r_regs[_R_T4], DB_SETF_REGS },
- { "t5", (long *)&ddb_regs.r_regs[_R_T5], DB_SETF_REGS },
- { "t6", (long *)&ddb_regs.r_regs[_R_T6], DB_SETF_REGS },
- { "t7", (long *)&ddb_regs.r_regs[_R_T7], DB_SETF_REGS },
+ { "t0", (long *)&ddb_regs.r_regs[_R_T0], DB_SETF_REGS, NULL },
+ { "t1", (long *)&ddb_regs.r_regs[_R_T1], DB_SETF_REGS, NULL },
+ { "t2", (long *)&ddb_regs.r_regs[_R_T2], DB_SETF_REGS, NULL },
+ { "t3", (long *)&ddb_regs.r_regs[_R_T3], DB_SETF_REGS, NULL },
+ { "t4", (long *)&ddb_regs.r_regs[_R_T4], DB_SETF_REGS, NULL },
+ { "t5", (long *)&ddb_regs.r_regs[_R_T5], DB_SETF_REGS, NULL },
+ { "t6", (long *)&ddb_regs.r_regs[_R_T6], DB_SETF_REGS, NULL },
+ { "t7", (long *)&ddb_regs.r_regs[_R_T7], DB_SETF_REGS, NULL },
#endif /* __mips_n32 || __mips_n64 */
- { "s0", (long *)&ddb_regs.r_regs[_R_S0], DB_SETF_REGS },
- { "s1", (long *)&ddb_regs.r_regs[_R_S1], DB_SETF_REGS },
- { "s2", (long *)&ddb_regs.r_regs[_R_S2], DB_SETF_REGS },
- { "s3", (long *)&ddb_regs.r_regs[_R_S3], DB_SETF_REGS },
- { "s4", (long *)&ddb_regs.r_regs[_R_S4], DB_SETF_REGS },
- { "s5", (long *)&ddb_regs.r_regs[_R_S5], DB_SETF_REGS },
- { "s6", (long *)&ddb_regs.r_regs[_R_S6], DB_SETF_REGS },
- { "s7", (long *)&ddb_regs.r_regs[_R_S7], DB_SETF_REGS },
- { "t8", (long *)&ddb_regs.r_regs[_R_T8], DB_SETF_REGS },
- { "t9", (long *)&ddb_regs.r_regs[_R_T9], DB_SETF_REGS },
- { "k0", (long *)&ddb_regs.r_regs[_R_K0], DB_SETF_REGS },
- { "k1", (long *)&ddb_regs.r_regs[_R_K1], DB_SETF_REGS },
- { "gp", (long *)&ddb_regs.r_regs[_R_GP], DB_SETF_REGS },
- { "sp", (long *)&ddb_regs.r_regs[_R_SP], DB_SETF_REGS },
- { "fp", (long *)&ddb_regs.r_regs[_R_S8], DB_SETF_REGS },/* frame ptr */
- { "ra", (long *)&ddb_regs.r_regs[_R_RA], DB_SETF_REGS },
- { "sr", (long *)&ddb_regs.r_regs[_R_SR], DB_SETF_REGS },
- { "mdlo",(long *)&ddb_regs.r_regs[_R_MULLO], DB_SETF_REGS },
- { "mdhi",(long *)&ddb_regs.r_regs[_R_MULHI], DB_SETF_REGS },
- { "bad", (long *)&ddb_regs.r_regs[_R_BADVADDR], DB_SETF_REGS },
- { "cs", (long *)&ddb_regs.r_regs[_R_CAUSE], DB_SETF_REGS },
- { "pc", (long *)&ddb_regs.r_regs[_R_PC], DB_SETF_REGS },
+ { "s0", (long *)&ddb_regs.r_regs[_R_S0], DB_SETF_REGS, NULL },
+ { "s1", (long *)&ddb_regs.r_regs[_R_S1], DB_SETF_REGS, NULL },
+ { "s2", (long *)&ddb_regs.r_regs[_R_S2], DB_SETF_REGS, NULL },
+ { "s3", (long *)&ddb_regs.r_regs[_R_S3], DB_SETF_REGS, NULL },
+ { "s4", (long *)&ddb_regs.r_regs[_R_S4], DB_SETF_REGS, NULL },
+ { "s5", (long *)&ddb_regs.r_regs[_R_S5], DB_SETF_REGS, NULL },
+ { "s6", (long *)&ddb_regs.r_regs[_R_S6], DB_SETF_REGS, NULL },
+ { "s7", (long *)&ddb_regs.r_regs[_R_S7], DB_SETF_REGS, NULL },
+ { "t8", (long *)&ddb_regs.r_regs[_R_T8], DB_SETF_REGS, NULL },
+ { "t9", (long *)&ddb_regs.r_regs[_R_T9], DB_SETF_REGS, NULL },
+ { "k0", (long *)&ddb_regs.r_regs[_R_K0], DB_SETF_REGS, NULL },
+ { "k1", (long *)&ddb_regs.r_regs[_R_K1], DB_SETF_REGS, NULL },
+ { "gp", (long *)&ddb_regs.r_regs[_R_GP], DB_SETF_REGS, NULL },
+ { "sp", (long *)&ddb_regs.r_regs[_R_SP], DB_SETF_REGS, NULL },
+ { "fp", (long *)&ddb_regs.r_regs[_R_S8], DB_SETF_REGS, NULL },/* frame ptr */
+ { "ra", (long *)&ddb_regs.r_regs[_R_RA], DB_SETF_REGS, NULL },
+ { "sr", (long *)&ddb_regs.r_regs[_R_SR], DB_SETF_REGS, NULL },
+ { "mdlo",(long *)&ddb_regs.r_regs[_R_MULLO], DB_SETF_REGS, NULL },
+ { "mdhi",(long *)&ddb_regs.r_regs[_R_MULHI], DB_SETF_REGS, NULL },
+ { "bad", (long *)&ddb_regs.r_regs[_R_BADVADDR], DB_SETF_REGS, NULL },
+ { "cs", (long *)&ddb_regs.r_regs[_R_CAUSE], DB_SETF_REGS, NULL },
+ { "pc", (long *)&ddb_regs.r_regs[_R_PC], DB_SETF_REGS, NULL },
};
const struct db_variable * const db_eregs = db_regs + __arraycount(db_regs);
@@ -138,11 +142,15 @@ db_stack_trace_print(db_expr_t addr, boo
{
#ifndef DDB_TRACE
struct pcb *pcb;
- struct proc *p;
- struct lwp *l;
+ struct proc p;
+ struct lwp l;
const char *cp = modif;
char c;
bool lwpaddr = false;
+ vaddr_t pc, sp, s8, ra;
+#ifndef _KERNEL
+ mips_label_t label;
+#endif
if (!have_addr) {
struct reg * regs = &ddb_regs;
@@ -166,28 +174,43 @@ db_stack_trace_print(db_expr_t addr, boo
}
if (lwpaddr) {
- l = (struct lwp *)(intptr_t)addr;
- (*pr)("pid %d.%d ", l->l_proc->p_pid, l->l_lid);
+ db_read_bytes(addr, sizeof(l), (char *)&l);
+ db_read_bytes((db_addr_t)l.l_proc, sizeof(p), (char *)&p);
+ (*pr)("pid %d.%d ", p.p_pid, l.l_lid);
} else {
/* "trace/t" */
(*pr)("pid %d ", (int)addr);
- p = proc_find_raw(addr);
- if (p == NULL) {
+#ifdef _KERNEL
+ struct proc *p2 = proc_find_raw(addr);
+ if (p2 == NULL) {
(*pr)("not found\n");
return;
}
- l = LIST_FIRST(&p->p_lwps); /* XXX NJWLWP */
+ l = *LIST_FIRST(&p2->p_lwps); /* XXX NJWLWP */
+#else
+ (*pr)("no proc_find_raw() in crash\n");
+ return;
+#endif
}
- pcb = lwp_getpcb(l);
+ pcb = lwp_getpcb(&l);
(*pr)("at %p\n", pcb);
+#ifdef _KERNEL
+ pc = (vaddr_t)cpu_switchto;
+ sp = pcb->pcb_context.val[_L_SP];
+ s8 = pcb->pcb_context.val[_L_S8];
+ ra = pcb->pcb_context.val[_L_RA];
+#else
+ pc = db_mach_addr_cpuswitch();
+ db_read_bytes((db_addr_t)&pcb->pcb_context, sizeof(label), (char *)&label);
+ sp = label.val[_L_SP];
+ s8 = label.val[_L_S8];
+ ra = label.val[_L_RA];
+#endif
stacktrace_subr(0,0,0,0, /* no args known */
- (vaddr_t)cpu_switchto,
- pcb->pcb_context.val[_L_SP],
- pcb->pcb_context.val[_L_S8],
- pcb->pcb_context.val[_L_RA],
+ pc, sp, s8, ra,
pr);
#else
/*
Index: src/sys/arch/mips/mips/mips_stacktrace.c
diff -u src/sys/arch/mips/mips/mips_stacktrace.c:1.2 src/sys/arch/mips/mips/mips_stacktrace.c:1.3
--- src/sys/arch/mips/mips/mips_stacktrace.c:1.2 Mon Aug 17 03:19:35 2020
+++ src/sys/arch/mips/mips/mips_stacktrace.c Mon Aug 17 04:15:34 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_stacktrace.c,v 1.2 2020/08/17 03:19:35 mrg Exp $ */
+/* $NetBSD: mips_stacktrace.c,v 1.3 2020/08/17 04:15:34 mrg Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_stacktrace.c,v 1.2 2020/08/17 03:19:35 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_stacktrace.c,v 1.3 2020/08/17 04:15:34 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -55,11 +55,16 @@ __KERNEL_RCSID(0, "$NetBSD: mips_stacktr
#include <mips/mips_opcode.h>
#include <mips/stacktrace.h>
+#if defined(_KMEMUSER) && !defined(DDB)
+#define DDB 1
+#endif
+
#ifdef DDB
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#endif
#include <ddb/db_user.h>
+#include <ddb/db_access.h>
#ifdef KGDB
#include <sys/kgdb.h>
@@ -196,7 +201,7 @@ kdbpeek(vaddr_t addr, unsigned *valp)
printf("kdbpeek: NULL\n");
return false;
} else {
- *valp = *(unsigned *)addr;
+ db_read_bytes((db_addr_t)addr, sizeof(unsigned), (char *)valp);
return true;
}
}
@@ -204,7 +209,7 @@ kdbpeek(vaddr_t addr, unsigned *valp)
static mips_reg_t
kdbrpeek(vaddr_t addr, size_t n)
{
- mips_reg_t rc;
+ mips_reg_t rc = 0;
if (addr & (n - 1)) {
printf("kdbrpeek: unaligned address %#"PRIxVADDR"\n", addr);
@@ -212,15 +217,15 @@ kdbrpeek(vaddr_t addr, size_t n)
/* We might have been called from DDB, so do not go there. */
stacktrace();
#endif
- rc = -1 ;
+ rc = -1;
} else if (addr == 0) {
printf("kdbrpeek: NULL\n");
rc = 0xdeadfeed;
} else {
if (sizeof(mips_reg_t) == 8 && n == 8)
- rc = *(int64_t *)addr;
+ db_read_bytes((db_addr_t)addr, sizeof(int64_t), (char *)&rc);
else
- rc = *(int32_t *)addr;
+ db_read_bytes((db_addr_t)addr, sizeof(int32_t), (char *)&rc);
}
return rc;
}
Index: src/usr.sbin/crash/Makefile
diff -u src/usr.sbin/crash/Makefile:1.44 src/usr.sbin/crash/Makefile:1.45
--- src/usr.sbin/crash/Makefile:1.44 Mon Mar 9 05:10:19 2020
+++ src/usr.sbin/crash/Makefile Mon Aug 17 04:15:33 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.44 2020/03/09 05:10:19 rin Exp $
+# $NetBSD: Makefile,v 1.45 2020/08/17 04:15:33 mrg Exp $
PROG= crash
MAN= crash.8
@@ -20,9 +20,13 @@ DPADD+= ${LIBUTIL} ${LIBKVM} ${LIBEDIT}
|| ${MACHINE} == "sparc64" \
|| ${MACHINE_CPU} == "arm" \
|| ${MACHINE_CPU} == "aarch64" \
+ || ${MACHINE_CPU} == "mips" \
|| ${MACHINE_ARCH} == "m68k"
SRCS+= db_trace.c
-.if ${MACHINE_ARCH} != "m68k"
+.if ${MACHINE_CPU} == "mips"
+SRCS+= db_interface.c mips_stacktrace.c
+CPPFLAGS+= -DDDB
+.elif ${MACHINE_ARCH} != "m68k"
SRCS+= db_machdep.c
.endif
REALCRASH=yes
Index: src/usr.sbin/crash/crash.c
diff -u src/usr.sbin/crash/crash.c:1.13 src/usr.sbin/crash/crash.c:1.14
--- src/usr.sbin/crash/crash.c:1.13 Fri Mar 27 00:17:08 2020
+++ src/usr.sbin/crash/crash.c Mon Aug 17 04:15:33 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: crash.c,v 1.13 2020/03/27 00:17:08 ad Exp $ */
+/* $NetBSD: crash.c,v 1.14 2020/08/17 04:15:33 mrg Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: crash.c,v 1.13 2020/03/27 00:17:08 ad Exp $");
+__RCSID("$NetBSD: crash.c,v 1.14 2020/08/17 04:15:33 mrg Exp $");
#endif /* not lint */
#include <ddb/ddb.h>
@@ -41,7 +41,9 @@ __RCSID("$NetBSD: crash.c,v 1.13 2020/03
#include <sys/stat.h>
#include <sys/ioctl.h>
+#ifndef __mips__
#include <machine/frame.h>
+#endif
#include <stdarg.h>
#include <stdlib.h>
Added files:
Index: src/usr.sbin/crash/arch/mips.c
diff -u /dev/null src/usr.sbin/crash/arch/mips.c:1.1
--- /dev/null Mon Aug 17 04:15:34 2020
+++ src/usr.sbin/crash/arch/mips.c Mon Aug 17 04:15:33 2020
@@ -0,0 +1,73 @@
+/* $NetBSD: mips.c,v 1.1 2020/08/17 04:15:33 mrg Exp $ */
+
+/*
+ * Copyright (c) 2020 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: mips.c,v 1.1 2020/08/17 04:15:33 mrg Exp $");
+#endif /* not lint */
+
+#include <ddb/ddb.h>
+
+#include <kvm.h>
+#include <nlist.h>
+#include <err.h>
+#include <stdlib.h>
+
+#include <machine/pcb.h>
+
+#include "extern.h"
+
+static struct nlist nl[] = {
+ { .n_name = "dumppcb" },
+ { .n_name = "cpu_switchto" },
+ { .n_name = NULL },
+};
+
+struct pcb pcb;
+
+void
+db_mach_init(kvm_t *kd)
+{
+
+ if (kvm_nlist(kd, nl) == -1) {
+ errx(EXIT_FAILURE, "kvm_nlist: %s", kvm_geterr(kd));
+ }
+ if ((size_t)kvm_read(kd, nl[0].n_value, &pcb, sizeof(pcb)) !=
+ sizeof(pcb)) {
+ warnx("cannot read dumppcb: %s", kvm_geterr(kd));
+ }
+}
+
+/* Provided for db_trace.c. */
+vaddr_t
+db_mach_addr_cpuswitch(void)
+{
+ return (vaddr_t)nl[1].n_value;
+}