diff mbox

Add PowerPC 32-bit guest memory dump support

Message ID B5737074-2342-45C9-A7A3-339599F8CB9B@gtri.gatech.edu
State New
Headers show

Commit Message

Michael Nawrocki Feb. 8, 2017, 8:39 p.m. UTC
This patch extends support for the `dump-guest-memory` command to the 32-bit PowerPC architecture. It relies on the assumption that a 64-bit guest will not dump a 32-bit core file (and vice versa); if this assumption is invalid, please let me know.

Signed-off-by: Mike Nawrocki <michael.nawrocki@gtri.gatech.edu>

---
 target/ppc/Makefile.objs    |   4 +-
 target/ppc/arch_dump.c      | 154 ++++++++++++++++++++++++--------------------
 target/ppc/cpu.h            |   2 +
 target/ppc/translate_init.c |   5 +-
 4 files changed, 91 insertions(+), 74 deletions(-)

-- 
2.8.2

Comments

David Gibson Feb. 10, 2017, 3:21 a.m. UTC | #1
On Wed, Feb 08, 2017 at 08:39:36PM +0000, Nawrocki, Michael wrote:

> This patch extends support for the `dump-guest-memory` command to
> the 32-bit PowerPC architecture. It relies on the assumption that a
> 64-bit guest will not dump a 32-bit core file (and vice versa); if
> this assumption is invalid, please let me know.

Erm..  I'm trying to work out exactly what you mean by that
assumption.

A TARGET_PPC64=y qemu supports 32-bit as well as 64-bit machine types,
so it could be running a 32-bit guest inside it.

So, arguably compile time switching between 32bit and 64-bit dumps
isn't quite correct; but then it's not any worse than what we have now
which is a compile time switch between 64-bit dumps and nothing at
all.

I think this change should be ok, but I'm no ELF or dump expert.

> Signed-off-by: Mike Nawrocki <michael.nawrocki@gtri.gatech.edu>
> ---
>  target/ppc/Makefile.objs    |   4 +-
>  target/ppc/arch_dump.c      | 154 ++++++++++++++++++++++++--------------------
>  target/ppc/cpu.h            |   2 +
>  target/ppc/translate_init.c |   5 +-
>  4 files changed, 91 insertions(+), 74 deletions(-)
> 
> diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
> index a8c7a30..f50ffac 100644
> --- a/target/ppc/Makefile.objs
> +++ b/target/ppc/Makefile.objs
> @@ -1,8 +1,8 @@
>  obj-y += cpu-models.o
>  obj-y += translate.o
>  ifeq ($(CONFIG_SOFTMMU),y)
> -obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
> -obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o compat.o
> +obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o
> +obj-$(TARGET_PPC64) += mmu-hash64.o compat.o
>  endif
>  obj-$(CONFIG_KVM) += kvm.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 40282a1..28d9cc7 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -1,5 +1,5 @@
>  /*
> - * writing ELF notes for ppc64 arch
> + * writing ELF notes for ppc{64,} arch
>   *
>   *
>   * Copyright IBM, Corp. 2013
> @@ -19,36 +19,48 @@
>  #include "sysemu/dump.h"
>  #include "sysemu/kvm.h"
>  
> -struct PPC64UserRegStruct {
> -    uint64_t gpr[32];
> -    uint64_t nip;
> -    uint64_t msr;
> -    uint64_t orig_gpr3;
> -    uint64_t ctr;
> -    uint64_t link;
> -    uint64_t xer;
> -    uint64_t ccr;
> -    uint64_t softe;
> -    uint64_t trap;
> -    uint64_t dar;
> -    uint64_t dsisr;
> -    uint64_t result;
> +#ifdef TARGET_PPC64
> +#define ELFCLASS ELFCLASS64
> +#define cpu_to_dump_reg cpu_to_dump64
> +typedef uint64_t reg_t;
> +typedef Elf64_Nhdr Elf_Nhdr;
> +#else
> +#define ELFCLASS ELFCLASS32
> +#define cpu_to_dump_reg cpu_to_dump32
> +typedef uint32_t reg_t;
> +typedef Elf32_Nhdr Elf_Nhdr;
> +#endif /* TARGET_PPC64 */
> +
> +struct PPCUserRegStruct {
> +    reg_t gpr[32];
> +    reg_t nip;
> +    reg_t msr;
> +    reg_t orig_gpr3;
> +    reg_t ctr;
> +    reg_t link;
> +    reg_t xer;
> +    reg_t ccr;
> +    reg_t softe;
> +    reg_t trap;
> +    reg_t dar;
> +    reg_t dsisr;
> +    reg_t result;
>  } QEMU_PACKED;
>  
> -struct PPC64ElfPrstatus {
> +struct PPCElfPrstatus {
>      char pad1[112];
> -    struct PPC64UserRegStruct pr_reg;
> -    uint64_t pad2[4];
> +    struct PPCUserRegStruct pr_reg;
> +    reg_t pad2[4];
>  } QEMU_PACKED;
>  
>  
> -struct PPC64ElfFpregset {
> +struct PPCElfFpregset {
>      uint64_t fpr[32];
> -    uint64_t fpscr;
> +    reg_t fpscr;
>  }  QEMU_PACKED;
>  
>  
> -struct PPC64ElfVmxregset {
> +struct PPCElfVmxregset {
>      ppc_avr_t avr[32];
>      ppc_avr_t vscr;
>      union {
> @@ -57,26 +69,26 @@ struct PPC64ElfVmxregset {
>      } vrsave;
>  }  QEMU_PACKED;
>  
> -struct PPC64ElfVsxregset {
> +struct PPCElfVsxregset {
>      uint64_t vsr[32];
>  }  QEMU_PACKED;
>  
> -struct PPC64ElfSperegset {
> +struct PPCElfSperegset {
>      uint32_t evr[32];
>      uint64_t spe_acc;
>      uint32_t spe_fscr;
>  }  QEMU_PACKED;
>  
>  typedef struct noteStruct {
> -    Elf64_Nhdr hdr;
> +    Elf_Nhdr hdr;
>      char name[5];
>      char pad3[3];
>      union {
> -        struct PPC64ElfPrstatus  prstatus;
> -        struct PPC64ElfFpregset  fpregset;
> -        struct PPC64ElfVmxregset vmxregset;
> -        struct PPC64ElfVsxregset vsxregset;
> -        struct PPC64ElfSperegset speregset;
> +        struct PPCElfPrstatus  prstatus;
> +        struct PPCElfFpregset  fpregset;
> +        struct PPCElfVmxregset vmxregset;
> +        struct PPCElfVsxregset vsxregset;
> +        struct PPCElfSperegset speregset;
>      } contents;
>  } QEMU_PACKED Note;
>  
> @@ -85,12 +97,12 @@ typedef struct NoteFuncArg {
>      DumpState *state;
>  } NoteFuncArg;
>  
> -static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    uint64_t cr;
> -    struct PPC64ElfPrstatus *prstatus;
> -    struct PPC64UserRegStruct *reg;
> +    reg_t cr;
> +    struct PPCElfPrstatus *prstatus;
> +    struct PPCUserRegStruct *reg;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -101,25 +113,25 @@ static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>      reg = &prstatus->pr_reg;
>  
>      for (i = 0; i < 32; i++) {
> -        reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);
> +        reg->gpr[i] = cpu_to_dump_reg(s, cpu->env.gpr[i]);
>      }
> -    reg->nip = cpu_to_dump64(s, cpu->env.nip);
> -    reg->msr = cpu_to_dump64(s, cpu->env.msr);
> -    reg->ctr = cpu_to_dump64(s, cpu->env.ctr);
> -    reg->link = cpu_to_dump64(s, cpu->env.lr);
> -    reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));
> +    reg->nip = cpu_to_dump_reg(s, cpu->env.nip);
> +    reg->msr = cpu_to_dump_reg(s, cpu->env.msr);
> +    reg->ctr = cpu_to_dump_reg(s, cpu->env.ctr);
> +    reg->link = cpu_to_dump_reg(s, cpu->env.lr);
> +    reg->xer = cpu_to_dump_reg(s, cpu_read_xer(&cpu->env));
>  
>      cr = 0;
>      for (i = 0; i < 8; i++) {
>          cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));
>      }
> -    reg->ccr = cpu_to_dump64(s, cr);
> +    reg->ccr = cpu_to_dump_reg(s, cr);
>  }
>  
> -static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfFpregset  *fpregset;
> +    struct PPCElfFpregset  *fpregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -131,13 +143,13 @@ static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>      for (i = 0; i < 32; i++) {
>          fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
>      }
> -    fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);
> +    fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
>  }
>  
> -static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVmxregset *vmxregset;
> +    struct PPCElfVmxregset *vmxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -164,10 +176,11 @@ static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>      }
>      vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
>  }
> -static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVsxregset *vsxregset;
> +    struct PPCElfVsxregset *vsxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -179,9 +192,10 @@ static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>          vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
>      }
>  }
> -static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
> -    struct PPC64ElfSperegset *speregset;
> +    struct PPCElfSperegset *speregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -197,11 +211,11 @@ static const struct NoteFuncDescStruct {
>      int contents_size;
>      void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
>  } note_func[] = {
> -    {sizeof(((Note *)0)->contents.prstatus),  ppc64_write_elf64_prstatus},
> -    {sizeof(((Note *)0)->contents.fpregset),  ppc64_write_elf64_fpregset},
> -    {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},
> -    {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},
> -    {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},
> +    {sizeof(((Note *)0)->contents.prstatus),  ppc_write_elf_prstatus},
> +    {sizeof(((Note *)0)->contents.fpregset),  ppc_write_elf_fpregset},
> +    {sizeof(((Note *)0)->contents.vmxregset), ppc_write_elf_vmxregset},
> +    {sizeof(((Note *)0)->contents.vsxregset), ppc_write_elf_vsxregset},
> +    {sizeof(((Note *)0)->contents.speregset), ppc_write_elf_speregset},
>      { 0, NULL}
>  };
>  
> @@ -213,8 +227,9 @@ int cpu_get_dump_info(ArchDumpInfo *info,
>      PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
>      PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>  
> -    info->d_machine = EM_PPC64;
> -    info->d_class = ELFCLASS64;
> +    info->d_machine = PPC_ELF_MACHINE;
> +    info->d_class = ELFCLASS;
> +
>      if ((*pcc->interrupts_big_endian)(cpu)) {
>          info->d_endian = ELFDATA2MSB;
>      } else {
> @@ -236,25 +251,19 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>      int note_head_size;
>      const NoteFuncDesc *nf;
>  
> -    if (class != ELFCLASS64) {
> -        return -1;
> -    }
> -    assert(machine == EM_PPC64);
> -
> -    note_head_size = sizeof(Elf64_Nhdr);
> -
> +    note_head_size = sizeof(Elf_Nhdr);
>      for (nf = note_func; nf->note_contents_func; nf++) {
>          elf_note_size = elf_note_size + note_head_size + name_size +
> -                        nf->contents_size;
> +            nf->contents_size;
>      }
>  
>      return (elf_note_size) * nr_cpus;
>  }
>  
> -static int ppc64_write_all_elf64_notes(const char *note_name,
> -                                       WriteCoreDumpFunction f,
> -                                       PowerPCCPU *cpu, int id,
> -                                       void *opaque)
> +static int ppc_write_all_elf_notes(const char *note_name,
> +                                   WriteCoreDumpFunction f,
> +                                   PowerPCCPU *cpu, int id,
> +                                   void *opaque)
>  {
>      NoteFuncArg arg = { .state = opaque };
>      int ret = -1;
> @@ -282,5 +291,12 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> -    return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
> +}
> +
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
>  }
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index bc2a2ce..61efd7b 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1225,6 +1225,8 @@ int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque);
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque);
>  #ifndef CONFIG_USER_ONLY
>  void ppc_cpu_do_system_reset(CPUState *cs);
>  extern const struct VMStateDescription vmstate_ppc_cpu;
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 76f79fa..ebb3d8a 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -10478,11 +10478,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>  #else
>      cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_ppc_cpu;
> -#if defined(TARGET_PPC64)
> -    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> -#endif
>  #endif
>      cc->cpu_exec_enter = ppc_cpu_exec_enter;
> +    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> +    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
>  
>      cc->gdb_num_core_regs = 71;
>
Philippe Mathieu-Daudé Feb. 14, 2017, 11:18 p.m. UTC | #2
Hi Mike,

