From: Rabin Vincent <rabin@rab.in>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: Rabin Vincent <rabin@rab.in>, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] target-arm: add dump-guest-memory support
Date: Wed, 24 Dec 2014 00:29:18 +0100 [thread overview]
Message-ID: <1419377358-17222-1-git-send-email-rabin@rab.in> (raw)
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 <rabin@rab.in>
---
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
next reply other threads:[~2014-12-23 23:29 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-23 23:29 Rabin Vincent [this message]
2014-12-23 23:45 ` [Qemu-devel] [PATCH] target-arm: add dump-guest-memory support Peter Maydell
2014-12-24 16:54 ` Rabin Vincent
2014-12-24 17:12 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1419377358-17222-1-git-send-email-rabin@rab.in \
--to=rabin@rab.in \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).