From: Matt Turner <[email protected]> Define HAVE_ELF_CORE_DUMP and target_elf_gregset_t in target_elf.h, mirroring struct user_regs_struct: pc followed by x1 (ra) through x31 (t6). Implement elf_core_copy_regs() in elfload.c to populate the gregset from CPURISCVState.
Without this, bprm->core_dump is NULL for RISC-V targets. When a guest signal goes unhandled, dump_core_and_abort() skips the core write and falls through to die_with_signal(), which re-raises the signal to the host. The host kernel then writes an x86-64 core file for the qemu-riscv64 process instead of a RISC-V guest core. Signed-off-by: Matt Turner <[email protected]> Signed-off-by: Helge Deller <[email protected]> --- linux-user/riscv/elfload.c | 9 +++++++++ linux-user/riscv/target_elf.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/linux-user/riscv/elfload.c b/linux-user/riscv/elfload.c index 2e7d622232..afe103a631 100644 --- a/linux-user/riscv/elfload.c +++ b/linux-user/riscv/elfload.c @@ -3,6 +3,7 @@ #include "qemu/osdep.h" #include "qemu.h" #include "loader.h" +#include "target_elf.h" const char *get_elf_cpu_model(uint32_t eflags) @@ -10,6 +11,14 @@ const char *get_elf_cpu_model(uint32_t eflags) return "max"; } +void elf_core_copy_regs(target_elf_gregset_t *r, const CPURISCVState *env) +{ + r->pc = tswapal(env->pc); + for (int i = 0; i < 31; i++) { + r->regs[i] = tswapal(env->gpr[i + 1]); + } +} + abi_ulong get_elf_hwcap(CPUState *cs) { #define MISA_BIT(EXT) (1 << (EXT - 'A')) diff --git a/linux-user/riscv/target_elf.h b/linux-user/riscv/target_elf.h index dbbfdf54d3..859f726578 100644 --- a/linux-user/riscv/target_elf.h +++ b/linux-user/riscv/target_elf.h @@ -19,5 +19,12 @@ #endif #define HAVE_ELF_HWCAP 1 +#define HAVE_ELF_CORE_DUMP 1 + +/* Mirrors struct user_regs_struct: pc followed by x1 (ra) .. x31 (t6). */ +typedef struct target_elf_gregset_t { + abi_ulong pc; + abi_ulong regs[31]; +} target_elf_gregset_t; #endif -- 2.54.0
