diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-06-19 20:25:50 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-06-19 20:25:50 +0000 |
commit | ec0cd072e33631cd57cac617087eff4a10a713fa (patch) | |
tree | 0649c76b6a36bcae7bed49e396d82e4fb171595e | |
parent | 8e4e0d00306b9b02302711a0e35d18baa2e744d7 (diff) |
Real kvm routines for vax; allows ``target kvm'' to work in gdb for kernel
crash dumps.
ok kettenis@
-rw-r--r-- | lib/libkvm/kvm_vax.c | 79 |
1 files changed, 29 insertions, 50 deletions
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 <sys/param.h> #include <sys/user.h> #include <sys/proc.h> #include <sys/stat.h> +#include <sys/kcore.h> #include <unistd.h> #include <stdlib.h> #include <nlist.h> @@ -52,57 +51,26 @@ #include <uvm/uvm_extern.h> #include <machine/vmparam.h> +#include <machine/kcore.h> #include <machine/pmap.h> +#include <machine/pte.h> #include <limits.h> #include <db.h> #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); } |