On 5/26/26 00:53, Matt Turner wrote:
Define HAVE_ELF_CORE_DUMP and target_elf_gregset_t in target_elf.h,
mirroring the kernel's elf_gregset_t (ELF_NGREG = 66): r0-r31
[0..31], f0-f31 [32..63], pc [64], ps [65]. Implement
elf_core_copy_regs() in elfload.c to populate the gregset from
CPUAlphaState.
Without this, bprm->core_dump is NULL for Alpha 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-alpha process instead of an Alpha guest core.
I'm picking this change up for currently active qemu stable series
(10.0.x and 11.0.x). While it is not a bugfix per se, but a lack
of feature which can be very useful for debugging.
For 11.0.x, picking up this patch makes subsequent patches in this area
to apply cleanly (e.g. 7a2e863f9dd "populate AT_HWCAP from env->amask").
For 10.0.x, where things are quite a bit different, both mentioned
changes require manual apply, since in there, things are in different
place (in linux-user/elfload.c) and organized a bit differently
(HAVE_ELF_CORE_DUMP vs USE_ELF_CORE_DUMP). But since I picked this
one for 11.0.x, and since 10.0.x is an LTS series, I'm picking it for
10.0.x anyway.
The result can be seen here:
https://gitlab.com/mjt0k/qemu/-/commit/bb9f5a3bbc2f06fba918432b40b56e5aeb2b3c76
Hopefully I did the back-port correctly. It would be nice to have
another view on the result.
Thanks,
/mjt
Signed-off-by: Matt Turner <[email protected]>
---
linux-user/alpha/elfload.c | 12 ++++++++++++
linux-user/alpha/target_elf.h | 13 +++++++++++++
2 files changed, 25 insertions(+)
diff --git ./linux-user/alpha/elfload.c ./linux-user/alpha/elfload.c
index 1e44475c47..c86f9cf2bb 100644
--- ./linux-user/alpha/elfload.c
+++ ./linux-user/alpha/elfload.c
@@ -3,8 +3,20 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
+#include "target_elf.h"
+void elf_core_copy_regs(target_elf_gregset_t *r, const CPUAlphaState *env)
+{
+ int i;
+
+ for (i = 0; i < 31; i++) {
+ r->regs[i] = tswap64(env->ir[i]);
+ }
+ r->pc = tswap64(env->pc);
+ r->ps = 0;
+}
+
const char *get_elf_cpu_model(uint32_t eflags)
{
return "ev67";
diff --git ./linux-user/alpha/target_elf.h ./linux-user/alpha/target_elf.h
index 864dc6e2e6..bf3bd21b09 100644
--- ./linux-user/alpha/target_elf.h
+++ ./linux-user/alpha/target_elf.h
@@ -11,4 +11,17 @@
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_ALPHA
+#define HAVE_ELF_CORE_DUMP 1
+
+/*
+ * Matches the kernel's elf_gregset_t (ELF_NGREG = 33):
+ * r0-r30 at indices 0-30, pc at 31, ps at 32.
+ * r31 (hardwired zero) is not stored; pc occupies index 31.
+ */
+typedef struct target_elf_gregset_t {
+ abi_ulong regs[31]; /* integer registers r0-r30 [0..30] */
+ abi_ulong pc; /* program counter [31] */
+ abi_ulong ps; /* processor status [32] */
+} target_elf_gregset_t;
+
#endif