On 6/3/26 09:18, Matt Turner wrote:
@@ -502,6 +502,14 @@ void target_to_host_siginfo(siginfo_t *info, const 
target_siginfo_t *tinfo)
      info->si_value.sival_ptr = (void *)(long)sival_ptr;
  }
+/*
+ * Weak arch hook: flush all register windows to the guest stack before
+ * writing a core dump.  Required on SPARC where the register file holds
+ * multiple call-frames that have not been spilled to memory yet.
+ * Architectures without register windows leave this as a no-op.
+ */
+void __attribute__((weak)) target_flush_windows(CPUArchState *env) {}
+
  /* returns 1 if given signal should dump core if not handled */
  static int core_dump_signal(int sig)
  {
@@ -828,6 +836,7 @@ void dump_core_and_abort(CPUArchState *env, int target_sig)
/* dump core if supported by target binary format */
      if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
+        target_flush_windows(env);
          stop_all_tasks();
          core_dumped =
              ((*ts->bprm->core_dump)(target_sig, env) == 0);

Not a fan of the weak symbol.

I'm pretty sure you need this flush for all threads, so probably has to happen after stop_all_tasks. Probably via one of the CPU_FOREACH in elf_core_dump.

We're not quite to the state where there are no TARGET_FOO ifdefs in elfload.c.
I think we can stand a TARGET_SPARC ifdef in elf_core_dump.

+/* Override the weak hook in linux-user/signal.c to flush all SPARC register
+ * windows to the guest stack before a core dump is written.  Without this,
+ * only the active window (captured in NT_PRSTATUS) ends up in memory; all
+ * deeper call frames remain in the register file and are absent from the
+ * core's memory segments, breaking stack unwind beyond one frame. */
+void target_flush_windows(CPUArchState *env)
+{
+    flush_windows((CPUSPARCState *)env);
+}

Cast not required -- the two names are typedefs of each other.


r~

Reply via email to