sparc, sparc64: fix sigreturn decoding
* linux/sparc/arch_regs.h (U_REG_FP): New macro.
* signal.c (sys_sigreturn) [SPARC || SPARC64]: Fix decoding
of upper 32 bits of the sigmask.
diff --git a/linux/sparc/arch_regs.h b/linux/sparc/arch_regs.h
index 4dcae3b..ac11a1d 100644
--- a/linux/sparc/arch_regs.h
+++ b/linux/sparc/arch_regs.h
@@ -4,3 +4,4 @@
#define U_REG_G1 0
#define U_REG_O0 7
#define U_REG_O1 8
+#define U_REG_FP 13
diff --git a/signal.c b/signal.c
index 0dc31ea..d34fd72 100644
--- a/signal.c
+++ b/signal.c
@@ -876,14 +876,24 @@
}
#elif defined(SPARC) || defined(SPARC64)
if (entering(tcp)) {
- long i1;
- m_siginfo_t si;
- i1 = sparc_regs.u_regs[U_REG_O1];
- if (umove(tcp, i1, &si) < 0) {
- perror_msg("sigreturn: umove");
- return 0;
+ long fp = sparc_regs.u_regs[U_REG_FP] + sizeof(struct sparc_stackf);
+ struct {
+ m_siginfo_t si;
+ void *fpu_save;
+ long insns[2] __attribute__ ((aligned (8)));
+ unsigned int extramask[NSIG / 8 / sizeof(int) - 1];
+ } frame;
+
+ tprints(") (mask ");
+ if (umove(tcp, fp, &frame) < 0) {
+ tprintf("%#lx", fp);
+ } else {
+ unsigned int mask[NSIG / 8 / sizeof(int)];
+
+ mask[0] = frame.si.si_mask;
+ memcpy(mask + 1, frame.extramask, sizeof(frame.extramask));
+ tprintsigmask_val("", mask);
}
- tprintsigmask_val(") (mask ", si.si_mask);
}
#elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64)
/* This decodes rt_sigreturn. The 64-bit ABIs do not have