summaryrefslogtreecommitdiffstats
path: root/lib/libkvm/kvm_arm.c
diff options
context:
space:
mode:
authorraj <raj@FreeBSD.org>2008-11-06 16:20:27 +0000
committerraj <raj@FreeBSD.org>2008-11-06 16:20:27 +0000
commit032a270ba544a5cb29900526c3413bac480cde6d (patch)
tree40c6d0b68a8a60a72eef9874a719be1123e8c25c /lib/libkvm/kvm_arm.c
parentc6a123e24acb0ecb46ac0558d7b0ea7a66b2036a (diff)
downloadFreeBSD-src-032a270ba544a5cb29900526c3413bac480cde6d.zip
FreeBSD-src-032a270ba544a5cb29900526c3413bac480cde6d.tar.gz
Support kernel crash mini dumps on ARM architecture.
Obtained from: Juniper Networks, Semihalf
Diffstat (limited to 'lib/libkvm/kvm_arm.c')
-rw-r--r--lib/libkvm/kvm_arm.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/libkvm/kvm_arm.c b/lib/libkvm/kvm_arm.c
index 631aff6..489cfe0 100644
--- a/lib/libkvm/kvm_arm.c
+++ b/lib/libkvm/kvm_arm.c
@@ -52,10 +52,13 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <kvm.h>
#include <stdlib.h>
+#include <unistd.h>
#include "kvm_private.h"
+/* minidump must be the first item! */
struct vmstate {
+ int minidump; /* 1 = minidump mode */
pd_entry_t *l1pt;
void *mmapbase;
size_t mmapsize;
@@ -107,6 +110,8 @@ void
_kvm_freevtop(kvm_t *kd)
{
if (kd->vmst != 0) {
+ if (kd->vmst->minidump)
+ return (_kvm_minidump_freevtop(kd));
if (kd->vmst->mmapbase != NULL)
munmap(kd->vmst->mmapbase, kd->vmst->mmapsize);
free(kd->vmst);
@@ -117,13 +122,25 @@ _kvm_freevtop(kvm_t *kd)
int
_kvm_initvtop(kvm_t *kd)
{
- struct vmstate *vm = _kvm_malloc(kd, sizeof(*vm));
+ struct vmstate *vm;
struct nlist nlist[2];
u_long kernbase, physaddr, pa;
pd_entry_t *l1pt;
Elf32_Ehdr *ehdr;
size_t hdrsz;
-
+ char minihdr[8];
+
+ if (!kd->rawdump) {
+ if (pread(kd->pmfd, &minihdr, 8, 0) == 8) {
+ if (memcmp(&minihdr, "minidump", 8) == 0)
+ return (_kvm_minidump_initvtop(kd));
+ } else {
+ _kvm_err(kd, kd->program, "cannot read header");
+ return (-1);
+ }
+ }
+
+ vm = _kvm_malloc(kd, sizeof(*vm));
if (vm == 0) {
_kvm_err(kd, kd->program, "cannot allocate vm");
return (-1);
@@ -193,6 +210,9 @@ _kvm_kvatop(kvm_t *kd, u_long va, off_t *pa)
pt_entry_t pte;
u_long pte_pa;
+ if (kd->vmst->minidump)
+ return (_kvm_minidump_kvatop(kd, va, pa));
+
if (vm->l1pt == NULL)
return (_kvm_pa2off(kd, va, pa, PAGE_SIZE));
pd = vm->l1pt[L1_IDX(va)];
OpenPOWER on IntegriCloud