Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jun 2005 18:20:24 +0800
From:      Xin LI <delphij@frontfree.net>
To:        freebsd-arch@FreeBSD.org
Cc:        howardsue@gmail.com
Subject:   How to get stack from every thread when doing crash dump?
Message-ID:  <20050623102024.GA89874@frontfree.net>

next in thread | raw e-mail | index | archive | help

--9zSXsLTf0vkW971A
Content-Type: multipart/mixed; boundary="oyUTqETQ0mS9luUI"
Content-Disposition: inline


--oyUTqETQ0mS9luUI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Dear folks,

Recently I was working with a friend to figure out whether we can do more on
our crashdump mechanism, as dumping the whole core memory is a painful
process when you have some gigabytes of RAM.  Finally, we have implemented
an experimental mini-dump on our local development tree, and adopted some
IA64 MD dump code to provide a MI interface to handle dumping.  A proof-of-
concept patchset is included (see below).  As a side note,=20

One problem with the mini-dump is that, since the mini-dump utilizes:
	dump_write((char *)curthread->td_kstack, curthread->td_kstack_pages * PAGE=
_SIZE);

To write out the stack, and at the point before exception.S, curthread has
been changed, we can only obtain the stack from the current thread, which
may not be enough for analyzing the backtrace.  What can we do to improve
this situation?

Thanks in advance!

--------------------------------------------------------------------------
BTW:  A proof-of-concept patchset is in the attachment, which implements
mini-dump, and adopted the MD code from IA64 dump by turning them to MI
interfaces.  At this time, the idea that peter@ has commented this morning
has not implemented (yet), and we need to do more style cleanups on the
code.

The patchset is HIGHLY EXPERIMENTAL so be warned that there is glitches,
and may boom your box :-)  In order to use it, you need to patch your source
tree with the patchset, and rebuild the kernel as well as savecore(8) and
kgdb related stuff, a full make world/kernel procedure is recommended.

To use minidump you need to specify "-t 1" to kgdb.
-------------------------------------------------------------------------

Cheers,
--=20
Xin LI <delphij frontfree net>	http://www.delphij.net/
See complete headers for GPG key and other information.


--oyUTqETQ0mS9luUI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patchset-howard-minidump
Content-Transfer-Encoding: quoted-printable

Index: src/gnu/usr.bin/gdb/kgdb/Makefile
diff -u src/gnu/usr.bin/gdb/kgdb/Makefile:1.6 src/gnu/usr.bin/gdb/kgdb/Make=
file:1.6.1000.1
--- src/gnu/usr.bin/gdb/kgdb/Makefile:1.6	Mon Feb 21 07:06:03 2005
+++ src/gnu/usr.bin/gdb/kgdb/Makefile	Mon Jun 13 00:50:55 2005
@@ -1,9 +1,11 @@
 # $FreeBSD$
=20
 PROG=3D	kgdb${GDB_SUFFIX}
-SRCS=3D	main.c kthr.c trgt.c trgt_${TARGET_ARCH}.c
+SRCS=3D	main.c kthr.c trgt.c mini_trgt.c full_trgt.c trgt_${TARGET_ARCH}.c
 WARNS?=3D	2
=20
+CFLAGS+=3D-I${.CURDIR}/../../../../sys
+
 BULIBS=3D ${OBJ_BU}/libbfd/libbfd.a ${OBJ_BU}/libopcodes/libopcodes.a \
 	${OBJ_BU}/libiberty/libiberty.a
 GDBLIBS=3D ${OBJ_GDB}/libgdb/libgdb.a
Index: src/gnu/usr.bin/gdb/kgdb/full_trgt.c
diff -u /dev/null src/gnu/usr.bin/gdb/kgdb/full_trgt.c:1.1.1000.1
--- /dev/null	Thu Jun 23 18:02:17 2005
+++ src/gnu/usr.bin/gdb/kgdb/full_trgt.c	Mon Jun 13 00:50:55 2005
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTI=
ES
+ * 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 US=
E,
+ * 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>
+__FBSDID("$FreeBSD: src/gnu/usr.bin/gdb/kgdb/trgt.c,v 1.1 2004/07/25 05:29=
:15 marcel Exp $");
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+#include <err.h>
+#include <kvm.h>
+#include <fcntl.h>
+#include <string.h>
+#include "kgdb.h"
+
+#include <defs.h>
+#include <gdbcmd.h>
+#include <ui-out.h>
+#include <inferior.h>
+#include <target.h>
+
+static kvm_t *kvm;
+
+static int
+kgdb_trgt_xfer_memory_full(CORE_ADDR memaddr, char *myaddr, int len, int w=
rite,
+			   struct mem_attrib *attrib __unused, struct target_ops *target __unus=
ed)
+{
+	int result;
+	if (len =3D=3D 0)
+		return (0);
+
+	if (!write)
+		result =3D kvm_read(kvm, memaddr, myaddr, len);
+	else
+		result =3D kvm_write(kvm, memaddr, myaddr, len);
+	if (result !=3D len)
+		warnx("kvm_read/kvm_write: %s", kvm_geterr(kvm));
+	return result;
+}
+
+void trgt_provide_registers(struct pcb*);
+
+static void
+kgdb_trgt_fetch_registers_full(int regno __unused)
+{
+	struct kthr *kt;
+	struct pcb pcb;
+
+	kt =3D kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
+	if (kt =3D=3D NULL)
+		return;
+	if (core_read(kt->pcb, &pcb, sizeof(pcb)) !=3D sizeof(pcb)) {
+		memset(&pcb, 0, sizeof(pcb));
+	}
+	trgt_provide_registers(&pcb);
+}
+
+static void
+full_kldstat_cmd (char *args, int from_tty)
+{
+	int verbose =3D 0;
+	char** arg;
+	arg =3D buildargv(args);
+	if (arg !=3D NULL) {
+		if (strcmp(arg[0], "-v")) verbose =3D 1;
+	}
+=09
+	uintptr_t addr =3D core_lookup("linkerfile");
+	if (addr !=3D 0) {
+		ui_out_text(uiout, "OK");
+	}
+	ui_out_text(uiout, "\n");
+}
+
+void kgdb_trgt_init_full(struct target_ops* kgdb_trgt_ops, char* kernel, c=
har* vmcore)
+{
+	char *s;
+
+	add_cmd("kld", class_info,
+		full_kldstat_cmd,=20
+		"Lists the modules that were loaded when the kernel crashed.", &cmdlist);
+	kgdb_trgt_ops->to_xfer_memory =3D kgdb_trgt_xfer_memory_full;
+	kgdb_trgt_ops->to_fetch_registers =3D kgdb_trgt_fetch_registers_full;
+
+	s =3D malloc(_POSIX2_LINE_MAX);
+	kvm =3D kvm_openfiles(kernel, vmcore, NULL, O_RDONLY, s);
+	if (kvm =3D=3D NULL)
+		errx(1, s);
+	free(s);
+=09
+	kgdb_thr_init();
+}
Index: src/gnu/usr.bin/gdb/kgdb/kgdb.h
diff -u src/gnu/usr.bin/gdb/kgdb/kgdb.h:1.2 src/gnu/usr.bin/gdb/kgdb/kgdb.h=
:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/kgdb.h:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/kgdb.h	Mon Jun 13 00:50:55 2005
@@ -28,10 +28,10 @@
=20
 #ifndef _KGDB_H_
 #define	_KGDB_H_
+#include <sys/kerneldump.h>
=20
 struct	thread_info;
=20
-extern kvm_t *kvm;
 extern int verbose;
=20
 struct kthr {
@@ -46,9 +46,10 @@
=20
 extern struct kthr *curkthr;
=20
-void kgdb_target(void);
-void kgdb_trgt_fetch_registers(int);
-void kgdb_trgt_store_registers(int);
+void kgdb_target(char* kernel, char* vmcore, dumpcoretype type);
+int  core_read(uintptr_t addr, void* myaddr, int size);
+int  core_write(uintptr_t addr, void* myaddr, int size);
+uintptr_t core_lookup(const char *sym);
=20
 struct kthr *kgdb_thr_first(void);
 struct kthr *kgdb_thr_init(void);
@@ -60,4 +61,9 @@
 struct kthr *kgdb_thr_select(struct kthr *);
 char        *kgdb_thr_extra_thread_info(int);
=20
+struct target_ops;
+
+void kgdb_trgt_init_full(struct target_ops* kgdb_trgt_ops, char* kernel, c=
har* vmcore);
+void kgdb_trgt_init_mini(struct target_ops* kgdb_trgt_ops, char* kernel, c=
har* vmcore);
+
 #endif /* _KGDB_H_ */
Index: src/gnu/usr.bin/gdb/kgdb/kthr.c
diff -u src/gnu/usr.bin/gdb/kgdb/kthr.c:1.2 src/gnu/usr.bin/gdb/kgdb/kthr.c=
:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/kthr.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/kthr.c	Mon Jun 13 00:50:55 2005
@@ -33,7 +33,6 @@
 #include <sys/signal.h>
 #include <err.h>
 #include <inttypes.h>
-#include <kvm.h>
 #include <stdio.h>
 #include <stdlib.h>
=20
@@ -47,24 +46,27 @@
 static struct kthr *first;
 struct kthr *curkthr;
=20
-static uintptr_t
-lookup(const char *sym)
+struct kthr *
+kgdb_thr_first(void)
 {
-	struct nlist nl[2];
-
-	nl[0].n_name =3D (char *)(uintptr_t)sym;
-	nl[1].n_name =3D NULL;
-	if (kvm_nlist(kvm, nl) !=3D 0) {
-		warnx("kvm_nlist(%s): %s", sym, kvm_geterr(kvm));
-		return (0);
-	}
-	return (nl[0].n_value);
+	return (first);
 }
=20
 struct kthr *
-kgdb_thr_first(void)
+kgdb_thr_init_direct(struct pcb *dumppcb, struct thread *pcb, int tid)
 {
-	return (first);
+	struct kthr *kt;
+	dumptid =3D tid;
+=09
+	kt =3D malloc(sizeof(*kt));
+	kt->next =3D NULL;
+	kt->kaddr =3D 0;
+	kt->pcb =3D 0; // dumppcb;
+	kt->kstack =3D pcb->td_kstack;
+	kt->tid =3D tid;
+
+	curkthr =3D kt;
+	return kt;
 }
=20
 struct kthr *
@@ -75,28 +77,26 @@
 	struct kthr *kt;
 	uintptr_t addr, paddr;
=20
-	addr =3D lookup("_allproc");
+	addr =3D core_lookup("_allproc");
 	if (addr =3D=3D 0)
 		return (NULL);
-	kvm_read(kvm, addr, &paddr, sizeof(paddr));
+	core_read(addr, &paddr, sizeof(paddr));
=20
-	dumppcb =3D lookup("_dumppcb");
+	dumppcb =3D core_lookup("_dumppcb");
 	if (dumppcb =3D=3D 0)
 		return (NULL);
=20
-	addr =3D lookup("_dumptid");
+	addr =3D core_lookup("_dumptid");
 	if (addr !=3D 0)
-		kvm_read(kvm, addr, &dumptid, sizeof(dumptid));
+		core_read(addr, &dumptid, sizeof(dumptid));
 	else
 		dumptid =3D -1;
=20
 	while (paddr !=3D 0) {
-		if (kvm_read(kvm, paddr, &p, sizeof(p)) !=3D sizeof(p))
-			warnx("kvm_read: %s", kvm_geterr(kvm));
+	        core_read(paddr, &p, sizeof(p));
 		addr =3D (uintptr_t)TAILQ_FIRST(&p.p_threads);
 		while (addr !=3D 0) {
-			if (kvm_read(kvm, addr, &td, sizeof(td)) !=3D sizeof(td))
-				warnx("kvm_read: %s", kvm_geterr(kvm));
+		        core_read(addr, &td, sizeof(td));
 			kt =3D malloc(sizeof(*kt));
 			kt->next =3D first;
 			kt->kaddr =3D addr;
@@ -188,7 +188,7 @@
 	if (kt =3D=3D NULL)
 		return (NULL);
 	p =3D (struct proc *)kt->paddr;
-	if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) !=3D
+	if (core_read((uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) !=3D
 	    sizeof(comm))
 		return (NULL);
=20
Index: src/gnu/usr.bin/gdb/kgdb/main.c
diff -u src/gnu/usr.bin/gdb/kgdb/main.c:1.6 src/gnu/usr.bin/gdb/kgdb/main.c=
:1.6.1000.1
--- src/gnu/usr.bin/gdb/kgdb/main.c:1.6	Thu Mar  3 02:40:04 2005
+++ src/gnu/usr.bin/gdb/kgdb/main.c	Mon Jun 13 00:50:55 2005
@@ -39,7 +39,6 @@
 #include <err.h>
 #include <fcntl.h>
 #include <inttypes.h>
-#include <kvm.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
@@ -65,10 +64,9 @@
=20
 #include "kgdb.h"
=20
-kvm_t *kvm;
-
 static int dumpnr;
 static int verbose;
+static dumpcoretype dumptype;
=20
 static char crashdir[PATH_MAX];
 static char *kernel;
@@ -82,7 +80,8 @@
 {
=20
 	fprintf(stderr,
-	    "usage: %s [-afqv] [-d crashdir] [-c core | -n dumpnr | -r device]\n"
+	    "usage: %s [-afqv] [-d crashdir] [-c core | -n dumpnr | -r device\n"
+	    "\t| -t dumptype]\n"
 	    "\t[kernel [core]]\n", getprogname());
 	exit(1);
 }
@@ -149,6 +148,9 @@
 			break;
 		}
 	}
+
+	/* Fetch info details */
+
 	fclose(info);
 }
=20
@@ -198,7 +200,7 @@
 	if (remote)
 		push_remote_target (remote, 0);
 	else
-		kgdb_target();
+		kgdb_target(kernel, vmcore, dumptype);
 }
