All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 1/4] dump: create writable files
@ 2012-06-20 17:28 Rabin Vincent
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 2/4] dump: extract out note helper Rabin Vincent
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Rabin Vincent @ 2012-06-20 17:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Rabin Vincent

Make dump-guest-memory not create read-only files, so that it can
overwrite a file created by a previous invocation without having it to
be removed externally.

Signed-off-by: Rabin Vincent <rabin@rab.in>
---
 dump.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dump.c b/dump.c
index 2bf8d8d..5c5cb4d 100644
--- a/dump.c
+++ b/dump.c
@@ -845,7 +845,8 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
 #endif
 
     if  (strstart(file, "file:", &p)) {
-        fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
+        fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+                       S_IRUSR | S_IWUSR);
         if (fd < 0) {
             error_set(errp, QERR_OPEN_FILE_FAILED, p);
             return;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 2/4] dump: extract out note helper
  2012-06-20 17:28 [Qemu-devel] [PATCH 1/4] dump: create writable files Rabin Vincent
@ 2012-06-20 17:28 ` Rabin Vincent
  2012-07-04  2:21   ` Wen Congyang
  2012-07-04  2:31   ` Wen Congyang
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 3/4] dump: extract out get note size function Rabin Vincent
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support Rabin Vincent
  2 siblings, 2 replies; 10+ messages in thread
From: Rabin Vincent @ 2012-06-20 17:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Rabin Vincent

Make a common helper function to add ELF notes.

Signed-off-by: Rabin Vincent <rabin@rab.in>
---
 dump.c                  |   49 +++++++++++
 dump.h                  |    4 +
 target-i386/arch_dump.c |  206 +++++++++++------------------------------------
 3 files changed, 100 insertions(+), 159 deletions(-)

diff --git a/dump.c b/dump.c
index 5c5cb4d..be96c6c 100644
--- a/dump.c
+++ b/dump.c
@@ -468,6 +468,55 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
     return -1;
 }
 
+int dump_write_elf_note(int class, const char *name, uint32_t type,
+                        void *desc, size_t descsz,
+                        write_core_dump_function f, void *opaque)
+{
+    Elf64_Nhdr *note64;
+    Elf32_Nhdr *note32;
+    void *note;
+    char *buf;
+    size_t note_size, name_size, note_head_size;
+    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 + 3) / 4 + (name_size + 3) / 4 +
+                (descsz + 3) / 4) * 4;
+    note = g_malloc(note_size);
+
+    memset(note, 0, note_size);
+    if (class == ELFCLASS32) {
+        note32 = note;
+        note32->n_namesz = cpu_to_le32(name_size);
+        note32->n_descsz = cpu_to_le32(descsz);
+        note32->n_type = cpu_to_le32(type);
+    } else {
+        note64 = note;
+        note64->n_namesz = cpu_to_le32(name_size);
+        note64->n_descsz = cpu_to_le32(descsz);
+        note64->n_type = cpu_to_le32(type);
+    }
+    buf = note;
+    buf += ((note_head_size + 3) / 4) * 4;
+    memcpy(buf, name, name_size);
+    buf += ((name_size + 3) / 4) * 4;
+    memcpy(buf, desc, descsz);
+
+    ret = f(note, note_size, opaque);
+    g_free(note);
+    if (ret < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
 static int write_elf_loads(DumpState *s)
 {
     target_phys_addr_t offset;
diff --git a/dump.h b/dump.h
index e25b7cf..b07816a 100644
--- a/dump.h
+++ b/dump.h
@@ -32,4 +32,8 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
 int cpu_get_dump_info(ArchDumpInfo *info);
 ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
 
+int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
+                        size_t descsz, write_core_dump_function f,
+                        void *opaque);
+
 #endif
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index 4240278..dbc94bc 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -38,66 +38,41 @@ static int x86_64_write_elf64_note(write_core_dump_function f,
                                    CPUArchState *env, int id,
                                    void *opaque)
 {
-    x86_64_user_regs_struct regs;
-    Elf64_Nhdr *note;
-    char *buf;
-    int descsz, note_size, name_size = 5;
-    const char *name = "CORE";
-    int ret;
-
-    regs.r15 = env->regs[15];
-    regs.r14 = env->regs[14];
-    regs.r13 = env->regs[13];
-    regs.r12 = env->regs[12];
-    regs.r11 = env->regs[11];
-    regs.r10 = env->regs[10];
-    regs.r9  = env->regs[9];
-    regs.r8  = env->regs[8];
-    regs.rbp = env->regs[R_EBP];
-    regs.rsp = env->regs[R_ESP];
-    regs.rdi = env->regs[R_EDI];
-    regs.rsi = env->regs[R_ESI];
-    regs.rdx = env->regs[R_EDX];
-    regs.rcx = env->regs[R_ECX];
-    regs.rbx = env->regs[R_EBX];
-    regs.rax = env->regs[R_EAX];
-    regs.rip = env->eip;
-    regs.eflags = env->eflags;
-
-    regs.orig_rax = 0; /* FIXME */
-    regs.cs = env->segs[R_CS].selector;
-    regs.ss = env->segs[R_SS].selector;
-    regs.fs_base = env->segs[R_FS].base;
-    regs.gs_base = env->segs[R_GS].base;
-    regs.ds = env->segs[R_DS].selector;
-    regs.es = env->segs[R_ES].selector;
-    regs.fs = env->segs[R_FS].selector;
-    regs.gs = env->segs[R_GS].selector;
-
-    descsz = sizeof(x86_64_elf_prstatus);
-    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
-                (descsz + 3) / 4) * 4;
-    note = g_malloc(note_size);
-
-    memset(note, 0, note_size);
-    note->n_namesz = cpu_to_le32(name_size);
-    note->n_descsz = cpu_to_le32(descsz);
-    note->n_type = cpu_to_le32(NT_PRSTATUS);
-    buf = (char *)note;
-    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
-    memcpy(buf, name, name_size);
-    buf += ((name_size + 3) / 4) * 4;
-    memcpy(buf + 32, &id, 4); /* pr_pid */
-    buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
-    memcpy(buf, &regs, sizeof(x86_64_user_regs_struct));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
-
-    return 0;
+    x86_64_elf_prstatus prstatus;
+
+    prstatus.pid = id;
+    prstatus.regs.r15 = env->regs[15];
+    prstatus.regs.r14 = env->regs[14];
+    prstatus.regs.r13 = env->regs[13];
+    prstatus.regs.r12 = env->regs[12];
+    prstatus.regs.r11 = env->regs[11];
+    prstatus.regs.r10 = env->regs[10];
+    prstatus.regs.r9  = env->regs[9];
+    prstatus.regs.r8  = env->regs[8];
+    prstatus.regs.rbp = env->regs[R_EBP];
+    prstatus.regs.rsp = env->regs[R_ESP];
+    prstatus.regs.rdi = env->regs[R_EDI];
+    prstatus.regs.rsi = env->regs[R_ESI];
+    prstatus.regs.rdx = env->regs[R_EDX];
+    prstatus.regs.rcx = env->regs[R_ECX];
+    prstatus.regs.rbx = env->regs[R_EBX];
+    prstatus.regs.rax = env->regs[R_EAX];
+    prstatus.regs.rip = env->eip;
+    prstatus.regs.eflags = env->eflags;
+
+    prstatus.regs.orig_rax = 0; /* FIXME */
+    prstatus.regs.cs = env->segs[R_CS].selector;
+    prstatus.regs.ss = env->segs[R_SS].selector;
+    prstatus.regs.fs_base = env->segs[R_FS].base;
+    prstatus.regs.gs_base = env->segs[R_GS].base;
+    prstatus.regs.ds = env->segs[R_DS].selector;
+    prstatus.regs.es = env->segs[R_ES].selector;
+    prstatus.regs.fs = env->segs[R_FS].selector;
+    prstatus.regs.gs = env->segs[R_GS].selector;
+
+    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
 }
 #endif
 
@@ -148,35 +123,12 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
                                 int id, void *opaque)
 {
     x86_elf_prstatus prstatus;
-    Elf64_Nhdr *note;
-    char *buf;
-    int descsz, note_size, name_size = 5;
-    const char *name = "CORE";
-    int ret;
 
     x86_fill_elf_prstatus(&prstatus, env, id);
-    descsz = sizeof(x86_elf_prstatus);
-    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
-                (descsz + 3) / 4) * 4;
-    note = g_malloc(note_size);
-
-    memset(note, 0, note_size);
-    note->n_namesz = cpu_to_le32(name_size);
-    note->n_descsz = cpu_to_le32(descsz);
-    note->n_type = cpu_to_le32(NT_PRSTATUS);
-    buf = (char *)note;
-    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
-    memcpy(buf, name, name_size);
-    buf += ((name_size + 3) / 4) * 4;
-    memcpy(buf, &prstatus, sizeof(prstatus));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
 
-    return 0;
+    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
 }
 
 int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
@@ -202,35 +154,12 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
                          int cpuid, void *opaque)
 {
     x86_elf_prstatus prstatus;
-    Elf32_Nhdr *note;
-    char *buf;
-    int descsz, note_size, name_size = 5;
-    const char *name = "CORE";
-    int ret;
 
     x86_fill_elf_prstatus(&prstatus, env, cpuid);
-    descsz = sizeof(x86_elf_prstatus);
-    note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
-                (descsz + 3) / 4) * 4;
-    note = g_malloc(note_size);
-
-    memset(note, 0, note_size);
-    note->n_namesz = cpu_to_le32(name_size);
-    note->n_descsz = cpu_to_le32(descsz);
-    note->n_type = cpu_to_le32(NT_PRSTATUS);
-    buf = (char *)note;
-    buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
-    memcpy(buf, name, name_size);
-    buf += ((name_size + 3) / 4) * 4;
-    memcpy(buf, &prstatus, sizeof(prstatus));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
 
-    return 0;
+    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
 }
 
 /*
@@ -317,69 +246,28 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
     s->cr[4] = env->cr[4];
 }
 
-static inline int cpu_write_qemu_note(write_core_dump_function f,
+static inline int cpu_write_qemu_note(int class, write_core_dump_function f,
                                       CPUArchState *env,
-                                      void *opaque,
-                                      int type)
+                                      void *opaque)
 {
     QEMUCPUState state;
-    Elf64_Nhdr *note64;
-    Elf32_Nhdr *note32;
-    void *note;
-    char *buf;
-    int descsz, note_size, name_size = 5, note_head_size;
-    const char *name = "QEMU";
-    int ret;
 
     qemu_get_cpustate(&state, env);
 
-    descsz = sizeof(state);
-    if (type == 0) {
-        note_head_size = sizeof(Elf32_Nhdr);
-    } else {
-        note_head_size = sizeof(Elf64_Nhdr);
-    }
-    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
-                (descsz + 3) / 4) * 4;
-    note = g_malloc(note_size);
-
-    memset(note, 0, note_size);
-    if (type == 0) {
-        note32 = note;
-        note32->n_namesz = cpu_to_le32(name_size);
-        note32->n_descsz = cpu_to_le32(descsz);
-        note32->n_type = 0;
-    } else {
-        note64 = note;
-        note64->n_namesz = cpu_to_le32(name_size);
-        note64->n_descsz = cpu_to_le32(descsz);
-        note64->n_type = 0;
-    }
-    buf = note;
-    buf += ((note_head_size + 3) / 4) * 4;
-    memcpy(buf, name, name_size);
-    buf += ((name_size + 3) / 4) * 4;
-    memcpy(buf, &state, sizeof(state));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
-
-    return 0;
+    return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state),
+                               f, opaque);
 }
 
 int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
                              void *opaque)
 {
-    return cpu_write_qemu_note(f, env, opaque, 1);
+    return cpu_write_qemu_note(ELFCLASS64, f, env, opaque);
 }
 
 int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
                              void *opaque)
 {
-    return cpu_write_qemu_note(f, env, opaque, 0);
+    return cpu_write_qemu_note(ELFCLASS32, f, env, opaque);
 }
 
 int cpu_get_dump_info(ArchDumpInfo *info)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 3/4] dump: extract out get note size function
  2012-06-20 17:28 [Qemu-devel] [PATCH 1/4] dump: create writable files Rabin Vincent
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 2/4] dump: extract out note helper Rabin Vincent
@ 2012-06-20 17:28 ` Rabin Vincent
  2012-07-04  2:25   ` Wen Congyang
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support Rabin Vincent
  2 siblings, 1 reply; 10+ messages in thread
From: Rabin Vincent @ 2012-06-20 17:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Rabin Vincent

Extract out the ELF note size function from i386 so we can use it from
other targets.

Signed-off-by: Rabin Vincent <rabin@rab.in>
---
 dump.c                  |   15 +++++++++++++++
 dump.h                  |    2 ++
 target-i386/arch_dump.c |   14 ++------------
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/dump.c b/dump.c
index be96c6c..d3ca953 100644
--- a/dump.c
+++ b/dump.c
@@ -468,6 +468,21 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
     return -1;
 }
 
+size_t dump_get_note_size(int class, const char *name, size_t descsz)
+{
+    int name_size = strlen(name) + 1;
+    int note_head_size;
+
+    if (class == ELFCLASS32) {
+        note_head_size = sizeof(Elf32_Nhdr);
+    } else {
+        note_head_size = sizeof(Elf64_Nhdr);
+    }
+
+    return ((note_head_size + 3) / 4 + (name_size + 3) / 4
+            + (descsz + 3) / 4) * 4;
+}
+
 int dump_write_elf_note(int class, const char *name, uint32_t type,
                         void *desc, size_t descsz,
                         write_core_dump_function f, void *opaque)
diff --git a/dump.h b/dump.h
index b07816a..a06b149 100644
--- a/dump.h
+++ b/dump.h
@@ -36,4 +36,6 @@ int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
                         size_t descsz, write_core_dump_function f,
                         void *opaque);
 
+size_t dump_get_note_size(int class, const char *name, size_t descsz);
+
 #endif
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index dbc94bc..e2d18a0 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -305,18 +305,10 @@ int cpu_get_dump_info(ArchDumpInfo *info)
 
 ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 {
-    int name_size = 5; /* "CORE" or "QEMU" */
     size_t elf_note_size = 0;
     size_t qemu_note_size = 0;
     int elf_desc_size = 0;
     int qemu_desc_size = 0;
-    int note_head_size;
-
-    if (class == ELFCLASS32) {
-        note_head_size = sizeof(Elf32_Nhdr);
-    } else {
-        note_head_size = sizeof(Elf64_Nhdr);
-    }
 
     if (machine == EM_386) {
         elf_desc_size = sizeof(x86_elf_prstatus);
@@ -328,10 +320,8 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 #endif
     qemu_desc_size = sizeof(QEMUCPUState);
 
-    elf_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
-                     (elf_desc_size + 3) / 4) * 4;
-    qemu_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
-                      (qemu_desc_size + 3) / 4) * 4;
+    elf_note_size = dump_get_note_size(class, "CORE", elf_desc_size);
+    qemu_note_size = dump_get_note_size(class, "QEMU", qemu_desc_size);
 
     return (elf_note_size + qemu_note_size) * nr_cpus;
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support
  2012-06-20 17:28 [Qemu-devel] [PATCH 1/4] dump: create writable files Rabin Vincent
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 2/4] dump: extract out note helper Rabin Vincent
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 3/4] dump: extract out get note size function Rabin Vincent
@ 2012-06-20 17:28 ` Rabin Vincent
       [not found]   ` <CAFEAcA_x1HKmzgdjbi1Xv90Kwn3fwL3U3+_hiaO0wkTiNFR4pA@mail.gmail.com>
  2 siblings, 1 reply; 10+ messages in thread
From: Rabin Vincent @ 2012-06-20 17:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Rabin Vincent

Add a minimal dump-guest-memory support for ARM.  The -p option is not
supported and we don't add any QEMU-specific notes.

Signed-off-by: Rabin Vincent <rabin@rab.in>
---
 configure                        |    4 +--
 target-arm/Makefile.objs         |    2 +-
 target-arm/arch_dump.c           |   59 ++++++++++++++++++++++++++++++++++++++
 target-arm/arch_memory_mapping.c |   13 +++++++++
 4 files changed, 75 insertions(+), 3 deletions(-)
 create mode 100644 target-arm/arch_dump.c
 create mode 100644 target-arm/arch_memory_mapping.c

diff --git a/configure b/configure
index b68c0ca..a20ad19 100755
--- a/configure
+++ b/configure
@@ -3727,7 +3727,7 @@ case "$target_arch2" in
     fi
 esac
 case "$target_arch2" in
-  i386|x86_64)
+  arm|i386|x86_64)
     echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
 esac
 if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then
@@ -3746,7 +3746,7 @@ if test "$target_softmmu" = "yes" ; then
     echo "subdir-$target: subdir-libcacard" >> $config_host_mak
   fi
   case "$target_arch2" in
-    i386|x86_64)
+    arm|i386|x86_64)
       echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
   esac
 fi
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index f447c4f..837b374 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y += arm-semi.o
-obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
 obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += neon_helper.o iwmmxt_helper.o
 
diff --git a/target-arm/arch_dump.c b/target-arm/arch_dump.c
new file mode 100644
index 0000000..47a7e40
--- /dev/null
+++ b/target-arm/arch_dump.c
@@ -0,0 +1,59 @@
+#include "cpu.h"
+#include "cpu-all.h"
+#include "dump.h"
+#include "elf.h"
+
+typedef struct {
+    char pad1[24];
+    uint32_t pid;
+    char pad2[44];
+    uint32_t regs[18];
+    char pad3[4];
+} arm_elf_prstatus;
+
+int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
+                         int cpuid, void *opaque)
+{
+    return -1;
+}
+
+int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
+                         int cpuid, void *opaque)
+{
+    arm_elf_prstatus prstatus;
+
+    memset(&prstatus, 0, sizeof(prstatus));
+    memcpy(&(prstatus.regs), env->regs, sizeof(env->regs));
+    prstatus.pid = cpuid;
+
+    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
+}
+
+int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
+                             void *opaque)
+{
+    return -1;
+}
+
+int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
+                             void *opaque)
+{
+    return 0;
+}
+
+int cpu_get_dump_info(ArchDumpInfo *info)
+{
+    info->d_machine = EM_ARM;
+    info->d_endian = ELFDATA2LSB;
+    info->d_class = ELFCLASS32;
+
+    return 0;
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    return nr_cpus * dump_get_note_size(ELFCLASS32, "CORE",
+                                        sizeof(arm_elf_prstatus));
+}
diff --git a/target-arm/arch_memory_mapping.c b/target-arm/arch_memory_mapping.c
new file mode 100644
index 0000000..eeaaf09
--- /dev/null
+++ b/target-arm/arch_memory_mapping.c
@@ -0,0 +1,13 @@
+#include "cpu.h"
+#include "cpu-all.h"
+#include "memory_mapping.h"
+
+bool cpu_paging_enabled(CPUArchState *env)
+{
+    return 0;
+}
+
+int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
+{
+    return -1;
+}
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support
       [not found]   ` <CAFEAcA_x1HKmzgdjbi1Xv90Kwn3fwL3U3+_hiaO0wkTiNFR4pA@mail.gmail.com>