I failed to apply your patch on master:

error: patch failed: target/ppc/Makefile.objs:1
error: target/ppc/Makefile.objs: patch does not apply
error: patch failed: target/ppc/arch_dump.c:1
error: target/ppc/arch_dump.c: patch does not apply
error: patch failed: target/ppc/cpu.h:1225
error: target/ppc/cpu.h: patch does not apply
error: patch failed: target/ppc/translate_init.c:10478
error: target/ppc/translate_init.c: patch does not apply
Patch failed at 0001 Add PowerPC 32-bit guest memory dump support

Can you rebase/fix?

Thanks

On 02/08/2017 05:39 PM, Nawrocki, Michael wrote:
> This patch extends support for the `dump-guest-memory` command to the 32-bit PowerPC architecture. It relies on the assumption that a 64-bit guest will not dump a 32-bit core file (and vice versa); if this assumption is invalid, please let me know.
>
> Signed-off-by: Mike Nawrocki <michael.nawrocki@gtri.gatech.edu>
> ---
>  target/ppc/Makefile.objs    |   4 +-
>  target/ppc/arch_dump.c      | 154 ++++++++++++++++++++++++--------------------
>  target/ppc/cpu.h            |   2 +
>  target/ppc/translate_init.c |   5 +-
>  4 files changed, 91 insertions(+), 74 deletions(-)
>
> diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
> index a8c7a30..f50ffac 100644
> --- a/target/ppc/Makefile.objs
> +++ b/target/ppc/Makefile.objs
> @@ -1,8 +1,8 @@
>  obj-y += cpu-models.o
>  obj-y += translate.o
>  ifeq ($(CONFIG_SOFTMMU),y)
> -obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
> -obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o compat.o
> +obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o
> +obj-$(TARGET_PPC64) += mmu-hash64.o compat.o
>  endif
>  obj-$(CONFIG_KVM) += kvm.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 40282a1..28d9cc7 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -1,5 +1,5 @@
>  /*
> - * writing ELF notes for ppc64 arch
> + * writing ELF notes for ppc{64,} arch
>   *
>   *
>   * Copyright IBM, Corp. 2013
> @@ -19,36 +19,48 @@
>  #include "sysemu/dump.h"
>  #include "sysemu/kvm.h"
>
> -struct PPC64UserRegStruct {
> -    uint64_t gpr[32];
> -    uint64_t nip;
> -    uint64_t msr;
> -    uint64_t orig_gpr3;
> -    uint64_t ctr;
> -    uint64_t link;
> -    uint64_t xer;
> -    uint64_t ccr;
> -    uint64_t softe;
> -    uint64_t trap;
> -    uint64_t dar;
> -    uint64_t dsisr;
> -    uint64_t result;
> +#ifdef TARGET_PPC64
> +#define ELFCLASS ELFCLASS64
> +#define cpu_to_dump_reg cpu_to_dump64
> +typedef uint64_t reg_t;
> +typedef Elf64_Nhdr Elf_Nhdr;
> +#else
> +#define ELFCLASS ELFCLASS32
> +#define cpu_to_dump_reg cpu_to_dump32
> +typedef uint32_t reg_t;
> +typedef Elf32_Nhdr Elf_Nhdr;
> +#endif /* TARGET_PPC64 */
> +
> +struct PPCUserRegStruct {
> +    reg_t gpr[32];
> +    reg_t nip;
> +    reg_t msr;
> +    reg_t orig_gpr3;
> +    reg_t ctr;
> +    reg_t link;
> +    reg_t xer;
> +    reg_t ccr;
> +    reg_t softe;
> +    reg_t trap;
> +    reg_t dar;
> +    reg_t dsisr;
> +    reg_t result;
>  } QEMU_PACKED;
>
> -struct PPC64ElfPrstatus {
> +struct PPCElfPrstatus {
>      char pad1[112];
> -    struct PPC64UserRegStruct pr_reg;
> -    uint64_t pad2[4];
> +    struct PPCUserRegStruct pr_reg;
> +    reg_t pad2[4];
>  } QEMU_PACKED;
>
>
> -struct PPC64ElfFpregset {
> +struct PPCElfFpregset {
>      uint64_t fpr[32];
> -    uint64_t fpscr;
> +    reg_t fpscr;
>  }  QEMU_PACKED;
>
>
> -struct PPC64ElfVmxregset {
> +struct PPCElfVmxregset {
>      ppc_avr_t avr[32];
>      ppc_avr_t vscr;
>      union {
> @@ -57,26 +69,26 @@ struct PPC64ElfVmxregset {
>      } vrsave;
>  }  QEMU_PACKED;
>
> -struct PPC64ElfVsxregset {
> +struct PPCElfVsxregset {
>      uint64_t vsr[32];
>  }  QEMU_PACKED;
>
> -struct PPC64ElfSperegset {
> +struct PPCElfSperegset {
>      uint32_t evr[32];
>      uint64_t spe_acc;
>      uint32_t spe_fscr;
>  }  QEMU_PACKED;
>
>  typedef struct noteStruct {
> -    Elf64_Nhdr hdr;
> +    Elf_Nhdr hdr;
>      char name[5];
>      char pad3[3];
>      union {
> -        struct PPC64ElfPrstatus  prstatus;
> -        struct PPC64ElfFpregset  fpregset;
> -        struct PPC64ElfVmxregset vmxregset;
> -        struct PPC64ElfVsxregset vsxregset;
> -        struct PPC64ElfSperegset speregset;
> +        struct PPCElfPrstatus  prstatus;
> +        struct PPCElfFpregset  fpregset;
> +        struct PPCElfVmxregset vmxregset;
> +        struct PPCElfVsxregset vsxregset;
> +        struct PPCElfSperegset speregset;
>      } contents;
>  } QEMU_PACKED Note;
>
> @@ -85,12 +97,12 @@ typedef struct NoteFuncArg {
>      DumpState *state;
>  } NoteFuncArg;
>
> -static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    uint64_t cr;
> -    struct PPC64ElfPrstatus *prstatus;
> -    struct PPC64UserRegStruct *reg;
> +    reg_t cr;
> +    struct PPCElfPrstatus *prstatus;
> +    struct PPCUserRegStruct *reg;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>
> @@ -101,25 +113,25 @@ static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>      reg = &prstatus->pr_reg;
>
>      for (i = 0; i < 32; i++) {
> -        reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);
> +        reg->gpr[i] = cpu_to_dump_reg(s, cpu->env.gpr[i]);
>      }
> -    reg->nip = cpu_to_dump64(s, cpu->env.nip);
> -    reg->msr = cpu_to_dump64(s, cpu->env.msr);
> -    reg->ctr = cpu_to_dump64(s, cpu->env.ctr);
> -    reg->link = cpu_to_dump64(s, cpu->env.lr);
> -    reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));
> +    reg->nip = cpu_to_dump_reg(s, cpu->env.nip);
> +    reg->msr = cpu_to_dump_reg(s, cpu->env.msr);
> +    reg->ctr = cpu_to_dump_reg(s, cpu->env.ctr);
> +    reg->link = cpu_to_dump_reg(s, cpu->env.lr);
> +    reg->xer = cpu_to_dump_reg(s, cpu_read_xer(&cpu->env));
>
>      cr = 0;
>      for (i = 0; i < 8; i++) {
>          cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));
>      }
> -    reg->ccr = cpu_to_dump64(s, cr);
> +    reg->ccr = cpu_to_dump_reg(s, cr);
>  }
>
> -static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfFpregset  *fpregset;
> +    struct PPCElfFpregset  *fpregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>
> @@ -131,13 +143,13 @@ static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>      for (i = 0; i < 32; i++) {
>          fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
>      }
> -    fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);
> +    fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
>  }
>
> -static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVmxregset *vmxregset;
> +    struct PPCElfVmxregset *vmxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>
> @@ -164,10 +176,11 @@ static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>      }
>      vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
>  }
> -static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVsxregset *vsxregset;
> +    struct PPCElfVsxregset *vsxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>
> @@ -179,9 +192,10 @@ static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>          vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
>      }
>  }
> -static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
> -    struct PPC64ElfSperegset *speregset;
> +    struct PPCElfSperegset *speregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>
> @@ -197,11 +211,11 @@ static const struct NoteFuncDescStruct {
>      int contents_size;
>      void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
>  } note_func[] = {
> -    {sizeof(((Note *)0)->contents.prstatus),  ppc64_write_elf64_prstatus},
> -    {sizeof(((Note *)0)->contents.fpregset),  ppc64_write_elf64_fpregset},
> -    {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},
> -    {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},
> -    {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},
> +    {sizeof(((Note *)0)->contents.prstatus),  ppc_write_elf_prstatus},
> +    {sizeof(((Note *)0)->contents.fpregset),  ppc_write_elf_fpregset},
> +    {sizeof(((Note *)0)->contents.vmxregset), ppc_write_elf_vmxregset},
> +    {sizeof(((Note *)0)->contents.vsxregset), ppc_write_elf_vsxregset},
> +    {sizeof(((Note *)0)->contents.speregset), ppc_write_elf_speregset},
>      { 0, NULL}
>  };
>
> @@ -213,8 +227,9 @@ int cpu_get_dump_info(ArchDumpInfo *info,
>      PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
>      PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>
> -    info->d_machine = EM_PPC64;
> -    info->d_class = ELFCLASS64;
> +    info->d_machine = PPC_ELF_MACHINE;
> +    info->d_class = ELFCLASS;
> +
>      if ((*pcc->interrupts_big_endian)(cpu)) {
>          info->d_endian = ELFDATA2MSB;
>      } else {
> @@ -236,25 +251,19 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>      int note_head_size;
>      const NoteFuncDesc *nf;
>
> -    if (class != ELFCLASS64) {
> -        return -1;
> -    }
> -    assert(machine == EM_PPC64);
> -
> -    note_head_size = sizeof(Elf64_Nhdr);
> -
> +    note_head_size = sizeof(Elf_Nhdr);
>      for (nf = note_func; nf->note_contents_func; nf++) {
>          elf_note_size = elf_note_size + note_head_size + name_size +
> -                        nf->contents_size;
> +            nf->contents_size;
>      }
>
>      return (elf_note_size) * nr_cpus;
>  }
>
> -static int ppc64_write_all_elf64_notes(const char *note_name,
> -                                       WriteCoreDumpFunction f,
> -                                       PowerPCCPU *cpu, int id,
> -                                       void *opaque)
> +static int ppc_write_all_elf_notes(const char *note_name,
> +                                   WriteCoreDumpFunction f,
> +                                   PowerPCCPU *cpu, int id,
> +                                   void *opaque)
>  {
>      NoteFuncArg arg = { .state = opaque };
>      int ret = -1;
> @@ -282,5 +291,12 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> -    return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
> +}
> +
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
>  }
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index bc2a2ce..61efd7b 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1225,6 +1225,8 @@ int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque);
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque);
>  #ifndef CONFIG_USER_ONLY
>  void ppc_cpu_do_system_reset(CPUState *cs);
>  extern const struct VMStateDescription vmstate_ppc_cpu;
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 76f79fa..ebb3d8a 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -10478,11 +10478,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>  #else
>      cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_ppc_cpu;
> -#if defined(TARGET_PPC64)
> -    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> -#endif
>  #endif
>      cc->cpu_exec_enter = ppc_cpu_exec_enter;
> +    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> +    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
>
>      cc->gdb_num_core_regs = 71;
>
>
Michael Nawrocki Feb. 15, 2017, 3:17 a.m. UTC | #3
Hi Philippe,