=20
 static void
@@ -209,7 +211,7 @@
 	if (!once) {
 		once =3D 1;
 		kgdb_init_target();
-		kgdb_target();
+		//kgdb_target();
 		print_stack_frame (get_selected_frame (),
                 	frame_relative_level (get_selected_frame ()), 1);
 	}
@@ -246,6 +248,7 @@
 	int a, ch, quiet;
=20
 	dumpnr =3D -1;
+	dumptype =3D FULLDUMP;
=20
 	strlcpy(crashdir, "/var/crash", sizeof(crashdir));
 	s =3D getenv("KGDB_CRASH_DIR");
@@ -269,8 +272,17 @@
=20
 	quiet =3D 0;
=20
-	while ((ch =3D getopt(argc, argv, "ac:d:fn:qr:v")) !=3D -1) {
+	while ((ch =3D getopt(argc, argv, "ac:d:fn:qr:v:t:")) !=3D -1) {
 		switch (ch) {
+		case 't':		=09
+			dumptype =3D strtol(optarg, &s, 0);
+			if (dumptype < 0 || dumptype > ASCIIDUMP || *s !=3D '\0') {
+				warnx("option %c: invalid kernel dump type",
+				      optopt);
+				usage();
+				/* NOTREACHED */
+			}
+			break;
 		case 'a':
 			annotation_level++;
 			break;
@@ -404,15 +416,6 @@
 			warnx("kernel image: %s", kernel);
 	}
=20
-	if (remote =3D=3D NULL) {
-		s =3D malloc(_POSIX2_LINE_MAX);
-		kvm =3D kvm_openfiles(kernel, vmcore, NULL, O_RDONLY, s);
-		if (kvm =3D=3D NULL)
-			errx(1, s);
-		free(s);
-		kgdb_thr_init();
-	}
-
 	/* The libgdb code uses optind too. Reset it... */
 	optind =3D 0;
=20
Index: src/gnu/usr.bin/gdb/kgdb/mini_trgt.c
diff -u /dev/null src/gnu/usr.bin/gdb/kgdb/mini_trgt.c:1.1.1000.1
--- /dev/null	Thu Jun 23 18:02:17 2005
+++ src/gnu/usr.bin/gdb/kgdb/mini_trgt.c	Mon Jun 13 00:50:55 2005
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTI=
ES
+ * 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 US=
E,
+ * 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>
+__FBSDID("$FreeBSD: src/gnu/usr.bin/gdb/kgdb/trgt.c,v 1.1 2004/07/25 05:29=
:15 marcel Exp $");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/types.h>
+#include <machine/pcb.h>
+#include <err.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include "kgdb.h"
+
+#include <defs.h>
+#include <gdbcmd.h>
+#include <ui-out.h>
+#include <inferior.h>
+#include <target.h>
+
+#define PCB_OFFSET (0)
+#define TID_OFFSET (PCB_OFFSET + sizeof(struct pcb))
+#define THR_OFFSET (TID_OFFSET + sizeof(int))
+
+static int corefd;
+static int kernelfd;
+static struct pcb dumppcb;
+static int tid;
+static struct thread thr;
+
+static CORE_ADDR minoff, maxoff;
+static char *dumpmem;
+
+static off_t kernel_len;
+static CORE_ADDR kernel_base =3D 0xc0400000;
+
+static int
+kgdb_trgt_xfer_memory_mini(CORE_ADDR memaddr, char *myaddr, int len, int w=
rite,
+			   struct mem_attrib *attrib __unused, struct target_ops *target __unus=
ed)
+{
+	if (write =3D=3D 0 && memaddr >=3D minoff && (memaddr + len) < maxoff) {
+		bcopy(dumpmem + (memaddr - minoff), myaddr, len);
+		return len;
+	}
+=09
+
+	if (write =3D=3D 0 && memaddr >=3D kernel_base && (memaddr + len) < (kern=
el_base + kernel_len)) {
+		lseek(kernelfd, memaddr - kernel_base, SEEK_SET);
+		read(kernelfd, myaddr, len);
+		return len;
+	}
+=09
+	//bzero(myaddr, len);=09
+	return -1;
+}
+
+void trgt_provide_registers(struct pcb*);
+
+static void
+kgdb_trgt_fetch_registers_mini(int regno __unused)
+{
+	trgt_provide_registers(&dumppcb);
+}
+
+static void
+load_file()
+{
+	lseek(corefd, 0, SEEK_SET);
+	read(corefd, &dumppcb, sizeof(struct pcb));
+	read(corefd, &tid, sizeof(tid));
+	read(corefd, &thr, sizeof(thr));
+
+	minoff =3D thr.td_kstack;
+	maxoff =3D thr.td_kstack + PAGE_SIZE * thr.td_kstack_pages;
+=09
+	dumpmem =3D malloc(maxoff - minoff);
+	read(corefd, dumpmem, maxoff - minoff);
+
+	kernel_len =3D lseek(kernelfd, 0, SEEK_END);
+}
+
+struct kthr *kgdb_thr_init_direct(struct pcb *dumppcb, struct thread *pcb,=
 int tid);
+
+void kgdb_trgt_init_mini(struct target_ops* kgdb_trgt_ops, char* kernel, c=
har* vmcore)
+{
+	kgdb_trgt_ops->to_xfer_memory =3D kgdb_trgt_xfer_memory_mini;
+	kgdb_trgt_ops->to_fetch_registers =3D kgdb_trgt_fetch_registers_mini;
+=09
+	corefd =3D open(vmcore, O_RDONLY);
+	kernelfd =3D open(kernel, O_RDONLY);
+	if (corefd =3D=3D -1 || kernelfd =3D=3D -1)
+		errx(1, "Can not open core or kernel.");
+	load_file();
+
+	kgdb_thr_init_direct(&dumppcb, &thr, tid);
+}
Index: src/gnu/usr.bin/gdb/kgdb/trgt.c
diff -u src/gnu/usr.bin/gdb/kgdb/trgt.c:1.2 src/gnu/usr.bin/gdb/kgdb/trgt.c=
:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/trgt.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/trgt.c	Mon Jun 13 00:50:55 2005
@@ -31,7 +31,10 @@
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 #include <sys/user.h>
-#include <kvm.h>
+#include <machine/pcb.h>
+#include <nlist.h>
+#include <fcntl.h>
+#include <string.h>
=20
 #include <defs.h>
 #include <command.h>
@@ -96,13 +99,8 @@
 kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
     struct mem_attrib *attrib __unused, struct target_ops *target __unused)
 {
-	if (len =3D=3D 0)
-		return (0);
-
-	if (!write)
-		return (kvm_read(kvm, memaddr, myaddr, len));
-	else
-		return (kvm_write(kvm, memaddr, myaddr, len));
+	fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+	return (0);
 }
=20
 static void
@@ -127,9 +125,6 @@
 	if (!arg)
 		error_no_arg ("proc address for the new context");
=20
-	if (kvm =3D=3D NULL)
-		error ("no kernel core file");
-
 	addr =3D (CORE_ADDR) parse_and_eval_address (arg);
=20
 	if (!INKERNEL (addr)) {
@@ -153,9 +148,6 @@
 	if (!arg)
 		error_no_arg ("TID or thread address for the new context");
=20
-	if (kvm =3D=3D NULL)
-		error ("no kernel core file");
-
 	addr =3D (CORE_ADDR) parse_and_eval_address (arg);
=20
 	if (!INKERNEL (addr)) {
@@ -170,12 +162,56 @@
 	kgdb_switch_to_thread(thr);
 }
=20
+int core_read(uintptr_t memaddr, void *myaddr, int len)
+{
+  return (kgdb_trgt_ops.to_xfer_memory(memaddr, myaddr, len, 0, NULL, NULL=
));
+}
+
+int core_write(uintptr_t memaddr, void *myaddr, int len)
+{
+  return (kgdb_trgt_ops.to_xfer_memory(memaddr, myaddr, len, 1, NULL, NULL=
));
+}
+=20
+static int nlfd;
+/* from src/lib/libc/gen/nlist.c */
+int __fdnlist(int, struct nlist *);
+=20
+uintptr_t core_lookup(const char *sym)
+{
+  struct nlist nl[2];
+=20
+  nl[0].n_name =3D (char *)(uintptr_t)sym;
+  nl[1].n_name =3D NULL;
+  if (__fdnlist(nlfd, nl) !=3D 0) {
+    return (0);
+  }
+  return (nl[0].n_value);
+}
+
+static void
+kgdb_trgt_fetch_registers(int regno __unused)
+{
+  fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+}
+
+static void
+kgdb_trgt_store_registers(int regno __unused)
+{
+  fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+}
+
 void
-kgdb_target(void)
+kgdb_target(char* kernel, char* vmcore, dumpcoretype type)
 {
 	struct kthr *kt;
 	struct thread_info *ti;
=20
+	if (kernel !=3D NULL) {
+	  nlfd =3D open(kernel, O_RDONLY, 0);
+	  if (nlfd !=3D -1)
+ 	    fcntl(nlfd, F_SETFD, FD_CLOEXEC);
+	}
+
 	kgdb_trgt_ops.to_magic =3D OPS_MAGIC;
 	kgdb_trgt_ops.to_shortname =3D "kernel";
 	kgdb_trgt_ops.to_longname =3D "kernel core files.";
@@ -192,6 +228,18 @@
 	kgdb_trgt_ops.to_store_registers =3D kgdb_trgt_store_registers;
 	kgdb_trgt_ops.to_thread_alive =3D kgdb_trgt_thread_alive;
 	kgdb_trgt_ops.to_xfer_memory =3D kgdb_trgt_xfer_memory;
+=09
+	switch(type) {
+	case FULLDUMP:
+		kgdb_trgt_init_full(&kgdb_trgt_ops, kernel, vmcore);
+		break;
+	case MINIDUMP:
+		kgdb_trgt_init_mini(&kgdb_trgt_ops, kernel, vmcore);
+		break;
+	default:
+		return;
+	}
+
 	add_target(&kgdb_trgt_ops);
 	push_target(&kgdb_trgt_ops);
=20
@@ -200,7 +248,8 @@
 		ti =3D add_thread(ptid_build(kt->pid, 0, kt->tid));
 		kt =3D kgdb_thr_next(kt);
 	}
-	inferior_ptid =3D ptid_build(curkthr->pid, 0, curkthr->tid);
+	if (curkthr !=3D NULL)
+	        inferior_ptid =3D ptid_build(curkthr->tid, 0, 0);
 	add_com ("proc", class_obscure, kgdb_set_proc_cmd,
 	   "Set current process context");
 	add_com ("tid", class_obscure, kgdb_set_tid_cmd,
Index: src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
diff -u src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c:1.2 src/gnu/usr.bin/gdb/kgdb/=
trgt_alpha.c:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c	Mon Jun 13 00:50:55 2005
@@ -29,9 +29,6 @@
=20
 #include <sys/types.h>
 #include <machine/pcb.h>
-#include <err.h>
-#include <kvm.h>
-#include <string.h>
=20
 #include "kgdb.h"
=20
@@ -42,32 +39,15 @@
 #include <regcache.h>
=20
 void
-kgdb_trgt_fetch_registers(int regno __unused)
+trgt_provide_registers(struct pcb *pcb)
 {
-	struct kthr *kt;
-	struct pcb pcb;
-
-	kt =3D kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
-	if (kt =3D=3D NULL)
-		return;
-	if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) !=3D sizeof(pcb)) {
-		warnx("kvm_read: %s", kvm_geterr(kvm));
-		memset(&pcb, 0, sizeof(pcb));
-	}
-
-	supply_register(9, (char *)&pcb.pcb_context[0]);
-	supply_register(10, (char *)&pcb.pcb_context[1]);
-	supply_register(11, (char *)&pcb.pcb_context[2]);
-	supply_register(12, (char *)&pcb.pcb_context[3]);
-	supply_register(13, (char *)&pcb.pcb_context[4]);
-	supply_register(14, (char *)&pcb.pcb_context[5]);
-	supply_register(15, (char *)&pcb.pcb_context[6]);
-	supply_register(30, (char *)&pcb.pcb_hw.apcb_ksp);
-	supply_register(64, (char *)&pcb.pcb_context[7]);
-}
-
-void
-kgdb_trgt_store_registers(int regno __unused)
-{
-	fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+	supply_register(9, (char *)&pcb->pcb_context[0]);
+	supply_register(10, (char *)&pcb->pcb_context[1]);
+	supply_register(11, (char *)&pcb->pcb_context[2]);
+	supply_register(12, (char *)&pcb->pcb_context[3]);
+	supply_register(13, (char *)&pcb->pcb_context[4]);
+	supply_register(14, (char *)&pcb->pcb_context[5]);
+	supply_register(15, (char *)&pcb->pcb_context[6]);
+	supply_register(30, (char *)&pcb->pcb_hw.apcb_ksp);
+	supply_register(64, (char *)&pcb->pcb_context[7]);
 }
Index: src/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
diff -u src/gnu/usr.bin/gdb/kgdb/trgt_amd64.c:1.2 src/gnu/usr.bin/gdb/kgdb/=
trgt_amd64.c:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/trgt_amd64.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/trgt_amd64.c	Mon Jun 13 00:50:55 2005
@@ -29,9 +29,6 @@
=20
 #include <sys/types.h>
 #include <machine/pcb.h>
-#include <err.h>
-#include <kvm.h>
-#include <string.h>
=20
 #include "kgdb.h"
=20
@@ -42,32 +39,15 @@
 #include <regcache.h>
=20
 void
-kgdb_trgt_fetch_registers(int regno __unused)
+trgt_provide_registers(struct pcb *pcb)
 {
-	struct kthr *kt;
-	struct pcb pcb;
-
-	kt =3D kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
-	if (kt =3D=3D NULL)
-		return;
-	if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) !=3D sizeof(pcb)) {
-		warnx("kvm_read: %s", kvm_geterr(kvm));
-		memset(&pcb, 0, sizeof(pcb));
-	}
-
-	supply_register(1, (char *)&pcb.pcb_rbx);
-	supply_register(6, (char *)&pcb.pcb_rbp);
-	supply_register(7, (char *)&pcb.pcb_rsp);
-	supply_register(12, (char *)&pcb.pcb_r12);
-	supply_register(13, (char *)&pcb.pcb_r13);
-	supply_register(14, (char *)&pcb.pcb_r14);
-	supply_register(15, (char *)&pcb.pcb_r15);
-	supply_register(16, (char *)&pcb.pcb_rip);
-	supply_register(17, (char *)&pcb.pcb_rflags);
-}
-
-void
-kgdb_trgt_store_registers(int regno __unused)
-{
-	fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+	supply_register(1, (char *)&pcb->pcb_rbx);
+	supply_register(6, (char *)&pcb->pcb_rbp);
+	supply_register(7, (char *)&pcb->pcb_rsp);
+	supply_register(12, (char *)&pcb->pcb_r12);
+	supply_register(13, (char *)&pcb->pcb_r13);
+	supply_register(14, (char *)&pcb->pcb_r14);
+	supply_register(15, (char *)&pcb->pcb_r15);
+	supply_register(16, (char *)&pcb->pcb_rip);
+	supply_register(17, (char *)&pcb->pcb_rflags);
 }