@ 2012-07-01  6:22     ` Rabin Vincent
  2012-07-04  2:48       ` Wen Congyang
       [not found]     ` <4FEDA2C0.7040405@suse.de>
  1 sibling, 1 reply; 10+ messages in thread
From: Rabin Vincent @ 2012-07-01  6:22 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Andreas Färber

On Thu, Jun 28, 2012 at 05:46:02PM +0100, Peter Maydell wrote:
> On 20 June 2012 18:28, Rabin Vincent <rabin@rab.in> wrote:
> > Add a minimal dump-guest-memory support for ARM.  The -p option is not
> > supported and we don't add any QEMU-specific notes.
> 
> So what does this patch give us? This commit message is pretty
> short and I couldn't find a cover message for the patchset...

It makes the dump-guest-memory command work for arm-softmmu.  The
resulting core dump can be analysed with a tool such as the crash
utility.

> 
> > Signed-off-by: Rabin Vincent <rabin@rab.in>
> > ---
> >  configure                        |    4 +--
> >  target-arm/Makefile.objs         |    2 +-
> >  target-arm/arch_dump.c           |   59 ++++++++++++++++++++++++++++++++++++++
> >  target-arm/arch_memory_mapping.c |   13 +++++++++
> >  4 files changed, 75 insertions(+), 3 deletions(-)
> >  create mode 100644 target-arm/arch_dump.c
> >  create mode 100644 target-arm/arch_memory_mapping.c
> >
> > diff --git a/configure b/configure
> > index b68c0ca..a20ad19 100755
> > --- a/configure
> > +++ b/configure
> > @@ -3727,7 +3727,7 @@ case "$target_arch2" in
> >     fi
> >  esac
> >  case "$target_arch2" in
> > -  i386|x86_64)
> > +  arm|i386|x86_64)
> >     echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
> >  esac
> >  if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then
> > @@ -3746,7 +3746,7 @@ if test "$target_softmmu" = "yes" ; then
> >     echo "subdir-$target: subdir-libcacard" >> $config_host_mak
> >   fi
> >   case "$target_arch2" in
> > -    i386|x86_64)
> > +    arm|i386|x86_64)
> >       echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
> >   esac
> >  fi
> > diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
> > index f447c4f..837b374 100644
> > --- a/target-arm/Makefile.objs
> > +++ b/target-arm/Makefile.objs
> > @@ -1,5 +1,5 @@
> >  obj-y += arm-semi.o
> > -obj-$(CONFIG_SOFTMMU) += machine.o
> > +obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
> >  obj-y += translate.o op_helper.o helper.o cpu.o
> >  obj-y += neon_helper.o iwmmxt_helper.o
> >
> > diff --git a/target-arm/arch_dump.c b/target-arm/arch_dump.c
> > new file mode 100644
> > index 0000000..47a7e40
> > --- /dev/null
> > +++ b/target-arm/arch_dump.c
> > @@ -0,0 +1,59 @@
> > +#include "cpu.h"
> > +#include "cpu-all.h"
> > +#include "dump.h"
> > +#include "elf.h"
> > +
> > +typedef struct {
> > +    char pad1[24];
> > +    uint32_t pid;
> > +    char pad2[44];
> > +    uint32_t regs[18];
> > +    char pad3[4];
> > +} arm_elf_prstatus;
> 
> I'm guessing this is following some specification's structure layout;
> what specification?

struct elf_prstatus from the Linux kernel's include/linux/elfcore.h.

> 
> > +
> > +int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
> > +                         int cpuid, void *opaque)
> 
> Should these APIs really be taking a CPUArchState* rather rather than
> an ARMCPU* ? (Andreas?)

No idea.  Cc'ing Wen, who added the APIs.

> 
> > +{
> > +    return -1;
> > +}
> > +
> > +int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
> > +                         int cpuid, void *opaque)
> > +{
> > +    arm_elf_prstatus prstatus;
> > +
> > +    memset(&prstatus, 0, sizeof(prstatus));
> > +    memcpy(&(prstatus.regs), env->regs, sizeof(env->regs));
> 
> This looks a bit odd -- env->regs[] is a 16 word array but
> prstatus.regs is 18 words. What are the last two words for?

CPSR and orig_r0.  orig_r0 is not useful, but I think we can save the
CPSR in there.

> 
> > +    prstatus.pid = cpuid;
> > +
> > +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
> > +                               &prstatus, sizeof(prstatus),
> > +                               f, opaque);
> > +}
> > +
> > +int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
> > +                             void *opaque)
> > +{
> > +    return -1;
> > +}
> > +
> > +int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
> > +                             void *opaque)
> > +{
> > +    return 0;
> > +}
> > +
> > +int cpu_get_dump_info(ArchDumpInfo *info)
> > +{
> > +    info->d_machine = EM_ARM;
> > +    info->d_endian = ELFDATA2LSB;
> 
> ...even for big endian ARM?

I'll use TARGET_WORDS_BIGENDIAN to check.

Though it appears we don't have a armbe-softmmu?

> 
> > +    info->d_class = ELFCLASS32;
> > +
> > +    return 0;
> > +}
> > +
> > +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
> > +{
> > +    return nr_cpus * dump_get_note_size(ELFCLASS32, "CORE",
> > +                                        sizeof(arm_elf_prstatus));
> > +}
> > diff --git a/target-arm/arch_memory_mapping.c b/target-arm/arch_memory_mapping.c
> > new file mode 100644
> > index 0000000..eeaaf09
> > --- /dev/null
> > +++ b/target-arm/arch_memory_mapping.c
> > @@ -0,0 +1,13 @@
> > +#include "cpu.h"
> > +#include "cpu-all.h"
> > +#include "memory_mapping.h"
> > +
> > +bool cpu_paging_enabled(CPUArchState *env)
> > +{
> > +    return 0;
> > +}
> > +
> > +int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
> > +{
> > +    return -1;
> > +}
> 
> Why do we need these null implementations and why do they
> work better than the default ones in memory_mapping-stub.c ?

The implementations are to make the dump-guest-memory command build.  A
full implementation would add support for the "-p" option which afaics
is supposed to walk the page tables and dump only the pages which are
mapped instead of the complete RAM.  I personally have no need for this
option, so they are only null implementations which result in an error
if this option is used.

The current config code keeps memory-mapping.c and memory-mapping-stub.c
exclusive.  I think we should be able to make some changes there to
allow us to use memory-mapping-stub.c instead of this
arch_memory_mapping.c.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] dump: extract out note helper
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 2/4] dump: extract out note helper Rabin Vincent
@ 2012-07-04  2:21   ` Wen Congyang
  2012-07-04  2:31   ` Wen Congyang
  1 sibling, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2012-07-04  2:21 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: qemu-devel

Hi, Rabin

Sorry for later reviewing...

At 06/21/2012 01:28 AM, Rabin Vincent Wrote:
> Make a common helper function to add ELF notes.
> 
> Signed-off-by: Rabin Vincent <rabin@rab.in>
> ---
>  dump.c                  |   49 +++++++++++
>  dump.h                  |    4 +
>  target-i386/arch_dump.c |  206 +++++++++++------------------------------------
>  3 files changed, 100 insertions(+), 159 deletions(-)
> 
> diff --git a/dump.c b/dump.c
> index 5c5cb4d..be96c6c 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -468,6 +468,55 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
>      return -1;
>  }
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type,
> +                        void *desc, size_t descsz,
> +                        write_core_dump_function f, void *opaque)
> +{
> +    Elf64_Nhdr *note64;
> +    Elf32_Nhdr *note32;
> +    void *note;
> +    char *buf;
> +    size_t note_size, name_size, note_head_size;
> +    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 + 3) / 4 + (name_size + 3) / 4 +
> +                (descsz + 3) / 4) * 4;
> +    note = g_malloc(note_size);
> +
> +    memset(note, 0, note_size);
> +    if (class == ELFCLASS32) {
> +        note32 = note;
> +        note32->n_namesz = cpu_to_le32(name_size);
> +        note32->n_descsz = cpu_to_le32(descsz);
> +        note32->n_type = cpu_to_le32(type);

This function may be called by all targets, so you can not say the target
is little endian.

The other code looks fine to me.

Thanks
Wen Congyang
> +    } else {
> +        note64 = note;
> +        note64->n_namesz = cpu_to_le32(name_size);
> +        note64->n_descsz = cpu_to_le32(descsz);
> +        note64->n_type = cpu_to_le32(type);
> +    }
> +    buf = note;
> +    buf += ((note_head_size + 3) / 4) * 4;
> +    memcpy(buf, name, name_size);
> +    buf += ((name_size + 3) / 4) * 4;
> +    memcpy(buf, desc, descsz);
> +
> +    ret = f(note, note_size, opaque);
> +    g_free(note);
> +    if (ret < 0) {
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>  static int write_elf_loads(DumpState *s)
>  {
>      target_phys_addr_t offset;
> diff --git a/dump.h b/dump.h
> index e25b7cf..b07816a 100644
> --- a/dump.h
> +++ b/dump.h
> @@ -32,4 +32,8 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>  int cpu_get_dump_info(ArchDumpInfo *info);
>  ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
> +                        size_t descsz, write_core_dump_function f,
> +                        void *opaque);
> +
>  #endif
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index 4240278..dbc94bc 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -38,66 +38,41 @@ static int x86_64_write_elf64_note(write_core_dump_function f,
>                                     CPUArchState *env, int id,
>                                     void *opaque)
>  {
> -    x86_64_user_regs_struct regs;
> -    Elf64_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
> -
> -    regs.r15 = env->regs[15];
> -    regs.r14 = env->regs[14];
> -    regs.r13 = env->regs[13];
> -    regs.r12 = env->regs[12];
> -    regs.r11 = env->regs[11];
> -    regs.r10 = env->regs[10];
> -    regs.r9  = env->regs[9];
> -    regs.r8  = env->regs[8];
> -    regs.rbp = env->regs[R_EBP];
> -    regs.rsp = env->regs[R_ESP];
> -    regs.rdi = env->regs[R_EDI];
> -    regs.rsi = env->regs[R_ESI];
> -    regs.rdx = env->regs[R_EDX];
> -    regs.rcx = env->regs[R_ECX];
> -    regs.rbx = env->regs[R_EBX];
> -    regs.rax = env->regs[R_EAX];
> -    regs.rip = env->eip;
> -    regs.eflags = env->eflags;
> -
> -    regs.orig_rax = 0; /* FIXME */
> -    regs.cs = env->segs[R_CS].selector;
> -    regs.ss = env->segs[R_SS].selector;
> -    regs.fs_base = env->segs[R_FS].base;
> -    regs.gs_base = env->segs[R_GS].base;
> -    regs.ds = env->segs[R_DS].selector;
> -    regs.es = env->segs[R_ES].selector;
> -    regs.fs = env->segs[R_FS].selector;
> -    regs.gs = env->segs[R_GS].selector;
> -
> -    descsz = sizeof(x86_64_elf_prstatus);
> -    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    note->n_namesz = cpu_to_le32(name_size);
> -    note->n_descsz = cpu_to_le32(descsz);
> -    note->n_type = cpu_to_le32(NT_PRSTATUS);
> -    buf = (char *)note;
> -    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf + 32, &id, 4); /* pr_pid */
> -    buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
> -    memcpy(buf, &regs, sizeof(x86_64_user_regs_struct));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    x86_64_elf_prstatus prstatus;
> +
> +    prstatus.pid = id;
> +    prstatus.regs.r15 = env->regs[15];
> +    prstatus.regs.r14 = env->regs[14];
> +    prstatus.regs.r13 = env->regs[13];
> +    prstatus.regs.r12 = env->regs[12];
> +    prstatus.regs.r11 = env->regs[11];
> +    prstatus.regs.r10 = env->regs[10];
> +    prstatus.regs.r9  = env->regs[9];
> +    prstatus.regs.r8  = env->regs[8];
> +    prstatus.regs.rbp = env->regs[R_EBP];
> +    prstatus.regs.rsp = env->regs[R_ESP];
> +    prstatus.regs.rdi = env->regs[R_EDI];
> +    prstatus.regs.rsi = env->regs[R_ESI];
> +    prstatus.regs.rdx = env->regs[R_EDX];
> +    prstatus.regs.rcx = env->regs[R_ECX];
> +    prstatus.regs.rbx = env->regs[R_EBX];
> +    prstatus.regs.rax = env->regs[R_EAX];
> +    prstatus.regs.rip = env->eip;
> +    prstatus.regs.eflags = env->eflags;
> +
> +    prstatus.regs.orig_rax = 0; /* FIXME */
> +    prstatus.regs.cs = env->segs[R_CS].selector;
> +    prstatus.regs.ss = env->segs[R_SS].selector;
> +    prstatus.regs.fs_base = env->segs[R_FS].base;
> +    prstatus.regs.gs_base = env->segs[R_GS].base;
> +    prstatus.regs.ds = env->segs[R_DS].selector;
> +    prstatus.regs.es = env->segs[R_ES].selector;
> +    prstatus.regs.fs = env->segs[R_FS].selector;
> +    prstatus.regs.gs = env->segs[R_GS].selector;
> +
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  #endif
>  
> @@ -148,35 +123,12 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
>                                  int id, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf64_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, id);
> -    descsz = sizeof(x86_elf_prstatus);
> -    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    note->n_namesz = cpu_to_le32(name_size);
> -    note->n_descsz = cpu_to_le32(descsz);
> -    note->n_type = cpu_to_le32(NT_PRSTATUS);
> -    buf = (char *)note;
> -    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
> @@ -202,35 +154,12 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
>                           int cpuid, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf32_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, cpuid);
> -    descsz = sizeof(x86_elf_prstatus);
> -    note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    note->n_namesz = cpu_to_le32(name_size);
> -    note->n_descsz = cpu_to_le32(descsz);
> -    note->n_type = cpu_to_le32(NT_PRSTATUS);
> -    buf = (char *)note;
> -    buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  /*
> @@ -317,69 +246,28 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
>      s->cr[4] = env->cr[4];
>  }
>  
> -static inline int cpu_write_qemu_note(write_core_dump_function f,
> +static inline int cpu_write_qemu_note(int class, write_core_dump_function f,
>                                        CPUArchState *env,
> -                                      void *opaque,
> -                                      int type)
> +                                      void *opaque)
>  {
>      QEMUCPUState state;
> -    Elf64_Nhdr *note64;
> -    Elf32_Nhdr *note32;
> -    void *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5, note_head_size;
> -    const char *name = "QEMU";
> -    int ret;
>  
>      qemu_get_cpustate(&state, env);
>  
> -    descsz = sizeof(state);
> -    if (type == 0) {
> -        note_head_size = sizeof(Elf32_Nhdr);
> -    } else {
> -        note_head_size = sizeof(Elf64_Nhdr);
> -    }
> -    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    if (type == 0) {
> -        note32 = note;
> -        note32->n_namesz = cpu_to_le32(name_size);
> -        note32->n_descsz = cpu_to_le32(descsz);
> -        note32->n_type = 0;
> -    } else {
> -        note64 = note;
> -        note64->n_namesz = cpu_to_le32(name_size);
> -        note64->n_descsz = cpu_to_le32(descsz);
> -        note64->n_type = 0;
> -    }
> -    buf = note;
> -    buf += ((note_head_size + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &state, sizeof(state));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 1);
> +    return cpu_write_qemu_note(ELFCLASS64, f, env, opaque);
>  }
>  
>  int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 0);
> +    return cpu_write_qemu_note(ELFCLASS32, f, env, opaque);
>  }
>  
>  int cpu_get_dump_info(ArchDumpInfo *info)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] dump: extract out get note size function
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 3/4] dump: extract out get note size function Rabin Vincent
@ 2012-07-04  2:25   ` Wen Congyang
  0 siblings, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2012-07-04  2:25 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: qemu-devel

