[PATCH 0/5] linux-user: support writing floating-point registers to a core dump
Matt Turner <[email protected]> Wed, 5 Aug 2026 13:23:29 -0400
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Write an NT_FPREGSET note for targets that opt in: a target_elf.h that defines HAVE_ELF_CORE_FPREGS and target_elf_fpregset_t, and supplies an elf_core_copy_fpregs() beside the existing elf_core_copy_regs(). Signed-off-by: Matt Turner <[email protected]> --- Apologies -- this prerequisite patch was accidentally omitted from the series I sent earlier today (Message-ID: <[email protected]>). It should be applied before patches 1-5 of that series. linux-user/elfload.c | 19 +++++++++++++++++++ linux-user/loader.h | 3 +++ 2 files changed, 22 insertions(+) diff --git ./linux-user/elfload.c ./linux-user/elfload.c index e7c56af8ed..88508deac5 100644 --- ./linux-user/elfload.c +++ ./linux-user/elfload.c @@ -1887,6 +1887,17 @@ static void fill_elf_note_phdr(struct elf_phdr *phdr, size_t sz, off_t offset) bswap_phdr(phdr, 1); } +#ifdef HAVE_ELF_CORE_FPREGS +static void fill_fpregset_note(void *data, CPUState *cpu) +{ + /* Fill locally and copy: note memory is only aligned to 4. */ + target_elf_fpregset_t fpregs = {}; + + elf_core_copy_fpregs(&fpregs, cpu_env(cpu)); + memcpy(data, &fpregs, sizeof(fpregs)); +} +#endif + static void fill_prstatus_note(void *data, CPUState *cpu, int signr) { /* @@ -2166,6 +2177,9 @@ static int elf_core_dump(int signr, const CPUArchState *env) offset += size_note("CORE", ts->info->auxv_len); offset += size_note("CORE", sizeof(struct target_elf_prpsinfo)); offset += size_note("CORE", sizeof(struct target_elf_prstatus)) * cpus; +#ifdef HAVE_ELF_CORE_FPREGS + offset += size_note("CORE", sizeof(target_elf_fpregset_t)) * cpus; +#endif note_size = offset - note_offset; data_offset = TARGET_PAGE_ALIGN(offset); @@ -2222,6 +2236,11 @@ static int elf_core_dump(int signr, const CPUArchState *env) dptr = fill_note(&hptr, NT_PRSTATUS, "CORE", sizeof(struct target_elf_prstatus)); fill_prstatus_note(dptr, cpu_iter, cpu_iter == cpu ? signr : 0); +#ifdef HAVE_ELF_CORE_FPREGS + dptr = fill_note(&hptr, NT_FPREGSET, "CORE", + sizeof(target_elf_fpregset_t)); + fill_fpregset_note(dptr, cpu_iter); +#endif } if (dump_write(fd, header, data_offset) < 0) { diff --git ./linux-user/loader.h ./linux-user/loader.h index da9ad28db5..5ddd140276 100644 --- ./linux-user/loader.h +++ ./linux-user/loader.h @@ -109,6 +109,9 @@ bool init_guest_commpage(void); struct target_elf_gregset_t; void elf_core_copy_regs(struct target_elf_gregset_t *, const CPUArchState *); +/* Only defined by a target whose target_elf.h sets HAVE_ELF_CORE_FPREGS. */ +struct target_elf_fpregset_t; +void elf_core_copy_fpregs(struct target_elf_fpregset_t *, const CPUArchState *); typedef struct { const uint8_t *image; -- 2.54.0