sync with netbsd
authorderaadt <deraadt@openbsd.org>
Fri, 10 May 1996 12:58:30 +0000 (12:58 +0000)
committerderaadt <deraadt@openbsd.org>
Fri, 10 May 1996 12:58:30 +0000 (12:58 +0000)
lib/libkvm/kvm.c
lib/libkvm/kvm_m68k.c
lib/libkvm/kvm_private.h
lib/libkvm/kvm_sun3.c

index 0ff1e73..bafe6ee 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: kvm.c,v 1.3 1996/05/05 14:56:42 deraadt Exp $ */
-/*     $NetBSD: kvm.c,v 1.42 1996/03/18 22:33:13 thorpej Exp $ */
+/*     $OpenBSD: kvm.c,v 1.4 1996/05/10 12:58:30 deraadt Exp $ */
+/*     $NetBSD: kvm.c,v 1.43 1996/05/05 04:31:59 gwr Exp $     */
 
 /*-
  * Copyright (c) 1989, 1992, 1993
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)kvm.c      8.2 (Berkeley) 2/13/94";
 #else
-static char *rcsid = "$OpenBSD: kvm.c,v 1.3 1996/05/05 14:56:42 deraadt Exp $";
+static char *rcsid = "$OpenBSD: kvm.c,v 1.4 1996/05/10 12:58:30 deraadt Exp $";
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -61,9 +61,6 @@ static char *rcsid = "$OpenBSD: kvm.c,v 1.3 1996/05/05 14:56:42 deraadt Exp $";
 #include <vm/vm_param.h>
 #include <vm/swap_pager.h>
 
-#include <machine/vmparam.h>
-#include <machine/kcore.h>
-
 #include <ctype.h>
 #include <db.h>
 #include <fcntl.h>
@@ -239,7 +236,8 @@ _kvm_open(kd, uf, mf, sf, flag, errout)
        kd->vmst = 0;
        kd->vm_page_buckets = 0;
        kd->kcore_hdr = 0;
-       kd->cpu_hdr = 0;
+       kd->cpu_dsize = 0;
+       kd->cpu_data = 0;
        kd->dump_off = 0;
 
        if (uf == 0)
@@ -331,116 +329,131 @@ failed:
        return (0);
 }
 
+/*
+ * The kernel dump file (from savecore) contains:
+ *    kcore_hdr_t kcore_hdr;
+ *    kcore_seg_t cpu_hdr;
+ *    (opaque)    cpu_data; (size is cpu_hdr.c_size)
+ *       kcore_seg_t mem_hdr;
+ *    (memory)    mem_data; (size is mem_hdr.c_size)
+ *    
+ * Note: khdr is padded to khdr.c_hdrsize;
+ * cpu_hdr and mem_hdr are padded to khdr.c_seghdrsize
+ */
 static int
 _kvm_get_header(kd)
-kvm_t  *kd;
+       kvm_t   *kd;
 {
-       cpu_kcore_hdr_t ckhdr;
-       kcore_hdr_t     khdr;
-       kcore_seg_t     seghdr;
-       off_t           offset;
+       kcore_hdr_t     kcore_hdr;
+       kcore_seg_t     cpu_hdr;
+       kcore_seg_t     mem_hdr;
+       size_t          offset;
+       ssize_t         sz;
 
+       /*
+        * Read the kcore_hdr_t
+        */
        if (Lseek(kd, kd->pmfd, (off_t)0, SEEK_SET) == -1)
                return (-1);
-
-       if (Read(kd, kd->pmfd, &khdr, sizeof(khdr)) != sizeof(khdr))
+       sz = Read(kd, kd->pmfd, &kcore_hdr, sizeof(kcore_hdr));
+       if (sz != sizeof(kcore_hdr))
                return (-1);
-       offset = khdr.c_hdrsize;
 
        /*
         * Currently, we only support dump-files made by the current
         * architecture...
         */
-       if ((CORE_GETMAGIC(khdr) != KCORE_MAGIC)
-            || ((CORE_GETMID(khdr) != MID_MACHINE)))
-                       return (-1);
+       if ((CORE_GETMAGIC(kcore_hdr) != KCORE_MAGIC) ||
+           (CORE_GETMID(kcore_hdr) != MID_MACHINE))
+               return (-1);
 
        /*
         * Currently, we only support exactly 2 segments: cpu-segment
         * and data-segment in exactly that order.
         */
-       if (khdr.c_nseg != 2)
+       if (kcore_hdr.c_nseg != 2)
                return (-1);
 
        /*
-        * Read the next segment header: cpu segment
+        * Save away the kcore_hdr.  All errors after this
+        * should do a to "goto fail" to deallocate things.
+        */
+       kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr));
+       memcpy(kd->kcore_hdr, &kcore_hdr, sizeof(kcore_hdr));
+       offset = kcore_hdr.c_hdrsize;
+
+       /*
+        * Read the CPU segment header
         */
        if (Lseek(kd, kd->pmfd, (off_t)offset, SEEK_SET) == -1)