At 06/21/2012 01:28 AM, Rabin Vincent Wrote:
> Extract out the ELF note size function from i386 so we can use it from
> other targets.
> 
> Signed-off-by: Rabin Vincent <rabin@rab.in>

This patch looks fine to me.

Thanks
Wen Congyang
> ---
>  dump.c                  |   15 +++++++++++++++
>  dump.h                  |    2 ++
>  target-i386/arch_dump.c |   14 ++------------
>  3 files changed, 19 insertions(+), 12 deletions(-)
> 
> diff --git a/dump.c b/dump.c
> index be96c6c..d3ca953 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -468,6 +468,21 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
>      return -1;
>  }
>  
> +size_t dump_get_note_size(int class, const char *name, size_t descsz)
> +{
> +    int name_size = strlen(name) + 1;
> +    int note_head_size;
> +
> +    if (class == ELFCLASS32) {
> +        note_head_size = sizeof(Elf32_Nhdr);
> +    } else {
> +        note_head_size = sizeof(Elf64_Nhdr);
> +    }
> +
> +    return ((note_head_size + 3) / 4 + (name_size + 3) / 4
> +            + (descsz + 3) / 4) * 4;
> +}
> +
>  int dump_write_elf_note(int class, const char *name, uint32_t type,
>                          void *desc, size_t descsz,
>                          write_core_dump_function f, void *opaque)
> diff --git a/dump.h b/dump.h
> index b07816a..a06b149 100644
> --- a/dump.h
> +++ b/dump.h
> @@ -36,4 +36,6 @@ int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
>                          size_t descsz, write_core_dump_function f,
>                          void *opaque);
>  
> +size_t dump_get_note_size(int class, const char *name, size_t descsz);
> +
>  #endif
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index dbc94bc..e2d18a0 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -305,18 +305,10 @@ int cpu_get_dump_info(ArchDumpInfo *info)
>  
>  ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>  {
> -    int name_size = 5; /* "CORE" or "QEMU" */
>      size_t elf_note_size = 0;
>      size_t qemu_note_size = 0;
>      int elf_desc_size = 0;
>      int qemu_desc_size = 0;
> -    int note_head_size;
> -
> -    if (class == ELFCLASS32) {
> -        note_head_size = sizeof(Elf32_Nhdr);
> -    } else {
> -        note_head_size = sizeof(Elf64_Nhdr);
> -    }
>  
>      if (machine == EM_386) {
>          elf_desc_size = sizeof(x86_elf_prstatus);
> @@ -328,10 +320,8 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>  #endif
>      qemu_desc_size = sizeof(QEMUCPUState);
>  
> -    elf_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> -                     (elf_desc_size + 3) / 4) * 4;
> -    qemu_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> -                      (qemu_desc_size + 3) / 4) * 4;
> +    elf_note_size = dump_get_note_size(class, "CORE", elf_desc_size);
> +    qemu_note_size = dump_get_note_size(class, "QEMU", qemu_desc_size);
>  
>      return (elf_note_size + qemu_note_size) * nr_cpus;
>  }

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] dump: extract out note helper
  2012-06-20 17:28 ` [Qemu-devel] [PATCH 2/4] dump: extract out note helper Rabin Vincent
  2012-07-04  2:21   ` Wen Congyang