Index: src/gnu/usr.bin/gdb/kgdb/trgt_i386.c
diff -u src/gnu/usr.bin/gdb/kgdb/trgt_i386.c:1.2 src/gnu/usr.bin/gdb/kgdb/t=
rgt_i386.c:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/trgt_i386.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/trgt_i386.c	Mon Jun 13 00:50:55 2005
@@ -29,9 +29,6 @@
=20
 #include <sys/types.h>
 #include <machine/pcb.h>
-#include <err.h>
-#include <kvm.h>
-#include <string.h>
=20
 #include "kgdb.h"
=20
@@ -42,28 +39,12 @@
 #include <regcache.h>
=20
 void
-kgdb_trgt_fetch_registers(int regno __unused)
+trgt_provide_registers(struct pcb *pcb)
 {
-	struct kthr *kt;
-	struct pcb pcb;
-
-	kt =3D kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
-	if (kt =3D=3D NULL)
-		return;
-	if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) !=3D sizeof(pcb)) {
-		warnx("kvm_read: %s", kvm_geterr(kvm));
-		memset(&pcb, 0, sizeof(pcb));
-	}
-	supply_register(3, (char *)&pcb.pcb_ebx);
-	supply_register(4, (char *)&pcb.pcb_esp);
-	supply_register(5, (char *)&pcb.pcb_ebp);
-	supply_register(6, (char *)&pcb.pcb_esi);
-	supply_register(7, (char *)&pcb.pcb_edi);
-	supply_register(8, (char *)&pcb.pcb_eip);
-}
-
-void
-kgdb_trgt_store_registers(int regno __unused)
-{
-	fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+	supply_register(3, (char *)&pcb->pcb_ebx);
+	supply_register(4, (char *)&pcb->pcb_esp);
+	supply_register(5, (char *)&pcb->pcb_ebp);
+	supply_register(6, (char *)&pcb->pcb_esi);
+	supply_register(7, (char *)&pcb->pcb_edi);
+	supply_register(8, (char *)&pcb->pcb_eip);
 }