-               return (-1);
-       if (Read(kd, kd->pmfd, &seghdr, sizeof(seghdr)) != sizeof(seghdr))
-               return (-1);
-       if (CORE_GETMAGIC(seghdr) != KCORESEG_MAGIC
-               || CORE_GETFLAG(seghdr) != CORE_CPU)
-               return (-1);
-       offset += khdr.c_seghdrsize;
+               goto fail;
+       sz = Read(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr));
+       if (sz != sizeof(cpu_hdr))
+               goto fail;
+       if ((CORE_GETMAGIC(cpu_hdr) != KCORESEG_MAGIC) ||
+           (CORE_GETFLAG(cpu_hdr) != CORE_CPU))
+               goto fail;
+       offset += kcore_hdr.c_seghdrsize;
+
+       /*
+        * Read the CPU segment DATA.
+        */
+       kd->cpu_dsize = cpu_hdr.c_size;
+       kd->cpu_data = _kvm_malloc(kd, cpu_hdr.c_size);
+       if (kd->cpu_data == NULL)
+               goto fail;
        if (Lseek(kd, kd->pmfd, (off_t)offset, SEEK_SET) == -1)
-               return (-1);
-       if (Read(kd, kd->pmfd, &ckhdr, sizeof(ckhdr)) != sizeof(ckhdr))
-               return (-1);
-       offset += seghdr.c_size;
+               goto fail;
+       sz = Read(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size);
+       if (sz != cpu_hdr.c_size)
+               goto fail;
+       offset += cpu_hdr.c_size;
 
        /*
         * Read the next segment header: data segment
         */
        if (Lseek(kd, kd->pmfd, (off_t)offset, SEEK_SET) == -1)
-               return (-1);
-       if (Read(kd, kd->pmfd, &seghdr, sizeof(seghdr)) != sizeof(seghdr))
-               return (-1);
-       offset += khdr.c_seghdrsize;
+               goto fail;
+       sz = Read(kd, kd->pmfd, &mem_hdr, sizeof(mem_hdr));
+       if (sz != sizeof(mem_hdr))
+               goto fail;
+       offset += kcore_hdr.c_seghdrsize;
 
-       if (CORE_GETMAGIC(seghdr) != KCORESEG_MAGIC
-               || CORE_GETFLAG(seghdr) != CORE_DATA)
-               return (-1);
+       if ((CORE_GETMAGIC(mem_hdr) != KCORESEG_MAGIC) ||
+           (CORE_GETFLAG(mem_hdr) != CORE_DATA))
+               goto fail;
 
-       kd->kcore_hdr = (kcore_hdr_t *)_kvm_malloc(kd, sizeof(*kd->kcore_hdr));
-       if (kd->kcore_hdr == NULL)
-               return (-1);
-       kd->cpu_hdr = (cpu_kcore_hdr_t *)_kvm_malloc(kd, sizeof(*kd->cpu_hdr));
-       if (kd->cpu_hdr == NULL) {
-               free((void *)kd->kcore_hdr);
+       kd->dump_off = offset;
+       return (0);
+
+fail:
+       if (kd->kcore_hdr != NULL) {
+               free(kd->kcore_hdr);
                kd->kcore_hdr = NULL;
-               return (-1);
+       }
+       if (kd->cpu_data != NULL) {
+               free(kd->cpu_data);
+               kd->cpu_data = NULL;
+               kd->cpu_dsize = 0;
        }
 
-       *kd->kcore_hdr = khdr;
-       *kd->cpu_hdr   = ckhdr;
-       kd->dump_off   = offset;
-       return (0);
 }
 
 /*
- * Translate a physical address to a file-offset in the crash-dump.
+ * The format while on the dump device is: (new format)
+ *    kcore_seg_t cpu_hdr;
+ *    (opaque)    cpu_data; (size is cpu_hdr.c_size)
+ *       kcore_seg_t mem_hdr;
+ *    (memory)    mem_data; (size is mem_hdr.c_size)
  */