I rebased on the latest master, but the only difference between that patch and the emailed patch was the commit hash. I’m using master at git://git.qemu.org/qemu.git (latest commit 5dae13c). It seems to cleanly apply on my end… is there a different repo I should be working against, or am I missing something else?

Thanks

On 2/14/17, 18:18, "Philippe Mathieu-Daudé" <philippe.mathieu.daude@gmail.com on behalf of f4bug@amsat.org> wrote:

    Hi Mike,
    
    I failed to apply your patch on master:
    
    error: patch failed: target/ppc/Makefile.objs:1
    error: target/ppc/Makefile.objs: patch does not apply
    error: patch failed: target/ppc/arch_dump.c:1
    error: target/ppc/arch_dump.c: patch does not apply
    error: patch failed: target/ppc/cpu.h:1225
    error: target/ppc/cpu.h: patch does not apply
    error: patch failed: target/ppc/translate_init.c:10478
    error: target/ppc/translate_init.c: patch does not apply
    Patch failed at 0001 Add PowerPC 32-bit guest memory dump support
    
    Can you rebase/fix?
    
    Thanks
    
    On 02/08/2017 05:39 PM, Nawrocki, Michael wrote:
    > This patch extends support for the `dump-guest-memory` command to the 32-bit PowerPC architecture. It relies on the assumption that a 64-bit guest will not dump a 32-bit core file (and vice versa); if this assumption is invalid, please let me know.

    >

    > Signed-off-by: Mike Nawrocki <michael.nawrocki@gtri.gatech.edu>

    > ---

    >  target/ppc/Makefile.objs    |   4 +-

    >  target/ppc/arch_dump.c      | 154 ++++++++++++++++++++++++--------------------

    >  target/ppc/cpu.h            |   2 +

    >  target/ppc/translate_init.c |   5 +-

    >  4 files changed, 91 insertions(+), 74 deletions(-)

    >

    > diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs

    > index a8c7a30..f50ffac 100644

    > --- a/target/ppc/Makefile.objs

    > +++ b/target/ppc/Makefile.objs

    > @@ -1,8 +1,8 @@

    >  obj-y += cpu-models.o

    >  obj-y += translate.o

    >  ifeq ($(CONFIG_SOFTMMU),y)

    > -obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o

    > -obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o compat.o

    > +obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o

    > +obj-$(TARGET_PPC64) += mmu-hash64.o compat.o

    >  endif

    >  obj-$(CONFIG_KVM) += kvm.o

    >  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o

    > diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c

    > index 40282a1..28d9cc7 100644

    > --- a/target/ppc/arch_dump.c

    > +++ b/target/ppc/arch_dump.c

    > @@ -1,5 +1,5 @@

    >  /*

    > - * writing ELF notes for ppc64 arch

    > + * writing ELF notes for ppc{64,} arch

    >   *

    >   *

    >   * Copyright IBM, Corp. 2013

    > @@ -19,36 +19,48 @@

    >  #include "sysemu/dump.h"

    >  #include "sysemu/kvm.h"

    >

    > -struct PPC64UserRegStruct {

    > -    uint64_t gpr[32];

    > -    uint64_t nip;

    > -    uint64_t msr;

    > -    uint64_t orig_gpr3;

    > -    uint64_t ctr;

    > -    uint64_t link;

    > -    uint64_t xer;

    > -    uint64_t ccr;

    > -    uint64_t softe;

    > -    uint64_t trap;

    > -    uint64_t dar;

    > -    uint64_t dsisr;

    > -    uint64_t result;

    > +#ifdef TARGET_PPC64

    > +#define ELFCLASS ELFCLASS64

    > +#define cpu_to_dump_reg cpu_to_dump64

    > +typedef uint64_t reg_t;

    > +typedef Elf64_Nhdr Elf_Nhdr;

    > +#else

    > +#define ELFCLASS ELFCLASS32

    > +#define cpu_to_dump_reg cpu_to_dump32

    > +typedef uint32_t reg_t;

    > +typedef Elf32_Nhdr Elf_Nhdr;

    > +#endif /* TARGET_PPC64 */

    > +

    > +struct PPCUserRegStruct {

    > +    reg_t gpr[32];

    > +    reg_t nip;

    > +    reg_t msr;

    > +    reg_t orig_gpr3;

    > +    reg_t ctr;

    > +    reg_t link;

    > +    reg_t xer;

    > +    reg_t ccr;

    > +    reg_t softe;

    > +    reg_t trap;

    > +    reg_t dar;

    > +    reg_t dsisr;

    > +    reg_t result;

    >  } QEMU_PACKED;

    >

    > -struct PPC64ElfPrstatus {

    > +struct PPCElfPrstatus {

    >      char pad1[112];

    > -    struct PPC64UserRegStruct pr_reg;

    > -    uint64_t pad2[4];

    > +    struct PPCUserRegStruct pr_reg;

    > +    reg_t pad2[4];

    >  } QEMU_PACKED;

    >

    >

    > -struct PPC64ElfFpregset {

    > +struct PPCElfFpregset {

    >      uint64_t fpr[32];

    > -    uint64_t fpscr;

    > +    reg_t fpscr;

    >  }  QEMU_PACKED;

    >

    >

    > -struct PPC64ElfVmxregset {

    > +struct PPCElfVmxregset {

    >      ppc_avr_t avr[32];

    >      ppc_avr_t vscr;

    >      union {

    > @@ -57,26 +69,26 @@ struct PPC64ElfVmxregset {

    >      } vrsave;

    >  }  QEMU_PACKED;

    >

    > -struct PPC64ElfVsxregset {

    > +struct PPCElfVsxregset {

    >      uint64_t vsr[32];

    >  }  QEMU_PACKED;

    >

    > -struct PPC64ElfSperegset {

    > +struct PPCElfSperegset {

    >      uint32_t evr[32];

    >      uint64_t spe_acc;

    >      uint32_t spe_fscr;

    >  }  QEMU_PACKED;

    >

    >  typedef struct noteStruct {

    > -    Elf64_Nhdr hdr;

    > +    Elf_Nhdr hdr;

    >      char name[5];

    >      char pad3[3];

    >      union {

    > -        struct PPC64ElfPrstatus  prstatus;

    > -        struct PPC64ElfFpregset  fpregset;

    > -        struct PPC64ElfVmxregset vmxregset;

    > -        struct PPC64ElfVsxregset vsxregset;

    > -        struct PPC64ElfSperegset speregset;

    > +        struct PPCElfPrstatus  prstatus;

    > +        struct PPCElfFpregset  fpregset;

    > +        struct PPCElfVmxregset vmxregset;

    > +        struct PPCElfVsxregset vsxregset;

    > +        struct PPCElfSperegset speregset;

    >      } contents;

    >  } QEMU_PACKED Note;

    >

    > @@ -85,12 +97,12 @@ typedef struct NoteFuncArg {

    >      DumpState *state;

    >  } NoteFuncArg;

    >

    > -static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)

    > +static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)

    >  {

    >      int i;

    > -    uint64_t cr;

    > -    struct PPC64ElfPrstatus *prstatus;

    > -    struct PPC64UserRegStruct *reg;

    > +    reg_t cr;

    > +    struct PPCElfPrstatus *prstatus;

    > +    struct PPCUserRegStruct *reg;

    >      Note *note = &arg->note;

    >      DumpState *s = arg->state;

    >

    > @@ -101,25 +113,25 @@ static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)

    >      reg = &prstatus->pr_reg;

    >

    >      for (i = 0; i < 32; i++) {

    > -        reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);

    > +        reg->gpr[i] = cpu_to_dump_reg(s, cpu->env.gpr[i]);

    >      }

    > -    reg->nip = cpu_to_dump64(s, cpu->env.nip);

    > -    reg->msr = cpu_to_dump64(s, cpu->env.msr);

    > -    reg->ctr = cpu_to_dump64(s, cpu->env.ctr);

    > -    reg->link = cpu_to_dump64(s, cpu->env.lr);

    > -    reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));

    > +    reg->nip = cpu_to_dump_reg(s, cpu->env.nip);

    > +    reg->msr = cpu_to_dump_reg(s, cpu->env.msr);

    > +    reg->ctr = cpu_to_dump_reg(s, cpu->env.ctr);

    > +    reg->link = cpu_to_dump_reg(s, cpu->env.lr);

    > +    reg->xer = cpu_to_dump_reg(s, cpu_read_xer(&cpu->env));

    >

    >      cr = 0;

    >      for (i = 0; i < 8; i++) {

    >          cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));

    >      }

    > -    reg->ccr = cpu_to_dump64(s, cr);

    > +    reg->ccr = cpu_to_dump_reg(s, cr);

    >  }

    >

    > -static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    > +static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >  {

    >      int i;

    > -    struct PPC64ElfFpregset  *fpregset;

    > +    struct PPCElfFpregset  *fpregset;

    >      Note *note = &arg->note;

    >      DumpState *s = arg->state;

    >

    > @@ -131,13 +143,13 @@ static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >      for (i = 0; i < 32; i++) {

    >          fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);

    >      }

    > -    fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);

    > +    fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);

    >  }

    >

    > -static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    > +static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >  {

    >      int i;

    > -    struct PPC64ElfVmxregset *vmxregset;

    > +    struct PPCElfVmxregset *vmxregset;

    >      Note *note = &arg->note;

    >      DumpState *s = arg->state;

    >

    > @@ -164,10 +176,11 @@ static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >      }

    >      vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);

    >  }

    > -static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    > +

    > +static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >  {

    >      int i;

    > -    struct PPC64ElfVsxregset *vsxregset;

    > +    struct PPCElfVsxregset *vsxregset;

    >      Note *note = &arg->note;

    >      DumpState *s = arg->state;

    >

    > @@ -179,9 +192,10 @@ static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >          vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);

    >      }

    >  }

    > -static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    > +

    > +static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)

    >  {

    > -    struct PPC64ElfSperegset *speregset;

    > +    struct PPCElfSperegset *speregset;

    >      Note *note = &arg->note;

    >      DumpState *s = arg->state;

    >

    > @@ -197,11 +211,11 @@ static const struct NoteFuncDescStruct {

    >      int contents_size;

    >      void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);

    >  } note_func[] = {

    > -    {sizeof(((Note *)0)->contents.prstatus),  ppc64_write_elf64_prstatus},

    > -    {sizeof(((Note *)0)->contents.fpregset),  ppc64_write_elf64_fpregset},

    > -    {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},

    > -    {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},

    > -    {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},

    > +    {sizeof(((Note *)0)->contents.prstatus),  ppc_write_elf_prstatus},

    > +    {sizeof(((Note *)0)->contents.fpregset),  ppc_write_elf_fpregset},

    > +    {sizeof(((Note *)0)->contents.vmxregset), ppc_write_elf_vmxregset},

    > +    {sizeof(((Note *)0)->contents.vsxregset), ppc_write_elf_vsxregset},

    > +    {sizeof(((Note *)0)->contents.speregset), ppc_write_elf_speregset},

    >      { 0, NULL}

    >  };

    >

    > @@ -213,8 +227,9 @@ int cpu_get_dump_info(ArchDumpInfo *info,

    >      PowerPCCPU *cpu = POWERPC_CPU(first_cpu);

    >      PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);

    >

    > -    info->d_machine = EM_PPC64;

    > -    info->d_class = ELFCLASS64;

    > +    info->d_machine = PPC_ELF_MACHINE;

    > +    info->d_class = ELFCLASS;

    > +

    >      if ((*pcc->interrupts_big_endian)(cpu)) {

    >          info->d_endian = ELFDATA2MSB;

    >      } else {

    > @@ -236,25 +251,19 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)

    >      int note_head_size;

    >      const NoteFuncDesc *nf;

    >

    > -    if (class != ELFCLASS64) {

    > -        return -1;

    > -    }

    > -    assert(machine == EM_PPC64);

    > -

    > -    note_head_size = sizeof(Elf64_Nhdr);

    > -

    > +    note_head_size = sizeof(Elf_Nhdr);

    >      for (nf = note_func; nf->note_contents_func; nf++) {

    >          elf_note_size = elf_note_size + note_head_size + name_size +

    > -                        nf->contents_size;

    > +            nf->contents_size;

    >      }

    >

    >      return (elf_note_size) * nr_cpus;

    >  }

    >

    > -static int ppc64_write_all_elf64_notes(const char *note_name,

    > -                                       WriteCoreDumpFunction f,

    > -                                       PowerPCCPU *cpu, int id,

    > -                                       void *opaque)

    > +static int ppc_write_all_elf_notes(const char *note_name,

    > +                                   WriteCoreDumpFunction f,

    > +                                   PowerPCCPU *cpu, int id,

    > +                                   void *opaque)

    >  {

    >      NoteFuncArg arg = { .state = opaque };

    >      int ret = -1;

    > @@ -282,5 +291,12 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,

    >                                 int cpuid, void *opaque)

    >  {

    >      PowerPCCPU *cpu = POWERPC_CPU(cs);

    > -    return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);

    > +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);

    > +}

    > +

    > +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,

    > +                               int cpuid, void *opaque)

    > +{

    > +    PowerPCCPU *cpu = POWERPC_CPU(cs);

    > +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);

    >  }

    > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h

    > index bc2a2ce..61efd7b 100644

    > --- a/target/ppc/cpu.h

    > +++ b/target/ppc/cpu.h

    > @@ -1225,6 +1225,8 @@ int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);

    >  int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);

    >  int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,

    >                                 int cpuid, void *opaque);

    > +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,

    > +                               int cpuid, void *opaque);

    >  #ifndef CONFIG_USER_ONLY

    >  void ppc_cpu_do_system_reset(CPUState *cs);

    >  extern const struct VMStateDescription vmstate_ppc_cpu;

    > diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c

    > index 76f79fa..ebb3d8a 100644

    > --- a/target/ppc/translate_init.c

    > +++ b/target/ppc/translate_init.c

    > @@ -10478,11 +10478,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)

    >  #else

    >      cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;

    >      cc->vmsd = &vmstate_ppc_cpu;

    > -#if defined(TARGET_PPC64)

    > -    cc->write_elf64_note = ppc64_cpu_write_elf64_note;

    > -#endif

    >  #endif

    >      cc->cpu_exec_enter = ppc_cpu_exec_enter;

    > +    cc->write_elf64_note = ppc64_cpu_write_elf64_note;

    > +    cc->write_elf32_note = ppc32_cpu_write_elf32_note;

    >

    >      cc->gdb_num_core_regs = 71;

    >

    >