Index: src/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
diff -u src/gnu/usr.bin/gdb/kgdb/trgt_ia64.c:1.2 src/gnu/usr.bin/gdb/kgdb/t=
rgt_ia64.c:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/trgt_ia64.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/trgt_ia64.c	Mon Jun 13 00:50:55 2005
@@ -30,9 +30,6 @@
 #include <sys/types.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
-#include <err.h>
-#include <kvm.h>
-#include <string.h>
=20
 #include "kgdb.h"
=20
@@ -43,73 +40,63 @@
 #include <regcache.h>
=20
 void
-kgdb_trgt_fetch_registers(int regno __unused)
+trgt_provide_registers(struct pcb *pcb)
 {
-	struct kthr *kt;
-	struct pcb pcb;
 	uint64_t r;
=20
-	kt =3D kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
-	if (kt =3D=3D NULL)
-		return;
-	if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) !=3D sizeof(pcb)) {
-		warnx("kvm_read: %s", kvm_geterr(kvm));
-		memset(&pcb, 0, sizeof(pcb));
-	}
-
 	/* Registers 0-127: general registers. */
-	supply_register(1, (char *)&pcb.pcb_special.gp);
-	supply_register(4, (char *)&pcb.pcb_preserved.gr4);
-	supply_register(5, (char *)&pcb.pcb_preserved.gr5);
-	supply_register(6, (char *)&pcb.pcb_preserved.gr6);
-	supply_register(7, (char *)&pcb.pcb_preserved.gr7);
-	supply_register(12, (char *)&pcb.pcb_special.sp);
-	supply_register(13, (char *)&pcb.pcb_special.tp);
+	supply_register(1, (char *)&pcb->pcb_special.gp);
+	supply_register(4, (char *)&pcb->pcb_preserved.gr4);
+	supply_register(5, (char *)&pcb->pcb_preserved.gr5);
+	supply_register(6, (char *)&pcb->pcb_preserved.gr6);
+	supply_register(7, (char *)&pcb->pcb_preserved.gr7);
+	supply_register(12, (char *)&pcb->pcb_special.sp);
+	supply_register(13, (char *)&pcb->pcb_special.tp);
=20
 	/* Registers 128-255: floating-point registers. */