-off_t
-_kvm_pa2off(kd, pa)
-       kvm_t   *kd;
-       u_long  pa;
-{
-       off_t           off;
-       phys_ram_seg_t  *rsp;
-
-       off = 0;
-       for (rsp = kd->cpu_hdr->ram_segs; rsp->size; rsp++) {
-               if (pa >= rsp->start && pa < rsp->start + rsp->size) {
-                       pa -= rsp->start;
-                       break;
-               }
-               off += rsp->size;
-       }
-       return(pa + off + kd->dump_off);
-}
-
 int
 kvm_dump_mkheader(kd, dump_off)
 kvm_t  *kd;
 off_t  dump_off;
 {
-       kcore_hdr_t     kch;
-       kcore_seg_t     kseg;
-       cpu_kcore_hdr_t ckhdr;
-       int             hdr_size;
+       kcore_seg_t     cpu_hdr;
+       int     hdr_size, sz;
 
-       hdr_size = 0;
        if (kd->kcore_hdr != NULL) {
            _kvm_err(kd, kd->program, "already has a dump header");
            return (-1);
@@ -451,62 +464,70 @@ off_t     dump_off;
        }
 
        /*
-        * Check for new format crash dump
+        * Validate new format crash dump
         */
        if (Lseek(kd, kd->pmfd, dump_off, SEEK_SET) == -1)
                return (-1);
-       if (Read(kd, kd->pmfd, &kseg, sizeof(kseg)) != sizeof(kseg))
+       sz = Read(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr));
+       if (sz != sizeof(cpu_hdr))
                return (-1);
-       if ((CORE_GETMAGIC(kseg) == KCORE_MAGIC)
-            && ((CORE_GETMID(kseg) == MID_MACHINE))) {
-               hdr_size += ALIGN(sizeof(kcore_seg_t));
-               if (Lseek(kd, kd->pmfd, dump_off+hdr_size, SEEK_SET) == -1)
-                       return (-1);
-               if (Read(kd, kd->pmfd, &ckhdr, sizeof(ckhdr)) != sizeof(ckhdr))
-                       return (-1);
-               hdr_size += kseg.c_size;
-               if (Lseek(kd, kd->pmfd, dump_off+hdr_size, SEEK_SET) == -1)
-                       return (-1);
-               kd->cpu_hdr = (cpu_kcore_hdr_t *)
-                               _kvm_malloc(kd, sizeof(cpu_kcore_hdr_t));
-               *kd->cpu_hdr = ckhdr;
-       }
+       if (CORE_GETMAGIC(cpu_hdr) != KCORE_MAGIC)
+               return (-1);
+       if (CORE_GETMID(cpu_hdr) != MID_MACHINE)
+               return (-1);
+       hdr_size = ALIGN(sizeof(cpu_hdr));
+
+       /*
+        * Read the CPU segment.
+        */
+       kd->cpu_dsize = cpu_hdr.c_size;
+       kd->cpu_data = _kvm_malloc(kd, kd->cpu_dsize);
+       if (kd->cpu_data == NULL)
+               goto fail;
+       if (Lseek(kd, kd->pmfd, dump_off+hdr_size, SEEK_SET) == -1)
+               goto fail;
+       sz = Read(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size);
+       if (sz != cpu_hdr.c_size)
+               goto fail;
+       hdr_size += kd->cpu_dsize;
+
+       /*
+        * Leave phys mem pointer at beginning of memory data
+        */
+       kd->dump_off = dump_off + hdr_size;
+       if (Lseek(kd, kd->pmfd, kd->dump_off, SEEK_SET) == -1)
+               goto fail;
 
        /*
         * Create a kcore_hdr.
         */
