qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] target-arm: add dump-guest-memory support


From: Rabin Vincent
Subject: [Qemu-devel] [PATCH] target-arm: add dump-guest-memory support
Date: Wed, 24 Dec 2014 00:29:18 +0100

Enable support for the dump-guest-memory command on ARM and AArch64.
The dumped files can be analyzed with crash or similar tools.

Signed-off-by: Rabin Vincent <address@hidden>
---
 target-arm/Makefile.objs |   2 +-
 target-arm/arch_dump.c   | 148 +++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu-qom.h     |   8 +++
 target-arm/cpu.c         |   4 ++
 4 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 target-arm/arch_dump.c

diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 9460b40..38ba48c 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -7,6 +7,6 @@ obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += neon_helper.o iwmmxt_helper.o
 obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += psci.o
+obj-$(CONFIG_SOFTMMU) += psci.o arch_dump.o
 obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
 obj-y += crypto_helper.o
diff --git a/target-arm/arch_dump.c b/target-arm/arch_dump.c
new file mode 100644
index 0000000..4e7b9a2
--- /dev/null
+++ b/target-arm/arch_dump.c
@@ -0,0 +1,148 @@
+#include "cpu.h"
+
+#include "sysemu/dump.h"
+#include "elf.h"
+
+/* Matches elf_prstatus in <linux/elfcore.h> */
+
+typedef struct {
+    char pad1[24];
+    uint32_t pid;
+    char pad2[44];
+    uint32_t regs[18];
+    char pad3[4];
+} arm_elf_prstatus;
+
+typedef struct {
+    char pad1[32];
+    uint32_t pid;
+    char pad2[76];
+    uint64_t regs[32];
+    uint64_t pc;
+    uint64_t pstate;
+    char pad3[4];
+} aarch64_elf_prstatus;
+
+static size_t round4(size_t size)
+{
+    return ((size + 3) / 4) * 4;
+}
+
+static int write_elf_note(const char *name, uint32_t type,
+                          void *desc, size_t descsz,
+                          WriteCoreDumpFunction f, void *opaque)
+{
+    size_t note_size, name_size, note_head_size;
+    DumpState *s = opaque;
+    int class = s->dump_info.d_class;
+    Elf64_Nhdr *note64;
+    Elf32_Nhdr *note32;
+    void *note;
+    char *buf;
+    int ret;
+
+    name_size = strlen(name) + 1;
+
+    if (class == ELFCLASS32) {
+        note_head_size = sizeof(Elf32_Nhdr);
+    } else {
+        note_head_size = sizeof(Elf64_Nhdr);
+    }
+
+    note_size = note_head_size + round4(name_size) + descsz;
+    note = g_malloc0(note_size);
+
+    if (class == ELFCLASS32) {
+        note32 = note;
+        note32->n_namesz = cpu_to_dump32(s, name_size);
+        note32->n_descsz = cpu_to_dump32(s, descsz);
+        note32->n_type = cpu_to_dump32(s, type);
+    } else {
+        note64 = note;
+        note64->n_namesz = cpu_to_dump64(s, name_size);
+        note64->n_descsz = cpu_to_dump64(s, descsz);
+        note64->n_type = cpu_to_dump64(s, type);
+    }
+
+    buf = note;
+    buf += note_head_size;
+
+    memcpy(buf, name, name_size);
+    buf += round4(name_size);
+
+    memcpy(buf, desc, descsz);
+
+    ret = f(note, note_size, opaque);
+    g_free(note);
+
+    return ret;
+}
+
+int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque)
+{
+    arm_elf_prstatus prstatus = {.pid = cpuid};
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    memcpy(&(prstatus.regs), cpu->env.regs, sizeof(cpu->env.regs));
+    prstatus.regs[16] = cpsr_read(&cpu->env);
+
+    return write_elf_note("CORE", NT_PRSTATUS,
+                          &prstatus, sizeof(prstatus),
+                          f, opaque);
+}
+
+int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque)
+{
+    aarch64_elf_prstatus prstatus = {.pid = cpuid};
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    memcpy(&(prstatus.regs), cpu->env.xregs, sizeof(cpu->env.xregs));
+    prstatus.pc = cpu->env.pc;
+    prstatus.pstate = cpu->env.pstate;
+
+    return write_elf_note("CORE", NT_PRSTATUS,
+                          &prstatus, sizeof(prstatus),
+                          f, opaque);
+}
+
+int arm_cpu_write_elf32_qemunote(WriteCoreDumpFunction f,
+                                  CPUState *cpu, void *opaque)
+{
+    return 0;
+}
+
+int arm_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
+                                  CPUState *cpu, void *opaque)
+{
+    return 0;
+}
+
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const struct GuestPhysBlockList *guest_phys_blocks)
+{
+    info->d_machine = ELF_MACHINE;
+    info->d_class = (info->d_machine == EM_ARM) ? ELFCLASS32 : ELFCLASS64;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    info->d_endian = ELFDATA2MSB;
+#else
+    info->d_endian = ELFDATA2LSB;
+#endif
+
+    return 0;
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    size_t elf_note_size = round4(sizeof("CORE"));
+
+    if (machine == EM_ARM) {
+        elf_note_size += sizeof(Elf32_Nhdr) + sizeof(arm_elf_prstatus);
+    } else {
+        elf_note_size += sizeof(Elf64_Nhdr) + sizeof(aarch64_elf_prstatus);
+    }
+
+    return elf_note_size * nr_cpus;
+}
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index ed5a644..7de8ba1 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -205,6 +205,14 @@ bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
+int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque);
+int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque);
+int arm_cpu_write_elf32_qemunote(WriteCoreDumpFunction f,
+                                 CPUState *cpu, void *opaque);
+int arm_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
+                                 CPUState *cpu, void *opaque);
 
 hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 285947f..679387a 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1188,6 +1188,10 @@ static void arm_cpu_class_init(ObjectClass *oc, void 
*data)
 #else
     cc->do_interrupt = arm_cpu_do_interrupt;
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
+    cc->write_elf32_note = arm_cpu_write_elf32_note;
+    cc->write_elf64_note = arm_cpu_write_elf64_note;
+    cc->write_elf32_qemunote = arm_cpu_write_elf32_qemunote;
+    cc->write_elf64_qemunote = arm_cpu_write_elf64_qemunote;
     cc->vmsd = &vmstate_arm_cpu;
 #endif
     cc->gdb_num_core_regs = 26;
-- 
2.1.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]