* handler (provided that target process haven't registered
* handler for that) that does the dump when signal is received.
*/
+#ifdef TARGET_SPARC
+#include "sparc/cpu_loop.h"
+#endif
static int elf_core_dump(int signr, const CPUArchState *env)
{
const CPUState *cpu = env_cpu_const(env);
cpu_list_lock();
mmap_lock();
+#ifdef TARGET_SPARC
+ CPU_FOREACH(cpu_iter) {
+ flush_windows(cpu_env(cpu_iter));
+ }
+#endif
+
/* By unprotecting, we merge vmas that might be split. */
walk_memory_regions(NULL, wmr_page_unprotect_regions);
#include "user-internals.h"
#include "user/cpu_loop.h"
#include "signal-common.h"
+#include "sparc/cpu_loop.h"
#define SPARC64_STACK_BIAS 2047
#endif
}
-static void flush_windows(CPUSPARCState *env)
+void flush_windows(CPUSPARCState *env)
{
int offset, cwp1;
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef SPARC_CPU_LOOP_H
+#define SPARC_CPU_LOOP_H
+
+void flush_windows(CPUSPARCState *env);
+
+#endif
CPUSPARCState *e = (CPUSPARCState *)env;
int i;
+ memset(r, 0, sizeof(*r));
+
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
+ /* Linux kernel layout for sparc64 (arch/sparc/include/asm/elf_64.h):
+ * [0..7] G0-G7
+ * [8..15] O0-O7
+ * [16..23] L0-L7
+ * [24..31] I0-I7
+ * [32] TSTATE
+ * [33] TPC
+ * [34] TNPC
+ * [35] Y
+ */
for (i = 0; i < 8; i++) {
- r->regs[i] = tswap64(env->gregs[i]);
- r->regs[8 + i] = tswap64(env->regwptr[WREG_O0 + i]);
+ r->regs[i] = tswap64(env->gregs[i]);
+ r->regs[8 + i] = tswap64(env->regwptr[WREG_O0 + i]);
+ r->regs[16 + i] = tswap64(env->regwptr[WREG_L0 + i]);
+ r->regs[24 + i] = tswap64(env->regwptr[WREG_I0 + i]);
}
- r->regs[16] = tswap64(sparc64_tstate(e));
- r->regs[17] = tswap64(env->pc);
- r->regs[18] = tswap64(env->npc);
- r->regs[19] = tswap64(env->y);
+ r->regs[32] = tswap64(sparc64_tstate(e));
+ r->regs[33] = tswap64(env->pc);
+ r->regs[34] = tswap64(env->npc);
+ r->regs[35] = tswap64(env->y);
#else
+ /* Linux kernel layout for sparc32 (arch/sparc/include/asm/elf_32.h):
+ * [0] PSR
+ * [1] PC
+ * [2] NPC
+ * [3] Y
+ * [4..11] G0-G7
+ * [12..19] O0-O7
+ * [20..27] L0-L7
+ * [28..35] I0-I7
+ * [36..37] reserved (stack_check)
+ */
r->regs[0] = tswap32(cpu_get_psr(e));
r->regs[1] = tswap32(env->pc);
r->regs[2] = tswap32(env->npc);
for (i = 0; i < 8; i++) {
r->regs[4 + i] = tswap32(env->gregs[i]);
r->regs[12 + i] = tswap32(env->regwptr[WREG_O0 + i]);
+ r->regs[20 + i] = tswap32(env->regwptr[WREG_L0 + i]);
+ r->regs[28 + i] = tswap32(env->regwptr[WREG_I0 + i]);
}
#endif
}
#define HAVE_ELF_CORE_DUMP 1
/*
- * Matches the kernel's elf_gregset_t (ELF_NGREG = 20).
- * sparc32/sparc32plus: psr, pc, npc, y, u_regs[16] (g0-g7, o0-o7)
- * sparc64: u_regs[16] (g0-g7, o0-o7), tstate, pc, npc, y
+ * Matches the kernel's elf_gregset_t.
+ * sparc32/sparc32plus (ELF_NGREG = 38):
+ * psr, pc, npc, y, u_regs[16] (g0-g7, o0-o7),
+ * reg_window[16] (l0-l7, i0-i7), stack_check[2]
+ * sparc64 (ELF_NGREG = 36):
+ * u_regs[16] (g0-g7, o0-o7), reg_window[16] (l0-l7, i0-i7),
+ * tstate, tpc, tnpc, y
*/
+#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
+# define TARGET_ELF_NGREG 36
+#else
+# define TARGET_ELF_NGREG 38
+#endif
typedef struct target_elf_gregset_t {
- abi_ulong regs[20];
+ abi_ulong regs[TARGET_ELF_NGREG];
} target_elf_gregset_t;
#endif