-       kd->kcore_hdr = (kcore_hdr_t *) _kvm_malloc(kd, sizeof(kcore_hdr_t));
-       if (kd->kcore_hdr == NULL) {
-               if (kd->cpu_hdr != NULL) {
-                       free((void *)kd->cpu_hdr);
-                       kd->cpu_hdr = NULL;
-               }
-               return (-1);
-       }
+       kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr_t));
+       if (kd->kcore_hdr == NULL)
+               goto fail;
 
        kd->kcore_hdr->c_hdrsize    = ALIGN(sizeof(kcore_hdr_t));
        kd->kcore_hdr->c_seghdrsize = ALIGN(sizeof(kcore_seg_t));
        kd->kcore_hdr->c_nseg       = 2;
        CORE_SETMAGIC(*(kd->kcore_hdr), KCORE_MAGIC, MID_MACHINE,0);
 
-       /*
-        * If there is no cpu_hdr at this point, we probably have an
-        * old format crash dump.....bail out
-        */
-       if (kd->cpu_hdr == NULL) {
-               free((void *)kd->kcore_hdr);
-               kd->kcore_hdr = NULL;
-               _kvm_err(kd, kd->program, "invalid dump");
-       }
-
-       kd->dump_off  = dump_off + hdr_size;
-
        /*
         * Now that we have a valid header, enable translations.
         */
        _kvm_initvtop(kd);
 
        return(hdr_size);
+
+fail:
+       if (kd->kcore_hdr != NULL) {
+               free(kd->kcore_hdr);
+               kd->kcore_hdr = NULL;
+       }
+       if (kd->cpu_data != NULL) {
+               free(kd->cpu_data);
+               kd->cpu_data = NULL;
+               kd->cpu_dsize = 0;
+       }
+       return (-1);
 }
 
 static int
@@ -540,7 +561,7 @@ int dumpsize;
        long            offset;
        int             gap;
 
-       if (kd->kcore_hdr == NULL || kd->cpu_hdr == NULL) {
+       if (kd->kcore_hdr == NULL || kd->cpu_data == NULL) {
                _kvm_err(kd, kd->program, "no valid dump header(s)");
                return (-1);
        }
@@ -562,7 +583,7 @@ int dumpsize;
         * Write the cpu header
         */
        CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_CPU);