-	supply_register(130, (char *)&pcb.pcb_preserved_fp.fr2);
-	supply_register(131, (char *)&pcb.pcb_preserved_fp.fr3);
-	supply_register(132, (char *)&pcb.pcb_preserved_fp.fr4);
-	supply_register(133, (char *)&pcb.pcb_preserved_fp.fr5);
-	supply_register(144, (char *)&pcb.pcb_preserved_fp.fr16);
-	supply_register(145, (char *)&pcb.pcb_preserved_fp.fr17);
-	supply_register(146, (char *)&pcb.pcb_preserved_fp.fr18);
-	supply_register(147, (char *)&pcb.pcb_preserved_fp.fr19);
-	supply_register(148, (char *)&pcb.pcb_preserved_fp.fr20);
-	supply_register(149, (char *)&pcb.pcb_preserved_fp.fr21);
-	supply_register(150, (char *)&pcb.pcb_preserved_fp.fr22);
-	supply_register(151, (char *)&pcb.pcb_preserved_fp.fr23);
-	supply_register(152, (char *)&pcb.pcb_preserved_fp.fr24);
-	supply_register(153, (char *)&pcb.pcb_preserved_fp.fr25);
-	supply_register(154, (char *)&pcb.pcb_preserved_fp.fr26);
-	supply_register(155, (char *)&pcb.pcb_preserved_fp.fr27);
-	supply_register(156, (char *)&pcb.pcb_preserved_fp.fr28);
-	supply_register(157, (char *)&pcb.pcb_preserved_fp.fr29);
-	supply_register(158, (char *)&pcb.pcb_preserved_fp.fr30);
-	supply_register(159, (char *)&pcb.pcb_preserved_fp.fr31);
+	supply_register(130, (char *)&pcb->pcb_preserved_fp.fr2);
+	supply_register(131, (char *)&pcb->pcb_preserved_fp.fr3);
+	supply_register(132, (char *)&pcb->pcb_preserved_fp.fr4);
+	supply_register(133, (char *)&pcb->pcb_preserved_fp.fr5);
+	supply_register(144, (char *)&pcb->pcb_preserved_fp.fr16);
+	supply_register(145, (char *)&pcb->pcb_preserved_fp.fr17);
+	supply_register(146, (char *)&pcb->pcb_preserved_fp.fr18);
+	supply_register(147, (char *)&pcb->pcb_preserved_fp.fr19);
+	supply_register(148, (char *)&pcb->pcb_preserved_fp.fr20);
+	supply_register(149, (char *)&pcb->pcb_preserved_fp.fr21);
+	supply_register(150, (char *)&pcb->pcb_preserved_fp.fr22);
+	supply_register(151, (char *)&pcb->pcb_preserved_fp.fr23);
+	supply_register(152, (char *)&pcb->pcb_preserved_fp.fr24);
+	supply_register(153, (char *)&pcb->pcb_preserved_fp.fr25);
+	supply_register(154, (char *)&pcb->pcb_preserved_fp.fr26);
+	supply_register(155, (char *)&pcb->pcb_preserved_fp.fr27);
+	supply_register(156, (char *)&pcb->pcb_preserved_fp.fr28);
+	supply_register(157, (char *)&pcb->pcb_preserved_fp.fr29);
+	supply_register(158, (char *)&pcb->pcb_preserved_fp.fr30);
+	supply_register(159, (char *)&pcb->pcb_preserved_fp.fr31);
=20
 	/* Registers 320-327: branch registers. */
 	if (pcb.pcb_special.__spare =3D=3D ~0UL)
-		supply_register(320, (char *)&pcb.pcb_special.rp);
-	supply_register(321, (char *)&pcb.pcb_preserved.br1);
-	supply_register(322, (char *)&pcb.pcb_preserved.br2);
-	supply_register(323, (char *)&pcb.pcb_preserved.br3);
-	supply_register(324, (char *)&pcb.pcb_preserved.br4);
-	supply_register(325, (char *)&pcb.pcb_preserved.br5);
+		supply_register(320, (char *)&pcb->pcb_special.rp);
+	supply_register(321, (char *)&pcb->pcb_preserved.br1);
+	supply_register(322, (char *)&pcb->pcb_preserved.br2);
+	supply_register(323, (char *)&pcb->pcb_preserved.br3);
+	supply_register(324, (char *)&pcb->pcb_preserved.br4);
+	supply_register(325, (char *)&pcb->pcb_preserved.br5);
=20
 	/* Registers 328-333: misc. other registers. */
-	supply_register(330, (char *)&pcb.pcb_special.pr);
+	supply_register(330, (char *)&pcb->pcb_special.pr);
 	if (pcb.pcb_special.__spare =3D=3D ~0UL) {
 		r =3D pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3);
 		supply_register(331, (char *)&r);
-		supply_register(333, (char *)&pcb.pcb_special.cfm);
+		supply_register(333, (char *)&pcb->pcb_special.cfm);
 	} else {
-		supply_register(331, (char *)&pcb.pcb_special.rp);
-		supply_register(333, (char *)&pcb.pcb_special.pfs);
+		supply_register(331, (char *)&pcb->pcb_special.rp);
+		supply_register(333, (char *)&pcb->pcb_special.pfs);
 	}
=20
 	/* Registers 334-461: application registers. */
-	supply_register(350, (char *)&pcb.pcb_special.rsc);
+	supply_register(350, (char *)&pcb->pcb_special.rsc);
 	r =3D pcb.pcb_special.bspstore;
 	if (pcb.pcb_special.__spare =3D=3D ~0UL)
 		r +=3D pcb.pcb_special.ndirty;
@@ -118,16 +105,10 @@
 		    IA64_CFM_SOL(pcb.pcb_special.pfs));
 	supply_register(351, (char *)&r);	/* bsp */
 	supply_register(352, (char *)&r);	/* bspstore */
-	supply_register(353, (char *)&pcb.pcb_special.rnat);
-	supply_register(370, (char *)&pcb.pcb_special.unat);
-	supply_register(374, (char *)&pcb.pcb_special.fpsr);
+	supply_register(353, (char *)&pcb->pcb_special.rnat);
+	supply_register(370, (char *)&pcb->pcb_special.unat);
+	supply_register(374, (char *)&pcb->pcb_special.fpsr);
 	if (pcb.pcb_special.__spare =3D=3D ~0UL)
-		supply_register(398, (char *)&pcb.pcb_special.pfs);
-	supply_register(399, (char *)&pcb.pcb_preserved.lc);
-}
-
-void
-kgdb_trgt_store_registers(int regno __unused)
-{
-	fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+		supply_register(398, (char *)&pcb->pcb_special.pfs);
+	supply_register(399, (char *)&pcb->pcb_preserved.lc);
 }
Index: src/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
diff -u src/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c:1.2 src/gnu/usr.bin/gdb/kgd=
b/trgt_sparc64.c:1.2.1000.1
--- src/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c:1.2	Mon Feb 21 06:55:07 2005
+++ src/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c	Mon Jun 13 00:50:55 2005
@@ -30,9 +30,6 @@
 #include <sys/types.h>
 #include <machine/asm.h>
 #include <machine/pcb.h>
-#include <err.h>
-#include <kvm.h>
-#include <string.h>
=20
 #include "kgdb.h"
=20
@@ -43,39 +40,23 @@
 #include <regcache.h>
=20
 void
-kgdb_trgt_fetch_registers(int regno __unused)
+trgt_provide_registers(struct pcb *pcb)
 {
-	struct kthr *kt;
-	struct pcb pcb;
 	uint64_t r;
=20
-	kt =3D kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
-	if (kt =3D=3D NULL)
-		return;
-	if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) !=3D sizeof(pcb)) {
-		warnx("kvm_read: %s", kvm_geterr(kvm));
-		memset(&pcb, 0, sizeof(pcb));
-	}
-
 	/* 0-7: global registers (g0-g7) */
=20
 	/* 8-15: output registers (o0-o7) */
-	r =3D pcb.pcb_sp - CCFSZ;
+	r =3D pcb->pcb_sp - CCFSZ;
 	supply_register(14, (char *)&r);
=20
 	/* 16-23: local registers (l0-l7) */
=20
 	/* 24-31: input registers (i0-i7) */
-	supply_register(30, (char *)&pcb.pcb_sp);
+	supply_register(30, (char *)&pcb->pcb_sp);
=20
 	/* 32-63: single precision FP (f0-f31) */
=20
 	/* 64-79: double precision FP (f32-f62) */
-	supply_register(80, (char *)&pcb.pcb_pc);
-}
-
-void
-kgdb_trgt_store_registers(int regno __unused)
-{
-	fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
+	supply_register(80, (char *)&pcb->pcb_pc);
 }
Index: src/sbin/savecore/savecore.c
diff -u src/sbin/savecore/savecore.c:1.75 src/sbin/savecore/savecore.c:1.74=
.1000.3
--- src/sbin/savecore/savecore.c:1.75	Tue Jun 21 04:01:29 2005
+++ src/sbin/savecore/savecore.c	Tue Jun 21 08:45:06 2005
@@ -107,7 +107,18 @@
=20
 	fprintf(f, "Dump header from device %s\n", device);
 	fprintf(f, "  Architecture: %s\n", h->architecture);
-	fprintf(f, "  Architecture Version: %u\n", h->architectureversion);
+	fprintf(f, "  Dumptype: ");
+	switch(h->dumptype) {
+		case MINIDUMP:
+			fprintf(f, "Mini Dump\n");
+			break;
+		case ASCIIDUMP:
+			fprintf(f, "ASCII Dump\n");
+			break;
+		case FULLDUMP:
+		default:
+			fprintf(f, "Full Dump\n");
+	}
 	dumplen =3D dtoh64(h->dumplength);
 	fprintf(f, "  Dump Length: %lldB (%lld MB)\n", (long long)dumplen,
 	    (long long)(dumplen >> 20));
Index: src/sys/alpha/alpha/dump_machdep.c
diff -u src/sys/alpha/alpha/dump_machdep.c:1.6 src/sys/alpha/alpha/dump_mac=
hdep.c:1.6.1000.1
--- src/sys/alpha/alpha/dump_machdep.c:1.6	Tue Dec 23 10:36:41 2003
+++ src/sys/alpha/alpha/dump_machdep.c	Thu Jun 16 20:35:37 2005
@@ -64,7 +64,7 @@
 	strcpy(kdh.magic, KERNELDUMPMAGIC);
 	strcpy(kdh.architecture, "alpha");
 	kdh.version =3D htod32(KERNELDUMPVERSION);