David Gibson Feb. 28, 2017, 12:47 a.m. UTC | #4
On Wed, Feb 08, 2017 at 08:39:36PM +0000, Nawrocki, Michael wrote:
> This patch extends support for the `dump-guest-memory` command to the 32-bit PowerPC architecture. It relies on the assumption that a 64-bit guest will not dump a 32-bit core file (and vice versa); if this assumption is invalid, please let me know.
> 
> Signed-off-by: Mike Nawrocki <michael.nawrocki@gtri.gatech.edu>

Sorry I've taken so long to review this.  I'm not really sure if this
is correct for all machine type combinations (particularly 32-bit
machines with a 64-bit compiled qemu), but fairly clearly it does
strictly more than the existing code.

Unfortunately, updates since you posted this means it no longer
applies, so you'll need to rebase.

When I tried applying, git am also had some complaints about trailing
whitespace.

> ---
>  target/ppc/Makefile.objs    |   4 +-
>  target/ppc/arch_dump.c      | 154 ++++++++++++++++++++++++--------------------
>  target/ppc/cpu.h            |   2 +
>  target/ppc/translate_init.c |   5 +-
>  4 files changed, 91 insertions(+), 74 deletions(-)
> 
> diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
> index a8c7a30..f50ffac 100644
> --- a/target/ppc/Makefile.objs
> +++ b/target/ppc/Makefile.objs
> @@ -1,8 +1,8 @@
>  obj-y += cpu-models.o
>  obj-y += translate.o
>  ifeq ($(CONFIG_SOFTMMU),y)
> -obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
> -obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o compat.o
> +obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o
> +obj-$(TARGET_PPC64) += mmu-hash64.o compat.o
>  endif
>  obj-$(CONFIG_KVM) += kvm.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 40282a1..28d9cc7 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -1,5 +1,5 @@
>  /*
> - * writing ELF notes for ppc64 arch
> + * writing ELF notes for ppc{64,} arch
>   *
>   *
>   * Copyright IBM, Corp. 2013
> @@ -19,36 +19,48 @@
>  #include "sysemu/dump.h"
>  #include "sysemu/kvm.h"
>  
> -struct PPC64UserRegStruct {
> -    uint64_t gpr[32];
> -    uint64_t nip;
> -    uint64_t msr;
> -    uint64_t orig_gpr3;
> -    uint64_t ctr;
> -    uint64_t link;
> -    uint64_t xer;
> -    uint64_t ccr;
> -    uint64_t softe;
> -    uint64_t trap;
> -    uint64_t dar;
> -    uint64_t dsisr;
> -    uint64_t result;
> +#ifdef TARGET_PPC64
> +#define ELFCLASS ELFCLASS64
> +#define cpu_to_dump_reg cpu_to_dump64
> +typedef uint64_t reg_t;
> +typedef Elf64_Nhdr Elf_Nhdr;
> +#else
> +#define ELFCLASS ELFCLASS32
> +#define cpu_to_dump_reg cpu_to_dump32
> +typedef uint32_t reg_t;
> +typedef Elf32_Nhdr Elf_Nhdr;
> +#endif /* TARGET_PPC64 */
> +
> +struct PPCUserRegStruct {
> +    reg_t gpr[32];
> +    reg_t nip;
> +    reg_t msr;
> +    reg_t orig_gpr3;
> +    reg_t ctr;
> +    reg_t link;
> +    reg_t xer;
> +    reg_t ccr;
> +    reg_t softe;
> +    reg_t trap;
> +    reg_t dar;
> +    reg_t dsisr;
> +    reg_t result;
>  } QEMU_PACKED;
>  
> -struct PPC64ElfPrstatus {
> +struct PPCElfPrstatus {
>      char pad1[112];
> -    struct PPC64UserRegStruct pr_reg;
> -    uint64_t pad2[4];
> +    struct PPCUserRegStruct pr_reg;
> +    reg_t pad2[4];
>  } QEMU_PACKED;
>  
>  
> -struct PPC64ElfFpregset {
> +struct PPCElfFpregset {
>      uint64_t fpr[32];
> -    uint64_t fpscr;
> +    reg_t fpscr;
>  }  QEMU_PACKED;
>  
>  
> -struct PPC64ElfVmxregset {
> +struct PPCElfVmxregset {
>      ppc_avr_t avr[32];
>      ppc_avr_t vscr;
>      union {
> @@ -57,26 +69,26 @@ struct PPC64ElfVmxregset {
>      } vrsave;
>  }  QEMU_PACKED;
>  
> -struct PPC64ElfVsxregset {
> +struct PPCElfVsxregset {
>      uint64_t vsr[32];
>  }  QEMU_PACKED;
>  
> -struct PPC64ElfSperegset {
> +struct PPCElfSperegset {
>      uint32_t evr[32];
>      uint64_t spe_acc;
>      uint32_t spe_fscr;
>  }  QEMU_PACKED;
>  
>  typedef struct noteStruct {
> -    Elf64_Nhdr hdr;
> +    Elf_Nhdr hdr;
>      char name[5];
>      char pad3[3];
>      union {
> -        struct PPC64ElfPrstatus  prstatus;
> -        struct PPC64ElfFpregset  fpregset;
> -        struct PPC64ElfVmxregset vmxregset;
> -        struct PPC64ElfVsxregset vsxregset;
> -        struct PPC64ElfSperegset speregset;
> +        struct PPCElfPrstatus  prstatus;
> +        struct PPCElfFpregset  fpregset;
> +        struct PPCElfVmxregset vmxregset;
> +        struct PPCElfVsxregset vsxregset;
> +        struct PPCElfSperegset speregset;
>      } contents;
>  } QEMU_PACKED Note;
>  
> @@ -85,12 +97,12 @@ typedef struct NoteFuncArg {
>      DumpState *state;
>  } NoteFuncArg;
>  
> -static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    uint64_t cr;
> -    struct PPC64ElfPrstatus *prstatus;
> -    struct PPC64UserRegStruct *reg;
> +    reg_t cr;
> +    struct PPCElfPrstatus *prstatus;
> +    struct PPCUserRegStruct *reg;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -101,25 +113,25 @@ static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>      reg = &prstatus->pr_reg;
>  
>      for (i = 0; i < 32; i++) {
> -        reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);
> +        reg->gpr[i] = cpu_to_dump_reg(s, cpu->env.gpr[i]);
>      }
> -    reg->nip = cpu_to_dump64(s, cpu->env.nip);
> -    reg->msr = cpu_to_dump64(s, cpu->env.msr);
> -    reg->ctr = cpu_to_dump64(s, cpu->env.ctr);
> -    reg->link = cpu_to_dump64(s, cpu->env.lr);
> -    reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));
> +    reg->nip = cpu_to_dump_reg(s, cpu->env.nip);
> +    reg->msr = cpu_to_dump_reg(s, cpu->env.msr);
> +    reg->ctr = cpu_to_dump_reg(s, cpu->env.ctr);
> +    reg->link = cpu_to_dump_reg(s, cpu->env.lr);
> +    reg->xer = cpu_to_dump_reg(s, cpu_read_xer(&cpu->env));
>  
>      cr = 0;
>      for (i = 0; i < 8; i++) {
>          cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));
>      }
> -    reg->ccr = cpu_to_dump64(s, cr);
> +    reg->ccr = cpu_to_dump_reg(s, cr);
>  }
>  
> -static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfFpregset  *fpregset;
> +    struct PPCElfFpregset  *fpregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -131,13 +143,13 @@ static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>      for (i = 0; i < 32; i++) {
>          fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
>      }
> -    fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);
> +    fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
>  }
>  
> -static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVmxregset *vmxregset;
> +    struct PPCElfVmxregset *vmxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -164,10 +176,11 @@ static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>      }
>      vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
>  }
> -static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVsxregset *vsxregset;
> +    struct PPCElfVsxregset *vsxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -179,9 +192,10 @@ static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>          vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
>      }
>  }
> -static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
> -    struct PPC64ElfSperegset *speregset;
> +    struct PPCElfSperegset *speregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -197,11 +211,11 @@ static const struct NoteFuncDescStruct {
>      int contents_size;
>      void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
>  } note_func[] = {
> -    {sizeof(((Note *)0)->contents.prstatus),  ppc64_write_elf64_prstatus},
> -    {sizeof(((Note *)0)->contents.fpregset),  ppc64_write_elf64_fpregset},
> -    {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},
> -    {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},
> -    {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},
> +    {sizeof(((Note *)0)->contents.prstatus),  ppc_write_elf_prstatus},
> +    {sizeof(((Note *)0)->contents.fpregset),  ppc_write_elf_fpregset},
> +    {sizeof(((Note *)0)->contents.vmxregset), ppc_write_elf_vmxregset},
> +    {sizeof(((Note *)0)->contents.vsxregset), ppc_write_elf_vsxregset},
> +    {sizeof(((Note *)0)->contents.speregset), ppc_write_elf_speregset},
>      { 0, NULL}
>  };
>  
> @@ -213,8 +227,9 @@ int cpu_get_dump_info(ArchDumpInfo *info,
>      PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
>      PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>  
> -    info->d_machine = EM_PPC64;
> -    info->d_class = ELFCLASS64;
> +    info->d_machine = PPC_ELF_MACHINE;
> +    info->d_class = ELFCLASS;
> +
>      if ((*pcc->interrupts_big_endian)(cpu)) {
>          info->d_endian = ELFDATA2MSB;
>      } else {
> @@ -236,25 +251,19 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
>      int note_head_size;
>      const NoteFuncDesc *nf;
>  
> -    if (class != ELFCLASS64) {
> -        return -1;
> -    }
> -    assert(machine == EM_PPC64);
> -
> -    note_head_size = sizeof(Elf64_Nhdr);
> -
> +    note_head_size = sizeof(Elf_Nhdr);
>      for (nf = note_func; nf->note_contents_func; nf++) {
>          elf_note_size = elf_note_size + note_head_size + name_size +
> -                        nf->contents_size;
> +            nf->contents_size;
>      }
>  
>      return (elf_note_size) * nr_cpus;
>  }
>  
> -static int ppc64_write_all_elf64_notes(const char *note_name,
> -                                       WriteCoreDumpFunction f,
> -                                       PowerPCCPU *cpu, int id,
> -                                       void *opaque)
> +static int ppc_write_all_elf_notes(const char *note_name,
> +                                   WriteCoreDumpFunction f,
> +                                   PowerPCCPU *cpu, int id,
> +                                   void *opaque)
>  {
>      NoteFuncArg arg = { .state = opaque };
>      int ret = -1;
> @@ -282,5 +291,12 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> -    return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
> +}
> +
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
>  }
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index bc2a2ce..61efd7b 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1225,6 +1225,8 @@ int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque);
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque);
>  #ifndef CONFIG_USER_ONLY
>  void ppc_cpu_do_system_reset(CPUState *cs);
>  extern const struct VMStateDescription vmstate_ppc_cpu;
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 76f79fa..ebb3d8a 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -10478,11 +10478,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
>  #else
>      cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_ppc_cpu;
> -#if defined(TARGET_PPC64)
> -    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> -#endif
>  #endif
>      cc->cpu_exec_enter = ppc_cpu_exec_enter;
> +    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> +    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
>  
>      cc->gdb_num_core_regs = 71;
>
diff mbox

