From 5a9ac2da2607c6131586826fbaec4b2bceefe4d7 Mon Sep 17 00:00:00 2001 From: deraadt Date: Fri, 10 May 1996 12:58:30 +0000 Subject: [PATCH] sync with netbsd --- lib/libkvm/kvm.c | 256 +++++++++++++++++++++------------------ lib/libkvm/kvm_m68k.c | 37 +++++- lib/libkvm/kvm_private.h | 7 +- lib/libkvm/kvm_sun3.c | 133 ++++++++++++-------- 4 files changed, 258 insertions(+), 175 deletions(-) diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c index 0ff1e73c39c..bafe6eeefb4 100644 --- a/lib/libkvm/kvm.c +++ b/lib/libkvm/kvm.c @@ -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 #include -#include -#include - #include #include #include @@ -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); } diff --git a/lib/libkvm/kvm_m68k.c b/lib/libkvm/kvm_m68k.c index d6e33fe11c3..983cc724464 100644 --- a/lib/libkvm/kvm_m68k.c +++ b/lib/libkvm/kvm_m68k.c @@ -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); } diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h index cdea44877e5..a1dbf75989f 100644 --- a/lib/libkvm/kvm_private.h +++ b/lib/libkvm/kvm_private.h @@ -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 */ /* diff --git a/lib/libkvm/kvm_sun3.c b/lib/libkvm/kvm_sun3.c index 69b22c23c98..a7c06c5ce21 100644 --- a/lib/libkvm/kvm_sun3.c +++ b/lib/libkvm/kvm_sun3.c @@ -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 @@ -38,72 +38,73 @@ * 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 #include #include #include + +#include +#include +#include + #include +#include #include #include +#include #include #include -#include -#include +#include +#include #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); } -- 2.20.1