-	kdh.architectureversion =3D htod32(KERNELDUMP_ALPHA_VERSION);
+	kdh.dumptype =3D htod32(FULLDUMP);
 	kdh.dumplength =3D htod64(Maxmem * (off_t)PAGE_SIZE);
 	kdh.dumptime =3D htod64(time_second);
 	kdh.blocksize =3D htod32(di->blocksize);
Index: src/sys/amd64/amd64/dump_machdep.c
diff -u src/sys/amd64/amd64/dump_machdep.c:1.9 src/sys/amd64/amd64/dump_mac=
hdep.c:1.9.1000.1
--- src/sys/amd64/amd64/dump_machdep.c:1.9	Sat Jul 26 05:15:44 2003
+++ src/sys/amd64/amd64/dump_machdep.c	Thu Jun 16 20:35:38 2005
@@ -66,7 +66,7 @@
 	strcpy(kdh.magic, KERNELDUMPMAGIC);
 	strcpy(kdh.architecture, "amd64");
 	kdh.version =3D htod32(KERNELDUMPVERSION);
-	kdh.architectureversion =3D htod32(KERNELDUMP_I386_VERSION);
+	kdh.dumptype =3D htod32(FULLDUMP);
 	kdh.dumplength =3D htod64(Maxmem * (off_t)PAGE_SIZE);
 	kdh.dumptime =3D htod64(time_second);
 	kdh.blocksize =3D htod32(di->blocksize);
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1030 src/sys/conf/files:1.1029.1000.2
--- src/sys/conf/files:1.1030	Tue Jun 21 18:17:54 2005
+++ src/sys/conf/files	Thu Jun 23 00:31:08 2005
@@ -1226,6 +1226,7 @@
 kern/subr_clock.c		optional genclock
 kern/subr_devstat.c		standard
 kern/subr_disk.c		standard
+kern/subr_dump.c		standard
 kern/subr_eventhandler.c	standard
 kern/subr_hints.c		standard
 kern/subr_kdb.c			standard
Index: src/sys/dev/null/null.c
diff -u src/sys/dev/null/null.c:1.31 src/sys/dev/null/null.c:1.31.1000.1
--- src/sys/dev/null/null.c:1.31	Mon Feb 28 06:00:45 2005
+++ src/sys/dev/null/null.c	Mon Jun 20 09:32:14 2005
@@ -34,6 +34,7 @@
 #include <sys/conf.h>
 #include <sys/uio.h>
 #include <sys/kernel.h>
+#include <sys/kerneldump.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/disk.h>
Index: src/sys/geom/geom_dev.c
diff -u src/sys/geom/geom_dev.c:1.89 src/sys/geom/geom_dev.c:1.89.1000.1
--- src/sys/geom/geom_dev.c:1.89	Fri Mar 18 14:57:58 2005
+++ src/sys/geom/geom_dev.c	Mon Jun 20 09:32:13 2005
@@ -41,6 +41,7 @@
 #include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/conf.h>
+#include <sys/kerneldump.h>
 #include <sys/bio.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
Index: src/sys/geom/geom_disk.c
diff -u src/sys/geom/geom_disk.c:1.96 src/sys/geom/geom_disk.c:1.96.1000.1
--- src/sys/geom/geom_disk.c:1.96	Fri Mar 18 15:01:31 2005
+++ src/sys/geom/geom_disk.c	Sun Jun 19 23:43:44 2005
@@ -46,6 +46,7 @@
 #include <sys/conf.h>
 #include <sys/fcntl.h>
 #include <sys/malloc.h>
+#include <sys/kerneldump.h>
 #include <sys/sysctl.h>
 #include <sys/devicestat.h>
 #include <machine/md_var.h>
Index: src/sys/i386/i386/dump_machdep.c
diff -u src/sys/i386/i386/dump_machdep.c:1.9 src/sys/i386/i386/dump_machdep=
.c:1.9.1000.3
--- src/sys/i386/i386/dump_machdep.c:1.9	Mon Aug 25 17:48:46 2003
+++ src/sys/i386/i386/dump_machdep.c	Mon Jun 20 09:32:13 2005
@@ -46,57 +46,21 @@
 #include <vm/pmap.h>
 #include <machine/md_var.h>
=20
-CTASSERT(sizeof(struct kerneldumpheader) =3D=3D 512);
-
-static struct kerneldumpheader kdh;
-
 void
 dumpsys(struct dumperinfo *di)
 {
-	off_t dumplo;
 	vm_offset_t a, addr;
 	u_int count, left, u;
 	void *va;
-	int i, mb;
+	int i;
 	int c;
=20
-	printf("Dumping %ld MB\n", Maxmem / (1024*1024 / PAGE_SIZE));
-
-	/* Fill in the kernel dump header */
-	strcpy(kdh.magic, KERNELDUMPMAGIC);
-	strcpy(kdh.architecture, "i386");
-	kdh.version =3D htod32(KERNELDUMPVERSION);
-	kdh.architectureversion =3D htod32(KERNELDUMP_I386_VERSION);
-	kdh.dumplength =3D htod64(Maxmem * (off_t)PAGE_SIZE);
-	kdh.dumptime =3D htod64(time_second);
-	kdh.blocksize =3D htod32(di->blocksize);
-	strncpy(kdh.hostname, hostname, sizeof kdh.hostname);
-	strncpy(kdh.versionstring, version, sizeof kdh.versionstring);
-	if (panicstr !=3D NULL)
-		strncpy(kdh.panicstring, panicstr, sizeof kdh.panicstring);
-	kdh.parity =3D kerneldump_parity(&kdh);
-
-	/*
-	 * Check if we will have enough room to save the coredump.
-	 * The partition size needed is the sum of:
-	 * Memory to save + header + trailer + Room to leave untouched
-	 * at partition head. (an arbitrary amount).
-	 */
-	if (di->mediasize < =20
-	    Maxmem * (off_t)PAGE_SIZE + sizeof kdh * 2 + 64*1024) {
-		printf("\nDump failed. Partition too small.\n");
-		return;
-	}
-	dumplo =3D di->mediaoffset + di->mediasize - Maxmem * (off_t)PAGE_SIZE;
-	dumplo -=3D sizeof kdh * 2;
-	i =3D di->dumper(di->priv, &kdh, 0, dumplo, sizeof kdh);
+	i =3D dump_open(Maxmem * (off_t)PAGE_SIZE);
 	if (i)
 		printf("\nDump failed writing header (%d)\n", i);
-	dumplo +=3D sizeof kdh;
 	i =3D 0;
 	addr =3D 0;
 	va =3D 0;
-	mb =3D 0;
 	for (count =3D 0; count < Maxmem;) {
 		left =3D Maxmem - count;
 		if (left > MAXDUMPPGS)
@@ -107,16 +71,10 @@
 				a =3D 0;
 			va =3D pmap_kenter_temporary(trunc_page(a), u);
 		}
-		i =3D count / (16*1024*1024 / PAGE_SIZE);
-		if (i !=3D mb) {
-			printf(" %d", count / (1024 * 1024 / PAGE_SIZE));
-			mb =3D i;
-		}
-		i =3D di->dumper(di->priv, va, 0, dumplo, left * PAGE_SIZE);
+		i =3D dump_write(va, left * PAGE_SIZE);
 		if (i)
 			break;
 		count +=3D left;
-		dumplo +=3D left * PAGE_SIZE;
 		addr +=3D left * PAGE_SIZE;
 		if ((c =3D cncheckc()) =3D=3D 0x03) {
 			printf("\nDump aborted.\n");
@@ -124,12 +82,14 @@
 		} else if (c !=3D -1)
 			printf("[CTRL-C to abort] ");
 	}
-	if (i)=20
+	if (i) {
 		printf("\nDump failed writing data (%d)\n", i);
-	i =3D di->dumper(di->priv, &kdh, 0, dumplo, sizeof kdh);
+		return;
+	}
+	i =3D dump_close();
 	if (i)
 		printf("\nDump failed writing trailer (%d)\n", i);
-	di->dumper(di->priv, NULL, 0, 0, 0);  /* tell them we are done */
-	printf("\nDump complete\n");
+	else
+		printf("\nDump complete\n");
 	return;
 }
Index: src/sys/ia64/ia64/dump_machdep.c
diff -u src/sys/ia64/ia64/dump_machdep.c:1.12 src/sys/ia64/ia64/dump_machde=
p.c:1.12.1000.1
--- src/sys/ia64/ia64/dump_machdep.c:1.12	Fri Jan  7 06:18:22 2005
+++ src/sys/ia64/ia64/dump_machdep.c	Thu Jun 16 20:35:39 2005
@@ -61,15 +61,14 @@
=20
 /* XXX should be MI */
 static void
-mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dump=
len,
-    uint32_t blksz)
+mkdumpheader(struct kerneldumpheader *kdh, uint64_t dumplen, uint32_t blks=
z)
 {
=20
 	bzero(kdh, sizeof(*kdh));
 	strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
 	strncpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture));
 	kdh->version =3D htod32(KERNELDUMPVERSION);
-	kdh->architectureversion =3D htod32(archver);
+	kdh->dumptype =3D htod32(FULLDUMP);
 	kdh->dumplength =3D htod64(dumplen);
 	kdh->dumptime =3D htod64(time_second);
 	kdh->blocksize =3D htod32(blksz);
@@ -259,7 +258,7 @@
 	dumplo =3D di->mediaoffset + di->mediasize - dumpsize;
 	dumplo -=3D sizeof(kdh) * 2;
=20
-	mkdumpheader(&kdh, KERNELDUMP_IA64_VERSION, dumpsize, di->blocksize);
+	mkdumpheader(&kdh, dumpsize, di->blocksize);
=20
 	printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
 	    ehdr.e_phnum);
Index: src/sys/kern/kern_shutdown.c
diff -u src/sys/kern/kern_shutdown.c:1.174 src/sys/kern/kern_shutdown.c:1.1=
74.1000.2
--- src/sys/kern/kern_shutdown.c:1.174	Tue Apr 12 13:45:58 2005
+++ src/sys/kern/kern_shutdown.c	Mon Jun 20 10:03:45 2005
@@ -52,6 +52,7 @@
 #include <sys/eventhandler.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
+#include <sys/kerneldump.h>
 #include <sys/kthread.h>
 #include <sys/mac.h>
 #include <sys/malloc.h>
@@ -110,13 +111,6 @@
  */
 const char *panicstr;
=20
-int dumping;				/* system is dumping */
-static struct dumperinfo dumper;	/* our selected dumper */
-
-/* Context information for dump-debuggers. */
-static struct pcb dumppcb;		/* Registers. */
-static lwpid_t dumptid;			/* Thread ID. */
-
 static void boot(int) __dead2;
 static void poweroff_wait(void *, int);
 static void shutdown_halt(void *junk, int howto);
@@ -216,26 +210,6 @@
 	printf("%lds\n", (long)ts.tv_sec);
 }
=20
-static void
-doadump(void)
-{
-
-	/*
-	 * Sometimes people have to call this from the kernel debugger.=20
-	 * (if 'panic' can not dump)
-	 * Give them a clue as to why they can't dump.
-	 */
-	if (dumper.dumper =3D=3D NULL) {
-		printf("Cannot dump. No dump device defined.\n");
-		return;
-	}
-
-	savectx(&dumppcb);
-	dumptid =3D curthread->td_tid;
-	dumping++;
-	dumpsys(&dumper);
-}
-
 /*
  * Shutdown the system cleanly to prepare for reboot, halt, or power off.
  */
@@ -393,7 +367,7 @@
 	/* XXX This doesn't disable interrupts any more.  Reconsider? */
 	splhigh();
=20
-	if ((howto & (RB_HALT|RB_DUMP)) =3D=3D RB_DUMP && !cold && !dumping)=20
+	if ((howto & (RB_HALT|RB_DUMP)) =3D=3D RB_DUMP && !cold)=20
 		doadump();
=20
 	/* Now that we're going to really halt the system... */
@@ -605,27 +579,3 @@
 	else
 		printf("done\n");
 }
-
-/* Registration of dumpers */
-int
-set_dumper(struct dumperinfo *di)
-{
-
-	if (di =3D=3D NULL) {
-		bzero(&dumper, sizeof dumper);
-		return (0);
-	}
-	if (dumper.dumper !=3D NULL)
-		return (EBUSY);
-	dumper =3D *di;
-	return (0);
-}
-
-#if defined(__powerpc__)
-void
-dumpsys(struct dumperinfo *di __unused)
-{
-
-	printf("Kernel dumps not implemented on this architecture\n");
-}
-#endif
Index: src/sys/kern/subr_dump.c
diff -u /dev/null src/sys/kern/subr_dump.c:1.1.1000.7
--- /dev/null	Thu Jun 23 18:02:17 2005
+++ src/sys/kern/subr_dump.c	Thu Jun 23 01:41:00 2005
@@ -0,0 +1,291 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
+ * 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, STR=
ICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/kerneldump.h>
+#include <sys/sysctl.h>
+
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+
+int dumping;				/* system is dumping */
+
+/*
+ * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
+ * is to protect us from metadata and to protect metadata from us.
+ */
+#define	SIZEOF_METADATA		(64*1024)
+
+#define	DEV_ALIGN(x)	(((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1))
+
+static struct dumperinfo di;        /* our selected dumper */
+
+/* Context information for dump-debuggers. */
+static struct pcb dumppcb;              /* Registers. */
+static lwpid_t dumptid;                 /* Thread ID. */
+
+static int dumptype =3D 1;
+SYSCTL_INT(_kern, OID_AUTO, panic_dump_type, CTLFLAG_RW,
+	   &dumptype, 0,=20
+	   "Dump Type: 1->mini, 2->ascii, 3->kernelonly, other->full");
+
+CTASSERT(sizeof(struct kerneldumpheader) =3D=3D 512);
+
+static struct kerneldumpheader kdh;
+static off_t dumplo;
+
+/* Handle buffered writes. */
+static char buffer[DEV_BSIZE];
+static size_t fragsz;
+
+static void
+mkdumpheader(struct kerneldumpheader *kdh, uint64_t dumplen)
+{
+	bzero(kdh, sizeof(*kdh));
+	strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
+	strncpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture));
+	kdh->version =3D htod32(KERNELDUMPVERSION);
+	kdh->dumptype =3D htod32(dumptype);
+	kdh->dumplength =3D htod64(dumplen);
+	kdh->dumptime =3D htod64(time_second);
+	kdh->blocksize =3D htod32(di.blocksize);
+	strncpy(kdh->hostname, hostname, sizeof(kdh->hostname));
+	strncpy(kdh->versionstring, version, sizeof(kdh->versionstring));
+	if (panicstr !=3D NULL)
+		strncpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring));
+	kdh->parity =3D kerneldump_parity(kdh);
+}
+
+int dump_write(char *ptr, size_t sz)
+{
+	size_t len;
+	int error;
+	static u_int64_t count =3D 0;
+
+	if (fragsz =3D=3D 0 && (sz % DEV_BSIZE =3D=3D 0)) {
+		/* optimize if operation is in the edge of block */
+		while (sz) {
+			error =3D di.dumper(di.priv, ptr, 0, dumplo,
+					  DEV_BSIZE);
+			if (error)
+				return (error);
+			if (count++ % 1024)
+				printf(".");
+			dumplo +=3D DEV_BSIZE;
+			sz -=3D DEV_BSIZE;
+			ptr +=3D DEV_BSIZE;
+		}
+	}
+	else {
+		while (sz) {
+			len =3D DEV_BSIZE - fragsz;
+			if (len > sz)
+				len =3D sz;
+			bcopy(ptr, buffer + fragsz, len);
+			fragsz +=3D len;
+			ptr +=3D len;
+			sz -=3D len;
+			if (fragsz =3D=3D DEV_BSIZE) {
+				error =3D di.dumper(di.priv, buffer, 0, dumplo,
+						  DEV_BSIZE);
+			if (error)
+					return error;
+			if (count++ % 1024)
+				printf(".");
+				dumplo +=3D DEV_BSIZE;
+				fragsz =3D 0;
+			}
+		}
+	}
+	return (0);
+}
+
+int dump_open(size_t dumpsize)
+{
+	int error =3D 0;
+	size_t realsize;
+
+	realsize =3D DEV_ALIGN(dumpsize);
+
+	/* Check dump device size. 64KB additional for safe */
+	if (di.mediasize < SIZEOF_METADATA + realsize + sizeof(kdh) * 2 + 64 * 10=
24)
+		return (ENOSPC);
+	printf(" %u (aligned: %u)\n", dumpsize, realsize);
+
+	dumplo =3D di.mediaoffset + di.mediasize - realsize;
+	dumplo -=3D sizeof(kdh) * 2;
+
+	mkdumpheader(&kdh, realsize);
+	error =3D di.dumper(di.priv, &kdh, 0, dumplo, sizeof(kdh));
+	dumplo +=3D sizeof(kdh);
+	return error;
+}
+
+int dump_close(void)
+{
+	int error;
+
+	if (fragsz !=3D 0) {
+		/* align to the block */
+		error =3D di.dumper(di.priv, buffer, 0, dumplo, DEV_BSIZE);
+		dumplo +=3D DEV_BSIZE;
+	}
+
+	error =3D di.dumper(di.priv, &kdh, 0, dumplo, sizeof(kdh));
+	if (error =3D=3D 0)
+		error =3D di.dumper(di.priv, NULL, 0 , 0, 0);
+	printf("Dump tail header done.(%llu)\n", dumplo);
+	return (error);
+}
+
+static int dokernelonlydump(void)
+{
+	struct vm_map_entry *map =3D &kernel_map->header;
+	while(map !=3D NULL) {
+		if ((map->eflags & MAP_ENTRY_IS_SUB_MAP) ||
+		    (map->eflags & MAP_ENTRY_NOCOREDUMP))
+			continue;
+		printf("%x - %x\n", map->start, map->end);
+		map =3D map->next;
+	}
+	return 1;
+}
+
+static int dominidump(void)
+{
+	int i;
+	uint64_t dumpsize;
+
+	dumpsize =3D sizeof(dumppcb)
+		+ curthread->td_kstack_pages * PAGE_SIZE
+		+ sizeof(dumptid)
+		+ sizeof(*curthread);
+
+	printf("\nDumping mini dump\n");
+
+	i =3D dump_open(dumpsize);
+	if (i) {
+		printf("\nDump open failed (%d)\n", i);
+		return 0;
+	}
+
+	i =3D dump_write((char*)&dumppcb, sizeof(dumppcb));
+	i =3D dump_write((char*)&dumptid, sizeof(dumptid));
+	i =3D dump_write((char*)curthread, sizeof(*curthread));
+	i =3D dump_write((char *)curthread->td_kstack, curthread->td_kstack_pages=
 * PAGE_SIZE);
+	if (i)
+	{
+		printf("\nDump failed writing (%d)\n", i);
+		return 0;
+	}
+
+	i =3D dump_close();
+	if (i) {
+		printf("\nDump close failed (%d)\n", i);
+		return 0;
+	}
+	else {
+		printf("Done.\n");
+		return 1;
+	}
+}
+
+void
+doadump(void)
+{
+	if (dumping)
+		return;
+	/*
+	 * Sometimes people have to call this from the kernel debugger.
+	 * (if 'panic' can not dump)
+	 * Give them a clue as to why they can't dump.
+	 */
+	if (di.dumper =3D=3D NULL) {
+		printf("Cannot dump. No dump device defined.\n");
+		return;
+	}
+
+	savectx(&dumppcb);
+	dumptid =3D curthread->td_tid;
+	dumping++;
+	switch(dumptype) {
+	case MINIDUMP:
+		dominidump();
+		break;
+	case KERNELDUMP:
+		dokernelonlydump();
+		break;
+	case ASCIIDUMP:
+		break;
+	default:
+		dumpsys(&di);
+	}
+}
+
+/* Registration of dumpers */
+int
+set_dumper(struct dumperinfo *newdi)
+{
+
+	if (newdi =3D=3D NULL) {
+		bzero(&di, sizeof di);
+		return (0);
+	}
+	if (di.dumper !=3D NULL)
+		return (EBUSY);
+	di =3D *newdi;
+	return (0);
+}
+
+#if defined(__powerpc__)
+void
+dumpsys(struct dumperinfo *di __unused)
+{
+
+	printf("Kernel dumps not implemented on this architecture\n");
+}
+#endif
Index: src/sys/sparc64/sparc64/dump_machdep.c
diff -u src/sys/sparc64/sparc64/dump_machdep.c:1.8 src/sys/sparc64/sparc64/=
dump_machdep.c:1.8.1000.1
--- src/sys/sparc64/sparc64/dump_machdep.c:1.8	Fri Jan  7 10:29:23 2005
+++ src/sys/sparc64/sparc64/dump_machdep.c	Thu Jun 16 20:35:40 2005
@@ -65,7 +65,7 @@
 	strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
 	strncpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture));
 	kdh->version =3D htod32(KERNELDUMPVERSION);