Patch

diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
index a8c7a30..f50ffac 100644
--- a/target/ppc/Makefile.objs
+++ b/target/ppc/Makefile.objs
@@ -1,8 +1,8 @@ 
 obj-y += cpu-models.o
 obj-y += translate.o
 ifeq ($(CONFIG_SOFTMMU),y)
-obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
-obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o compat.o
+obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o
+obj-$(TARGET_PPC64) += mmu-hash64.o compat.o
 endif
 obj-$(CONFIG_KVM) += kvm.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index 40282a1..28d9cc7 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -1,5 +1,5 @@ 
 /*
- * writing ELF notes for ppc64 arch
+ * writing ELF notes for ppc{64,} arch
  *
  *
  * Copyright IBM, Corp. 2013
@@ -19,36 +19,48 @@ 
 #include "sysemu/dump.h"
 #include "sysemu/kvm.h"
 
-struct PPC64UserRegStruct {
-    uint64_t gpr[32];
-    uint64_t nip;
-    uint64_t msr;
-    uint64_t orig_gpr3;
-    uint64_t ctr;
-    uint64_t link;
-    uint64_t xer;
-    uint64_t ccr;
-    uint64_t softe;
-    uint64_t trap;
-    uint64_t dar;
-    uint64_t dsisr;
-    uint64_t result;
+#ifdef TARGET_PPC64
+#define ELFCLASS ELFCLASS64
+#define cpu_to_dump_reg cpu_to_dump64
+typedef uint64_t reg_t;
+typedef Elf64_Nhdr Elf_Nhdr;
+#else
+#define ELFCLASS ELFCLASS32
+#define cpu_to_dump_reg cpu_to_dump32
+typedef uint32_t reg_t;
+typedef Elf32_Nhdr Elf_Nhdr;
+#endif /* TARGET_PPC64 */
+
+struct PPCUserRegStruct {
+    reg_t gpr[32];
+    reg_t nip;
+    reg_t msr;
+    reg_t orig_gpr3;
+    reg_t ctr;
+    reg_t link;
+    reg_t xer;
+    reg_t ccr;
+    reg_t softe;
+    reg_t trap;
+    reg_t dar;
+    reg_t dsisr;
+    reg_t result;
 } QEMU_PACKED;
 