-       seghdr.c_size = ALIGN(sizeof(cpu_kcore_hdr_t));
+       seghdr.c_size = ALIGN(kd->cpu_dsize);
        if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) {
                _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
                return (-1);
@@ -572,12 +593,12 @@ int       dumpsize;
        if (clear_gap(kd, fp, gap) == -1)
                return (-1);
 
-       if (fwrite((void*)kd->cpu_hdr, sizeof(cpu_kcore_hdr_t), 1, fp) <= 0) {
+       if (fwrite((void*)kd->cpu_data, kd->cpu_dsize, 1, fp) <= 0) {
                _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
                return (-1);
        }
        offset += seghdr.c_size;
-       gap     = seghdr.c_size - sizeof(cpu_kcore_hdr_t);
+       gap     = seghdr.c_size - kd->cpu_dsize;
        if (clear_gap(kd, fp, gap) == -1)
                return (-1);
 
@@ -652,8 +673,9 @@ kvm_close(kd)
                error |= (kd->db->close)(kd->db);
        if (kd->vmst)
                _kvm_freevtop(kd);
-       if (kd->cpu_hdr != NULL)
-               free((void *)kd->cpu_hdr);
+       kd->cpu_dsize = 0;
+       if (kd->cpu_data != NULL)
+               free((void *)kd->cpu_data);
        if (kd->kcore_hdr != NULL)
                free((void *)kd->kcore_hdr);
        if (kd->procbase != 0)
@@ -858,7 +880,7 @@ kvm_read(kd, kva, buf, len)
                        _kvm_err(kd, kd->program, "short read");
                return (cc);
        } else {
-               if ((kd->kcore_hdr == NULL) || (kd->cpu_hdr == NULL)) {
+               if ((kd->kcore_hdr == NULL) || (kd->cpu_data == NULL)) {
                        _kvm_err(kd, kd->program, "no valid dump header");
                        return (0);
                }
index d6e33fe..983cc72 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: kvm_m68k.c,v 1.3 1996/05/05 14:57:23 deraadt Exp $ */
-/*     $NetBSD: kvm_m68k.c,v 1.7 1996/03/18 22:33:41 thorpej Exp $     */
+/*     $OpenBSD: kvm_m68k.c,v 1.4 1996/05/10 12:58:31 deraadt Exp $ */
+/*     $NetBSD: kvm_m68k.c,v 1.9 1996/05/07 06:09:11 leo Exp $ */
 
 /*-
  * Copyright (c) 1989, 1992, 1993
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)kvm_hp300.c        8.1 (Berkeley) 6/4/93";
 #else
-static char *rcsid = "$OpenBSD: kvm_m68k.c,v 1.3 1996/05/05 14:57:23 deraadt Exp $";
+static char *rcsid = "$OpenBSD: kvm_m68k.c,v 1.4 1996/05/10 12:58:31 deraadt Exp $";
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -115,7 +115,7 @@ _kvm_vatop(kd, sta, va, pa)
                return((off_t)0);
        }
        offset = va & PGOFSET;
-       cpu_kh = kd->cpu_hdr;
+       cpu_kh = kd->cpu_data;
        /*
         * If we are initializing (kernel segment table pointer not yet set)
         * then return pa == va to avoid infinite recursion.
@@ -203,5 +203,32 @@ _kvm_kvatop(kd, va, pa)
        u_long va;
        u_long *pa;
 {
-       return (_kvm_vatop(kd, (u_long)kd->cpu_hdr->sysseg_pa, va, pa));
+       register cpu_kcore_hdr_t *cpu_kh;
+
+       cpu_kh = kd->cpu_data;
+       return (_kvm_vatop(kd, (u_long)cpu_kh->sysseg_pa, va, pa));
+}
+
+/*
+ * Translate a physical address to a file-offset in the crash-dump.
+ */
+off_t
+_kvm_pa2off(kd, pa)
+       kvm_t   *kd;
+       u_long  pa;
+{
+       off_t           off;
+       phys_ram_seg_t  *rsp;
+       register cpu_kcore_hdr_t *cpu_kh;
+
+       cpu_kh = kd->cpu_data;
+       off = 0;
+       for (rsp = cpu_kh->ram_segs; rsp->size; rsp++) {
+               if (pa >= rsp->start && pa < rsp->start + rsp->size) {
+                       pa -= rsp->start;
+                       break;
+               }
+               off += rsp->size;
+       }
+       return(kd->dump_off + off + pa);
 }
index cdea448..a1dbf75 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: kvm_private.h,v 1.3 1996/05/05 14:57:38 deraadt Exp $ */
-/*     $NetBSD: kvm_private.h,v 1.6 1996/03/18 22:33:54 thorpej Exp $  */
+/*     $OpenBSD: kvm_private.h,v 1.4 1996/05/10 12:58:33 deraadt Exp $ */
+/*     $NetBSD: kvm_private.h,v 1.7 1996/05/05 04:32:15 gwr Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -68,7 +68,8 @@ struct __kvm {
         * dead kernels.
         */
        struct kcore_hdr        *kcore_hdr;
-       struct cpu_kcore_hdr    *cpu_hdr;
+       size_t  cpu_dsize;
+       void    *cpu_data;
        off_t   dump_off;       /* Where the actual dump starts */
 
        /*
index 69b22c2..a7c06c5 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: kvm_sun3.c,v 1.2 1996/05/05 14:57:53 deraadt Exp $ */
-/*     $NetBSD: kvm_sun3.c,v 1.3 1996/03/18 22:34:04 thorpej Exp $     */
+/*     $OpenBSD: kvm_sun3.c,v 1.3 1996/05/10 12:58:33 deraadt Exp $ */
+/*     $NetBSD: kvm_sun3.c,v 1.4 1996/05/05 04:32:18 gwr Exp $ */
 
 /*-
  * Copyright (c) 1992, 1993
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)kvm_sparc.c        8.1 (Berkeley) 6/4/93";
+#else
+static char *rcsid = "$NetBSD: kvm_sun3.c,v 1.4 1996/05/05 04:32:18 gwr Exp $";
+#endif
+#endif /* LIBC_SCCS and not lint */
+
 /*
- * Sun3 machine dependent routines for kvm.  Hopefully, the forthcoming
- * vm code will one day obsolete this module.  Furthermore, I hope it
- * gets here soon, because this basically is an error stub! (sorry)
+ * Sun3 machine dependent routines for kvm.
  */
 
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/proc.h>
 #include <sys/stat.h>
+
+#include <sys/core.h>
+#include <sys/exec_aout.h>
+#include <sys/kcore.h>
+
 #include <unistd.h>
+#include <limits.h>
 #include <nlist.h>
 #include <kvm.h>
+#include <db.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 
-#include <limits.h>
-#include <db.h>
+#include <machine/kcore.h>
+#include <machine/pte.h>
 
 #include "kvm_private.h"
 
+#define NKSEG (NSEGMAP/8)      /* kernel segmap entries */
 struct vmstate {
-       u_long end;
+       /* Page Map Entry Group (PMEG) */
+       int   pmeg[NKSEG][NPAGSEG];
 };
 
-void
-_kvm_freevtop(kd)
-       kvm_t *kd;
-{
-       if (kd->vmst != 0)
-               free(kd->vmst);
-}
-
+/*
+ * Prepare for translation of kernel virtual addresses into offsets
+ * into crash dump files. We use the MMU specific goop written at the
+ * beginning of a crash dump by dumpsys()
+ * Note: sun3 MMU specific!
+ */
 int
 _kvm_initvtop(kd)
        kvm_t *kd;
 {
-       register int i;
-       register int off;
-       register struct vmstate *vm;
-       struct stat st;
-       struct nlist nlist[2];
-
-       vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
-       if (vm == 0)
-               return (-1);
-
-       kd->vmst = vm;
-
-       if (fstat(kd->pmfd, &st) < 0)
-               return (-1);
-
-       /* Get end of kernel address */
-       nlist[0].n_name = "_end";
-       nlist[1].n_name = 0;
-       if (kvm_nlist(kd, nlist) != 0) {
-               _kvm_err(kd, kd->program, "pmap_stod: no such symbol");
-               return (-1);
-       }
-       vm->end = (u_long)nlist[0].n_value;
+       register char *p;
+
+       p = kd->cpu_data;
+       p += (NBPG - sizeof(kcore_seg_t));
+       kd->vmst = (struct vmstate *)p;
 
        return (0);
 }
 
-#define VA_OFF(va) (va & (NBPG - 1))
+void
+_kvm_freevtop(kd)
+       kvm_t *kd;
+{
+       /* This was set by pointer arithmetic, not allocation. */
+       kd->vmst = (void*)0;
+}
 
 /*
  * Translate a kernel virtual address to a physical address using the
@@ -112,24 +113,56 @@ _kvm_initvtop(kd)
  * physical address.  This routine is used only for crashdumps.
  */
 int
-_kvm_kvatop(kd, va, pa)
+_kvm_kvatop(kd, va, pap)
        kvm_t *kd;
        u_long va;
-       u_long *pa;
+       u_long *pap;
 {
-       register int end;
+       register cpu_kcore_hdr_t *ckh;
+       u_int segnum, sme, ptenum;
+       int pte, offset;
+       u_long pa;
+
+       if (ISALIVE(kd)) {
+               _kvm_err(kd, 0, "vatop called in live kernel!");
+               return((off_t)0);
+       }
+       ckh = kd->cpu_data;
 
        if (va < KERNBASE) {
-               _kvm_err(kd, 0, "invalid address (%x<%x)", va, KERNBASE);
-               return (0);
+               _kvm_err(kd, 0, "not a kernel address");
+               return((off_t)0);
        }
 
-       end = kd->vmst->end;
-       if (va >= end) {
-               _kvm_err(kd, 0, "invalid address (%x>=%x)", va, end);
+       /*
+        * Get the segmap entry (sme) from the kernel segmap.
+        * Note: only have segmap entries from KERNBASE to end.
+        */
+       segnum = VA_SEGNUM(va - KERNBASE);
+       ptenum = VA_PTE_NUM(va);
+       offset = va & PGOFSET;
+
+       /* The segmap entry selects a PMEG. */
+       sme = ckh->ksegmap[segnum];
+       pte = kd->vmst->pmeg[sme][ptenum];
+
+       if ((pte & PG_VALID) == 0) {
+               _kvm_err(kd, 0, "page not valid (VA=0x%x)", va);
                return (0);
        }
+       pa = PG_PA(pte) + offset;
+
+       *pap = pa;
+       return (NBPG - offset);
+}
 
-       *pa = (va - KERNBASE);
-       return (end - va);
+/*
+ * Translate a physical address to a file-offset in the crash-dump.
+ */
+off_t
+_kvm_pa2off(kd, pa)
+       kvm_t   *kd;
+       u_long  pa;
+{
+       return(kd->dump_off + pa);
 }