@ 2012-07-04  2:31   ` Wen Congyang
  1 sibling, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2012-07-04  2:31 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: qemu-devel

At 06/21/2012 01:28 AM, Rabin Vincent Wrote:
> Make a common helper function to add ELF notes.
> 
> Signed-off-by: Rabin Vincent <rabin@rab.in>
> ---
>  dump.c                  |   49 +++++++++++
>  dump.h                  |    4 +
>  target-i386/arch_dump.c |  206 +++++++++++------------------------------------
>  3 files changed, 100 insertions(+), 159 deletions(-)
> 
> diff --git a/dump.c b/dump.c
> index 5c5cb4d..be96c6c 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -468,6 +468,55 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
>      return -1;
>  }
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type,
> +                        void *desc, size_t descsz,
> +                        write_core_dump_function f, void *opaque)
> +{
> +    Elf64_Nhdr *note64;
> +    Elf32_Nhdr *note32;
> +    void *note;
> +    char *buf;
> +    size_t note_size, name_size, note_head_size;
> +    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 + 3) / 4 + (name_size + 3) / 4 +
> +                (descsz + 3) / 4) * 4;
> +    note = g_malloc(note_size);
> +
> +    memset(note, 0, note_size);
> +    if (class == ELFCLASS32) {
> +        note32 = note;
> +        note32->n_namesz = cpu_to_le32(name_size);
> +        note32->n_descsz = cpu_to_le32(descsz);
> +        note32->n_type = cpu_to_le32(type);
> +    } else {
> +        note64 = note;
> +        note64->n_namesz = cpu_to_le32(name_size);
> +        note64->n_descsz = cpu_to_le32(descsz);
> +        note64->n_type = cpu_to_le32(type);
> +    }
> +    buf = note;
> +    buf += ((note_head_size + 3) / 4) * 4;
> +    memcpy(buf, name, name_size);
> +    buf += ((name_size + 3) / 4) * 4;
> +    memcpy(buf, desc, descsz);
> +
> +    ret = f(note, note_size, opaque);
> +    g_free(note);
> +    if (ret < 0) {
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>  static int write_elf_loads(DumpState *s)
>  {
>      target_phys_addr_t offset;
> diff --git a/dump.h b/dump.h
> index e25b7cf..b07816a 100644
> --- a/dump.h
> +++ b/dump.h
> @@ -32,4 +32,8 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>  int cpu_get_dump_info(ArchDumpInfo *info);
>  ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
> +                        size_t descsz, write_core_dump_function f,
> +                        void *opaque);
> +
>  #endif
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index 4240278..dbc94bc 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -38,66 +38,41 @@ static int x86_64_write_elf64_note(write_core_dump_function f,
>                                     CPUArchState *env, int id,
>                                     void *opaque)
>  {
> -    x86_64_user_regs_struct regs;
> -    Elf64_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
> -
> -    regs.r15 = env->regs[15];
> -    regs.r14 = env->regs[14];
> -    regs.r13 = env->regs[13];
> -    regs.r12 = env->regs[12];
> -    regs.r11 = env->regs[11];
> -    regs.r10 = env->regs[10];
> -    regs.r9  = env->regs[9];
> -    regs.r8  = env->regs[8];
> -    regs.rbp = env->regs[R_EBP];
> -    regs.rsp = env->regs[R_ESP];
> -    regs.rdi = env->regs[R_EDI];
> -    regs.rsi = env->regs[R_ESI];
> -    regs.rdx = env->regs[R_EDX];
> -    regs.rcx = env->regs[R_ECX];
> -    regs.rbx = env->regs[R_EBX];
> -    regs.rax = env->regs[R_EAX];
> -    regs.rip = env->eip;
> -    regs.eflags = env->eflags;
> -
> -    regs.orig_rax = 0; /* FIXME */
> -    regs.cs = env->segs[R_CS].selector;
> -    regs.ss = env->segs[R_SS].selector;
> -    regs.fs_base = env->segs[R_FS].base;
> -    regs.gs_base = env->segs[R_GS].base;
> -    regs.ds = env->segs[R_DS].selector;
> -    regs.es = env->segs[R_ES].selector;
> -    regs.fs = env->segs[R_FS].selector;
> -    regs.gs = env->segs[R_GS].selector;
> -
> -    descsz = sizeof(x86_64_elf_prstatus);
> -    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    note->n_namesz = cpu_to_le32(name_size);
> -    note->n_descsz = cpu_to_le32(descsz);
> -    note->n_type = cpu_to_le32(NT_PRSTATUS);
> -    buf = (char *)note;
> -    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf + 32, &id, 4); /* pr_pid */
> -    buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
> -    memcpy(buf, &regs, sizeof(x86_64_user_regs_struct));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    x86_64_elf_prstatus prstatus;

You should set all fileds of prstatus to 0. If not,
I guess you may meet some surprising problem when
you deal with the core.

Thanks
Wen Congyang

> +
> +    prstatus.pid = id;
> +    prstatus.regs.r15 = env->regs[15];
> +    prstatus.regs.r14 = env->regs[14];
> +    prstatus.regs.r13 = env->regs[13];
> +    prstatus.regs.r12 = env->regs[12];
> +    prstatus.regs.r11 = env->regs[11];
> +    prstatus.regs.r10 = env->regs[10];
> +    prstatus.regs.r9  = env->regs[9];
> +    prstatus.regs.r8  = env->regs[8];
> +    prstatus.regs.rbp = env->regs[R_EBP];
> +    prstatus.regs.rsp = env->regs[R_ESP];
> +    prstatus.regs.rdi = env->regs[R_EDI];
> +    prstatus.regs.rsi = env->regs[R_ESI];
> +    prstatus.regs.rdx = env->regs[R_EDX];
> +    prstatus.regs.rcx = env->regs[R_ECX];
> +    prstatus.regs.rbx = env->regs[R_EBX];
> +    prstatus.regs.rax = env->regs[R_EAX];
> +    prstatus.regs.rip = env->eip;
> +    prstatus.regs.eflags = env->eflags;
> +
> +    prstatus.regs.orig_rax = 0; /* FIXME */
> +    prstatus.regs.cs = env->segs[R_CS].selector;
> +    prstatus.regs.ss = env->segs[R_SS].selector;
> +    prstatus.regs.fs_base = env->segs[R_FS].base;
> +    prstatus.regs.gs_base = env->segs[R_GS].base;
> +    prstatus.regs.ds = env->segs[R_DS].selector;
> +    prstatus.regs.es = env->segs[R_ES].selector;
> +    prstatus.regs.fs = env->segs[R_FS].selector;
> +    prstatus.regs.gs = env->segs[R_GS].selector;
> +
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  #endif
>  
> @@ -148,35 +123,12 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
>                                  int id, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf64_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, id);
> -    descsz = sizeof(x86_elf_prstatus);
> -    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    note->n_namesz = cpu_to_le32(name_size);
> -    note->n_descsz = cpu_to_le32(descsz);
> -    note->n_type = cpu_to_le32(NT_PRSTATUS);
> -    buf = (char *)note;
> -    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
> @@ -202,35 +154,12 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
>                           int cpuid, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf32_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, cpuid);
> -    descsz = sizeof(x86_elf_prstatus);
> -    note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    note->n_namesz = cpu_to_le32(name_size);
> -    note->n_descsz = cpu_to_le32(descsz);
> -    note->n_type = cpu_to_le32(NT_PRSTATUS);
> -    buf = (char *)note;
> -    buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  /*
> @@ -317,69 +246,28 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
>      s->cr[4] = env->cr[4];
>  }
>  
> -static inline int cpu_write_qemu_note(write_core_dump_function f,
> +static inline int cpu_write_qemu_note(int class, write_core_dump_function f,
>                                        CPUArchState *env,
> -                                      void *opaque,
> -                                      int type)
> +                                      void *opaque)
>  {
>      QEMUCPUState state;
> -    Elf64_Nhdr *note64;
> -    Elf32_Nhdr *note32;
> -    void *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5, note_head_size;
> -    const char *name = "QEMU";
> -    int ret;
>  
>      qemu_get_cpustate(&state, env);
>  
> -    descsz = sizeof(state);
> -    if (type == 0) {
> -        note_head_size = sizeof(Elf32_Nhdr);
> -    } else {
> -        note_head_size = sizeof(Elf64_Nhdr);
> -    }
> -    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    if (type == 0) {
> -        note32 = note;
> -        note32->n_namesz = cpu_to_le32(name_size);
> -        note32->n_descsz = cpu_to_le32(descsz);
> -        note32->n_type = 0;
> -    } else {
> -        note64 = note;
> -        note64->n_namesz = cpu_to_le32(name_size);
> -        note64->n_descsz = cpu_to_le32(descsz);
> -        note64->n_type = 0;
> -    }
> -    buf = note;
> -    buf += ((note_head_size + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &state, sizeof(state));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 1);
> +    return cpu_write_qemu_note(ELFCLASS64, f, env, opaque);
>  }
>  
>  int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 0);
> +    return cpu_write_qemu_note(ELFCLASS32, f, env, opaque);
>  }
>  
>  int cpu_get_dump_info(ArchDumpInfo *info)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support
  2012-07-01  6:22     ` Rabin Vincent