-struct PPC64ElfPrstatus {
+struct PPCElfPrstatus {
     char pad1[112];
-    struct PPC64UserRegStruct pr_reg;
-    uint64_t pad2[4];
+    struct PPCUserRegStruct pr_reg;
+    reg_t pad2[4];
 } QEMU_PACKED;
 
 
-struct PPC64ElfFpregset {
+struct PPCElfFpregset {
     uint64_t fpr[32];
-    uint64_t fpscr;
+    reg_t fpscr;
 }  QEMU_PACKED;
 
 
-struct PPC64ElfVmxregset {
+struct PPCElfVmxregset {
     ppc_avr_t avr[32];
     ppc_avr_t vscr;
     union {
@@ -57,26 +69,26 @@  struct PPC64ElfVmxregset {
     } vrsave;
 }  QEMU_PACKED;
 
-struct PPC64ElfVsxregset {
+struct PPCElfVsxregset {
     uint64_t vsr[32];
 }  QEMU_PACKED;
 
-struct PPC64ElfSperegset {
+struct PPCElfSperegset {
     uint32_t evr[32];
     uint64_t spe_acc;
     uint32_t spe_fscr;
 }  QEMU_PACKED;
 
 typedef struct noteStruct {
-    Elf64_Nhdr hdr;
+    Elf_Nhdr hdr;
     char name[5];
     char pad3[3];
     union {
-        struct PPC64ElfPrstatus  prstatus;
-        struct PPC64ElfFpregset  fpregset;
-        struct PPC64ElfVmxregset vmxregset;
-        struct PPC64ElfVsxregset vsxregset;
-        struct PPC64ElfSperegset speregset;
+        struct PPCElfPrstatus  prstatus;
+        struct PPCElfFpregset  fpregset;
+        struct PPCElfVmxregset vmxregset;
+        struct PPCElfVsxregset vsxregset;
+        struct PPCElfSperegset speregset;
     } contents;
 } QEMU_PACKED Note;
 
@@ -85,12 +97,12 @@  typedef struct NoteFuncArg {
     DumpState *state;
 } NoteFuncArg;
 
-static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
+static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
 {
     int i;
-    uint64_t cr;
-    struct PPC64ElfPrstatus *prstatus;
-    struct PPC64UserRegStruct *reg;
+    reg_t cr;
+    struct PPCElfPrstatus *prstatus;
+    struct PPCUserRegStruct *reg;
     Note *note = &arg->note;
     DumpState *s = arg->state;
 
@@ -101,25 +113,25 @@  static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
     reg = &prstatus->pr_reg;
 
     for (i = 0; i < 32; i++) {
-        reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);
+        reg->gpr[i] = cpu_to_dump_reg(s, cpu->env.gpr[i]);
     }
-    reg->nip = cpu_to_dump64(s, cpu->env.nip);
-    reg->msr = cpu_to_dump64(s, cpu->env.msr);
-    reg->ctr = cpu_to_dump64(s, cpu->env.ctr);
-    reg->link = cpu_to_dump64(s, cpu->env.lr);
-    reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));
+    reg->nip = cpu_to_dump_reg(s, cpu->env.nip);
+    reg->msr = cpu_to_dump_reg(s, cpu->env.msr);
+    reg->ctr = cpu_to_dump_reg(s, cpu->env.ctr);
+    reg->link = cpu_to_dump_reg(s, cpu->env.lr);
+    reg->xer = cpu_to_dump_reg(s, cpu_read_xer(&cpu->env));
 
     cr = 0;
     for (i = 0; i < 8; i++) {
         cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));
     }
-    reg->ccr = cpu_to_dump64(s, cr);
+    reg->ccr = cpu_to_dump_reg(s, cr);
 }
 
-static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
+static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
 {
     int i;
-    struct PPC64ElfFpregset  *fpregset;
+    struct PPCElfFpregset  *fpregset;
     Note *note = &arg->note;
     DumpState *s = arg->state;
 
@@ -131,13 +143,13 @@  static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
     for (i = 0; i < 32; i++) {
         fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
     }
-    fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);
+    fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
 }
 