-	kdh->architectureversion =3D htod32(archver);
+	kdh->dumptype =3D htod32(FULLDUMP);
 	kdh->dumplength =3D htod64(dumplen);
 	kdh->dumptime =3D htod64(time_second);
 	kdh->blocksize =3D htod32(blksz);
Index: src/sys/sys/conf.h
diff -u src/sys/sys/conf.h:1.222 src/sys/sys/conf.h:1.222.1000.1
--- src/sys/sys/conf.h:1.222	Thu Mar 31 18:29:57 2005
+++ src/sys/sys/conf.h	Sun Jun 19 23:43:43 2005
@@ -280,20 +280,6 @@
 int dev_stdclone(char *_name, char **_namep, const char *_stem, int *_unit=
);
 EVENTHANDLER_DECLARE(dev_clone, dev_clone_fn);
=20
-/* Stuff relating to kernel-dump */
-
-struct dumperinfo {
-	dumper_t *dumper;	/* Dumping function. */
-	void    *priv;		/* Private parts. */
-	u_int   blocksize;	/* Size of block in bytes. */
-	off_t   mediaoffset;	/* Initial offset in bytes. */
-	off_t   mediasize;	/* Space available in bytes. */
-};
-
-int set_dumper(struct dumperinfo *);
-void dumpsys(struct dumperinfo *);
-extern int dumping;		/* system is dumping */
-
 /* D_TTY related functions */
 d_close_t	 ttyclose;
 d_ioctl_t	 ttyioctl;
Index: src/sys/sys/kerneldump.h
diff -u src/sys/sys/kerneldump.h:1.6 src/sys/sys/kerneldump.h:1.6.1000.4
--- src/sys/sys/kerneldump.h:1.6	Mon Oct 21 01:03:15 2002
+++ src/sys/sys/kerneldump.h	Mon Jun 20 09:32:16 2005
@@ -52,6 +52,14 @@
 #define	htod64(x)	(x)
 #endif
=20
+typedef enum
+{
+	FULLDUMP =3D 0,
+	MINIDUMP =3D 1,
+	ASCIIDUMP =3D 2,
+	KERNELDUMP =3D 3
+}dumpcoretype;
+
 /*
  * All uintX_t fields are in dump byte order, which is the same as
  * network byte order. Use the macros defined above to read or
@@ -64,11 +72,7 @@
 	char		architecture[12];
 	uint32_t	version;
 #define	KERNELDUMPVERSION	1
-	uint32_t	architectureversion;
-#define	KERNELDUMP_ALPHA_VERSION	1
-#define	KERNELDUMP_I386_VERSION	1
-#define	KERNELDUMP_IA64_VERSION	1
-#define	KERNELDUMP_SPARC64_VERSION	1
+	uint32_t	dumptype;
 	uint64_t	dumplength;		/* excl headers */
 	uint64_t	dumptime;
 	uint32_t	blocksize;
@@ -94,5 +98,25 @@
 	return (parity);
 }
=20
+#ifdef _KERNEL
+
+struct dumperinfo {
+	dumper_t *dumper;	/* Dumping function. */
+	void    *priv;		/* Private parts. */
+	u_int   blocksize;	/* Size of block in bytes. */
+	off_t   mediaoffset;	/* Initial offset in bytes. */
+	off_t   mediasize;	/* Space available in bytes. */
+};
+
+int set_dumper(struct dumperinfo *);
+extern int dumping;		/* system is dumping */
+
+void doadump(void);
+int dump_open(size_t dumpsize);
+int dump_write(char* ptr, size_t sz);
+int dump_close(void);
+void dumpsys(struct dumperinfo *);
+
+#endif /* _KERNEL */
=20
 #endif /* _SYS_KERNELDUMP_H */
Index: src/sys/dev/pst/pst-raid.c
diff -u src/sys/dev/pst/pst-raid.c:1.14 src/sys/dev/pst/pst-raid.c:1.14.100=
2.1
--- src/sys/dev/pst/pst-raid.c:1.14	Wed Sep 15 23:39:28 2004
+++ src/sys/dev/pst/pst-raid.c	Thu Jun 23 18:01:42 2005
@@ -36,6 +36,7 @@
 #include <sys/bus.h>
 #include <sys/bio.h>
 #include <sys/conf.h>
+#include <sys/kerneldump.h>
 #include <sys/eventhandler.h>
 #include <sys/malloc.h>
 #include <sys/lock.h>

--oyUTqETQ0mS9luUI--

--9zSXsLTf0vkW971A
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (FreeBSD)

iD8DBQFCuozo/cVsHxFZiIoRAufiAJsF9MRYg+SM+UxrQp5E4Uw5DAhzQwCfVYiO
ksPn7y71JA8swfy1L7yJtHo=
=K6zN
-----END PGP SIGNATURE-----

--9zSXsLTf0vkW971A--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050623102024.GA89874>