@ 2012-07-04  2:48       ` Wen Congyang
  0 siblings, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2012-07-04  2:48 UTC (permalink / raw)
  To: Rabin Vincent; +Cc: Peter Maydell, qemu-devel, Andreas Färber

At 07/01/2012 02:22 PM, Rabin Vincent Wrote:
> On Thu, Jun 28, 2012 at 05:46:02PM +0100, Peter Maydell wrote:
>> On 20 June 2012 18:28, Rabin Vincent <rabin@rab.in> wrote:
>>> Add a minimal dump-guest-memory support for ARM.  The -p option is not
>>> supported and we don't add any QEMU-specific notes.
>>
>> So what does this patch give us? This commit message is pretty
>> short and I couldn't find a cover message for the patchset...
> 
> It makes the dump-guest-memory command work for arm-softmmu.  The
> resulting core dump can be analysed with a tool such as the crash
> utility.
> 
>>
>>> Signed-off-by: Rabin Vincent <rabin@rab.in>
>>> ---
>>>  configure                        |    4 +--
>>>  target-arm/Makefile.objs         |    2 +-
>>>  target-arm/arch_dump.c           |   59 ++++++++++++++++++++++++++++++++++++++
>>>  target-arm/arch_memory_mapping.c |   13 +++++++++
>>>  4 files changed, 75 insertions(+), 3 deletions(-)
>>>  create mode 100644 target-arm/arch_dump.c
>>>  create mode 100644 target-arm/arch_memory_mapping.c
>>>
>>> diff --git a/configure b/configure
>>> index b68c0ca..a20ad19 100755
>>> --- a/configure
>>> +++ b/configure
>>> @@ -3727,7 +3727,7 @@ case "$target_arch2" in
>>>     fi
>>>  esac
>>>  case "$target_arch2" in
>>> -  i386|x86_64)
>>> +  arm|i386|x86_64)
>>>     echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
>>>  esac
>>>  if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then
>>> @@ -3746,7 +3746,7 @@ if test "$target_softmmu" = "yes" ; then
>>>     echo "subdir-$target: subdir-libcacard" >> $config_host_mak
>>>   fi
>>>   case "$target_arch2" in
>>> -    i386|x86_64)
>>> +    arm|i386|x86_64)
>>>       echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
>>>   esac
>>>  fi
>>> diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
>>> index f447c4f..837b374 100644
>>> --- a/target-arm/Makefile.objs
>>> +++ b/target-arm/Makefile.objs
>>> @@ -1,5 +1,5 @@
>>>  obj-y += arm-semi.o
>>> -obj-$(CONFIG_SOFTMMU) += machine.o
>>> +obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
>>>  obj-y += translate.o op_helper.o helper.o cpu.o
>>>  obj-y += neon_helper.o iwmmxt_helper.o
>>>
>>> diff --git a/target-arm/arch_dump.c b/target-arm/arch_dump.c
>>> new file mode 100644
>>> index 0000000..47a7e40
>>> --- /dev/null
>>> +++ b/target-arm/arch_dump.c
>>> @@ -0,0 +1,59 @@
>>> +#include "cpu.h"
>>> +#include "cpu-all.h"
>>> +#include "dump.h"
>>> +#include "elf.h"
>>> +
>>> +typedef struct {
>>> +    char pad1[24];
>>> +    uint32_t pid;
>>> +    char pad2[44];
>>> +    uint32_t regs[18];
>>> +    char pad3[4];
>>> +} arm_elf_prstatus;
>>
>> I'm guessing this is following some specification's structure layout;
>> what specification?
> 
> struct elf_prstatus from the Linux kernel's include/linux/elfcore.h.
> 
>>
>>> +
>>> +int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
>>> +                         int cpuid, void *opaque)
>>
>> Should these APIs really be taking a CPUArchState* rather rather than
>> an ARMCPU* ? (Andreas?)
> 
> No idea.  Cc'ing Wen, who added the APIs.

These API is introduced by me. This API is for all targets, so I use
CPUArchState rather than XXXCPUState here.

> 
>>
>>> +{
>>> +    return -1;
>>> +}
>>> +
>>> +int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
>>> +                         int cpuid, void *opaque)
>>> +{
>>> +    arm_elf_prstatus prstatus;
>>> +
>>> +    memset(&prstatus, 0, sizeof(prstatus));
>>> +    memcpy(&(prstatus.regs), env->regs, sizeof(env->regs));
>>
>> This looks a bit odd -- env->regs[] is a 16 word array but
>> prstatus.regs is 18 words. What are the last two words for?
> 
> CPSR and orig_r0.  orig_r0 is not useful, but I think we can save the
> CPSR in there.
> 
>>
>>> +    prstatus.pid = cpuid;
>>> +
>>> +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
>>> +                               &prstatus, sizeof(prstatus),
>>> +                               f, opaque);
>>> +}
>>> +
>>> +int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
>>> +                             void *opaque)
>>> +{
>>> +    return -1;
>>> +}
>>> +
>>> +int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>>> +                             void *opaque)
>>> +{
>>> +    return 0;
>>> +}
>>> +
>>> +int cpu_get_dump_info(ArchDumpInfo *info)
>>> +{
>>> +    info->d_machine = EM_ARM;
>>> +    info->d_endian = ELFDATA2LSB;
>>
>> ...even for big endian ARM?
> 
> I'll use TARGET_WORDS_BIGENDIAN to check.
> 
> Though it appears we don't have a armbe-softmmu?
> 
>>
>>> +    info->d_class = ELFCLASS32;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>>> +{
>>> +    return nr_cpus * dump_get_note_size(ELFCLASS32, "CORE",
>>> +                                        sizeof(arm_elf_prstatus));
>>> +}
>>> diff --git a/target-arm/arch_memory_mapping.c b/target-arm/arch_memory_mapping.c
>>> new file mode 100644
>>> index 0000000..eeaaf09
>>> --- /dev/null
>>> +++ b/target-arm/arch_memory_mapping.c
>>> @@ -0,0 +1,13 @@
>>> +#include "cpu.h"
>>> +#include "cpu-all.h"
>>> +#include "memory_mapping.h"
>>> +
>>> +bool cpu_paging_enabled(CPUArchState *env)
>>> +{
>>> +    return 0;
>>> +}
>>> +
>>> +int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
>>> +{
>>> +    return -1;
>>> +}
>>
>> Why do we need these null implementations and why do they
>> work better than the default ones in memory_mapping-stub.c ?
> 
> The implementations are to make the dump-guest-memory command build.  A
> full implementation would add support for the "-p" option which afaics
> is supposed to walk the page tables and dump only the pages which are
> mapped instead of the complete RAM.  I personally have no need for this
> option, so they are only null implementations which result in an error
> if this option is used.

If you want an error when this option is used, cpu_paging_enabeld should
return true, not false.

Thanks
Wen Congyang

> 
> The current config code keeps memory-mapping.c and memory-mapping-stub.c
> exclusive.  I think we should be able to make some changes there to
> allow us to use memory-mapping-stub.c instead of this
> arch_memory_mapping.c.
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support
       [not found]     ` <4FEDA2C0.7040405@suse.de>
