From ec0cd072e33631cd57cac617087eff4a10a713fa Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Mon, 19 Jun 2006 20:25:50 +0000 Subject: Real kvm routines for vax; allows ``target kvm'' to work in gdb for kernel crash dumps. ok kettenis@ --- lib/libkvm/kvm_vax.c | 79 +++++++++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 50 deletions(-) (limited to 'lib/libkvm') diff --git a/lib/libkvm/kvm_vax.c b/lib/libkvm/kvm_vax.c index ad080b0bc76..5a5fb249aca 100644 --- a/lib/libkvm/kvm_vax.c +++ b/lib/libkvm/kvm_vax.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm_vax.c,v 1.12 2006/03/20 15:11:48 mickey Exp $ */ +/* $OpenBSD: kvm_vax.c,v 1.13 2006/06/19 20:25:49 miod Exp $ */ /* $NetBSD: kvm_vax.c,v 1.3 1996/03/18 22:34:06 thorpej Exp $ */ /*- @@ -36,15 +36,14 @@ /* * VAX 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) - * This code may not work anyway. + * vm code will one day obsolete this module. */ #include #include #include #include +#include #include #include #include @@ -52,57 +51,26 @@ #include #include +#include #include +#include #include #include #include "kvm_private.h" -struct vmstate { - u_long end; -}; - void _kvm_freevtop(kvm_t *kd) { - if (kd->vmst != NULL) { - free(kd->vmst); - kd->vmst = NULL; - } } int _kvm_initvtop(kvm_t *kd) { - struct nlist nlist[2]; - struct vmstate *vm; - struct stat st; - int i, off; - - 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; - return (0); } -#define VA_OFF(va) (va & (NBPG - 1)) - /* * Translate a kernel virtual address to a physical address using the * mapping information in kd->vm. Returns the result in pa, and returns @@ -112,34 +80,45 @@ _kvm_initvtop(kvm_t *kd) int _kvm_kvatop(kvm_t *kd, u_long va, paddr_t *pa) { - u_long end; + paddr_t ofs; + u_long pteaddr; + pt_entry_t pte; + cpu_kcore_hdr_t *cpu_kh; - if (va < KERNBASE) { - _kvm_err(kd, 0, "invalid address (%lx<%lx)", va, KERNBASE); + if (ISALIVE(kd)) { + _kvm_err(kd, 0, "vatop called in live kernel!"); return (0); } - if (!kd->vmst) { - _kvm_err(kd, 0, "vatop called before initvtop"); + if (va < (u_long)KERNBASE) { + _kvm_err(kd, 0, "invalid address (%lx<%lx)", va, KERNBASE); return (0); } - end = kd->vmst->end; - if (va >= end) { - _kvm_err(kd, 0, "invalid address (%lx>=%lx)", va, end); + /* read pte from Sysmap */ + cpu_kh = kd->cpu_data; + pteaddr = (cpu_kh->sysmap - KERNBASE) + + PG_PFNUM(va) * sizeof(pt_entry_t); + if (_kvm_pread(kd, kd->pmfd, (char *)&pte, sizeof(pte), + (off_t)_kvm_pa2off(kd, pteaddr)) < 0) { + _kvm_err(kd, 0, "invalid address (%lx)", va); + return (0); + } + if ((pte & PG_V) == 0) { + _kvm_err(kd, 0, "invalid pte %lx (address %lx)", pte, va); return (0); } - *pa = (va - KERNBASE); - return (end - va); + ofs = va & PAGE_MASK; + *pa = ((pte & PG_FRAME) << VAX_PGSHIFT) | ofs; + return (int)(PAGE_SIZE - ofs); } /* - * Translate a physical address to an offset in the crash dump - * XXX crashdumps not working yet anyway + * Translate a physical address to an offset in the crash dump. */ off_t _kvm_pa2off(kvm_t *kd, paddr_t pa) { - return (kd->dump_off+pa); + return (kd->dump_off + pa); } -- cgit v1.2.3