-static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
+static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
 {
     int i;
-    struct PPC64ElfVmxregset *vmxregset;
+    struct PPCElfVmxregset *vmxregset;
     Note *note = &arg->note;
     DumpState *s = arg->state;
 
@@ -164,10 +176,11 @@  static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
     }
     vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
 }
-static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
+
+static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
 {
     int i;
-    struct PPC64ElfVsxregset *vsxregset;
+    struct PPCElfVsxregset *vsxregset;
     Note *note = &arg->note;
     DumpState *s = arg->state;
 
@@ -179,9 +192,10 @@  static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
         vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
     }
 }
-static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
+
+static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
 {
-    struct PPC64ElfSperegset *speregset;
+    struct PPCElfSperegset *speregset;
     Note *note = &arg->note;
     DumpState *s = arg->state;
 
@@ -197,11 +211,11 @@  static const struct NoteFuncDescStruct {
     int contents_size;
     void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
 } note_func[] = {
-    {sizeof(((Note *)0)->contents.prstatus),  ppc64_write_elf64_prstatus},
-    {sizeof(((Note *)0)->contents.fpregset),  ppc64_write_elf64_fpregset},
-    {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},
-    {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},
-    {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},
+    {sizeof(((Note *)0)->contents.prstatus),  ppc_write_elf_prstatus},
+    {sizeof(((Note *)0)->contents.fpregset),  ppc_write_elf_fpregset},
+    {sizeof(((Note *)0)->contents.vmxregset), ppc_write_elf_vmxregset},
+    {sizeof(((Note *)0)->contents.vsxregset), ppc_write_elf_vsxregset},
+    {sizeof(((Note *)0)->contents.speregset), ppc_write_elf_speregset},
     { 0, NULL}
 };
 
@@ -213,8 +227,9 @@  int cpu_get_dump_info(ArchDumpInfo *info,
     PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 
-    info->d_machine = EM_PPC64;
-    info->d_class = ELFCLASS64;
+    info->d_machine = PPC_ELF_MACHINE;
+    info->d_class = ELFCLASS;
+
     if ((*pcc->interrupts_big_endian)(cpu)) {
         info->d_endian = ELFDATA2MSB;
     } else {
@@ -236,25 +251,19 @@  ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
     int note_head_size;
     const NoteFuncDesc *nf;
 
-    if (class != ELFCLASS64) {
-        return -1;
-    }
-    assert(machine == EM_PPC64);
-
-    note_head_size = sizeof(Elf64_Nhdr);
-
+    note_head_size = sizeof(Elf_Nhdr);
     for (nf = note_func; nf->note_contents_func; nf++) {
         elf_note_size = elf_note_size + note_head_size + name_size +
-                        nf->contents_size;
+            nf->contents_size;
     }
 
     return (elf_note_size) * nr_cpus;
 }
 
-static int ppc64_write_all_elf64_notes(const char *note_name,
-                                       WriteCoreDumpFunction f,
-                                       PowerPCCPU *cpu, int id,
-                                       void *opaque)
+static int ppc_write_all_elf_notes(const char *note_name,
+                                   WriteCoreDumpFunction f,
+                                   PowerPCCPU *cpu, int id,
+                                   void *opaque)
 {
     NoteFuncArg arg = { .state = opaque };
     int ret = -1;
@@ -282,5 +291,12 @@  int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
                                int cpuid, void *opaque)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
-    return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
+    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
+}
+
+int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+                               int cpuid, void *opaque)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
 }
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index bc2a2ce..61efd7b 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1225,6 +1225,8 @@  int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
 int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
                                int cpuid, void *opaque);
+int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+                               int cpuid, void *opaque);
 #ifndef CONFIG_USER_ONLY
 void ppc_cpu_do_system_reset(CPUState *cs);
 extern const struct VMStateDescription vmstate_ppc_cpu;
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 76f79fa..ebb3d8a 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -10478,11 +10478,10 @@  static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 #else
     cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_ppc_cpu;
-#if defined(TARGET_PPC64)
-    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
-#endif
 #endif
     cc->cpu_exec_enter = ppc_cpu_exec_enter;
+    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
+    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
 
     cc->gdb_num_core_regs = 71;