@ 2012-07-04  2:57       ` Wen Congyang
  0 siblings, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2012-07-04  2:57 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Rabin Vincent, Peter Maydell, qemu-devel

At 06/29/2012 08:42 PM, Andreas Färber Wrote:
> Am 28.06.2012 18:46, schrieb Peter Maydell:
>> On 20 June 2012 18:28, Rabin Vincent <rabin@rab.in> wrote:
>>> Add a minimal dump-guest-memory support for ARM.  The -p option is not
>>> supported and we don't add any QEMU-specific notes.
>>
>> So what does this patch give us? This commit message is pretty
>> short and I couldn't find a cover message for the patchset...
>>
>>> Signed-off-by: Rabin Vincent <rabin@rab.in>
>>> ---
>>>  configure                        |    4 +--
>>>  target-arm/Makefile.objs         |    2 +-
>>>  target-arm/arch_dump.c           |   59 ++++++++++++++++++++++++++++++++++++++
>>>  target-arm/arch_memory_mapping.c |   13 +++++++++
>>>  4 files changed, 75 insertions(+), 3 deletions(-)
>>>  create mode 100644 target-arm/arch_dump.c
>>>  create mode 100644 target-arm/arch_memory_mapping.c
>>>
>>> diff --git a/configure b/configure
>>> index b68c0ca..a20ad19 100755
>>> --- a/configure
>>> +++ b/configure
>>> @@ -3727,7 +3727,7 @@ case "$target_arch2" in
>>>     fi
>>>  esac
>>>  case "$target_arch2" in
>>> -  i386|x86_64)
>>> +  arm|i386|x86_64)
>>>     echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
>>>  esac
>>>  if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then
>>> @@ -3746,7 +3746,7 @@ if test "$target_softmmu" = "yes" ; then
>>>     echo "subdir-$target: subdir-libcacard" >> $config_host_mak
>>>   fi
>>>   case "$target_arch2" in
>>> -    i386|x86_64)
>>> +    arm|i386|x86_64)
>>>       echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
>>>   esac
>>>  fi
>>> diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
>>> index f447c4f..837b374 100644
>>> --- a/target-arm/Makefile.objs
>>> +++ b/target-arm/Makefile.objs
>>> @@ -1,5 +1,5 @@
>>>  obj-y += arm-semi.o
>>> -obj-$(CONFIG_SOFTMMU) += machine.o
>>> +obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
>>>  obj-y += translate.o op_helper.o helper.o cpu.o
>>>  obj-y += neon_helper.o iwmmxt_helper.o
>>>
>>> diff --git a/target-arm/arch_dump.c b/target-arm/arch_dump.c
>>> new file mode 100644
>>> index 0000000..47a7e40
>>> --- /dev/null
>>> +++ b/target-arm/arch_dump.c
>>> @@ -0,0 +1,59 @@
>>> +#include "cpu.h"
>>> +#include "cpu-all.h"
>>> +#include "dump.h"
>>> +#include "elf.h"
>>> +
>>> +typedef struct {
>>> +    char pad1[24];
>>> +    uint32_t pid;
>>> +    char pad2[44];
>>> +    uint32_t regs[18];
>>> +    char pad3[4];
>>> +} arm_elf_prstatus;
>>
>> I'm guessing this is following some specification's structure layout;
>> what specification?
>>
>>> +
>>> +int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
>>> +                         int cpuid, void *opaque)
>>
>> Should these APIs really be taking a CPUArchState* rather rather than
>> an ARMCPU* ? (Andreas?)
> 
> I'm missing some context here. This is a new API? Where is it being used?
> 
> If it applies to multiple architectures and has separate
> architecture-specific implementations then CPUState argument please. If
> it's an ARM-internal API then, yes, ARMCPU please. If it's using common
> CPU fields in common code then CPUArchState is still the most fitting today.

It applies to multiple architectures, and use arch-spec fileds(For example:
register's value). Which is better? CPUArchState or XXXCPUState?

> 
>>> +{
>>> +    return -1;
>>> +}
>>> +
>>> +int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
>>> +                         int cpuid, void *opaque)
>>> +{
>>> +    arm_elf_prstatus prstatus;
>>> +
>>> +    memset(&prstatus, 0, sizeof(prstatus));
>>> +    memcpy(&(prstatus.regs), env->regs, sizeof(env->regs));
>>
>> This looks a bit odd -- env->regs[] is a 16 word array but
>> prstatus.regs is 18 words. What are the last two words for?
>>
>>> +    prstatus.pid = cpuid;
>>> +
>>> +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
>>> +                               &prstatus, sizeof(prstatus),
>>> +                               f, opaque);
>>> +}
>>> +
>>> +int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
>>> +                             void *opaque)
>>> +{
>>> +    return -1;
>>> +}
>>> +
>>> +int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>>> +                             void *opaque)
>>> +{
>>> +    return 0;
>>> +}
>>> +
>>> +int cpu_get_dump_info(ArchDumpInfo *info)
>>> +{
>>> +    info->d_machine = EM_ARM;
>>> +    info->d_endian = ELFDATA2LSB;
>>
>> ...even for big endian ARM?
>>
>>> +    info->d_class = ELFCLASS32;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>>> +{
>>> +    return nr_cpus * dump_get_note_size(ELFCLASS32, "CORE",
>>> +                                        sizeof(arm_elf_prstatus));
>>> +}
>>> diff --git a/target-arm/arch_memory_mapping.c b/target-arm/arch_memory_mapping.c
>>> new file mode 100644
>>> index 0000000..eeaaf09
>>> --- /dev/null
>>> +++ b/target-arm/arch_memory_mapping.c
>>> @@ -0,0 +1,13 @@
>>> +#include "cpu.h"
>>> +#include "cpu-all.h"
>>> +#include "memory_mapping.h"
>>> +
>>> +bool cpu_paging_enabled(CPUArchState *env)
>>> +{
>>> +    return 0;
>>> +}
> 
> What is this supposed to be? I think this is calling for a CPUClass
> field that gets overridden in target-arm/cpu.c:arm_cpu_class_init()...

No, it is for the monitor command dump-guest-memory's option -p. If the
user specifies this option, we will write guest physicall address and
virtual address mapping in the core(PT_LOAD). If the guest runs in real
mode(not use paging), the physical address is equal to virtual address.
otherwise, we should walk page table to get this mapping. This API
can tell us whether the guest runs in real mode or not.

Thanks
Wen Congyang

> 
>>> +
>>> +int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
>>> +{
>>> +    return -1;
>>> +}
>>
>> Why do we need these null implementations and why do they
>> work better than the default ones in memory_mapping-stub.c ?
>>
>> (memory_mapping.h could use some documentation comments
>> describing the purpose and API of these functions IMHO.)
> 
> Generally I'm not happy about an API defining new global per-arch
> cpu_*() functions, that conflicts with the QOM CPUState efforts.
> 
> Rabin, please keep my in the loop.
> 
> Thanks,
> Andreas
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-07-04  2:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-20 17:28 [Qemu-devel] [PATCH 1/4] dump: create writable files Rabin Vincent
2012-06-20 17:28 ` [Qemu-devel] [PATCH 2/4] dump: extract out note helper Rabin Vincent
2012-07-04  2:21   ` Wen Congyang
2012-07-04  2:31   ` Wen Congyang
2012-06-20 17:28 ` [Qemu-devel] [PATCH 3/4] dump: extract out get note size function Rabin Vincent
2012-07-04  2:25   ` Wen Congyang
2012-06-20 17:28 ` [Qemu-devel] [PATCH 4/4] target-arm: add minimal dump-guest-memory support Rabin Vincent
     [not found]   ` <CAFEAcA_x1HKmzgdjbi1Xv90Kwn3fwL3U3+_hiaO0wkTiNFR4pA@mail.gmail.com>
2012-07-01  6:22     ` Rabin Vincent
2012-07-04  2:48       ` Wen Congyang
     [not found]     ` <4FEDA2C0.7040405@suse.de>
2012-07-04  2:57       ` Wen Congyang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.