From: Dmitry V. Levin Date: Wed, 4 Mar 2015 17:52:42 +0000 (+0000) Subject: sparc, sparc64: fix sigreturn decoding X-Git-Tag: v4.10~17 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=db19936861698d1cdb466c8d5d57bee029bf7282;p=strace 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 4dcae3bb..ac11a1df 100644 --- a/linux/sparc/arch_regs.h +++ b/linux/sparc/arch_regs.h @@ -4,3 +4,4 @@ extern struct pt_regs sparc_regs; #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 0dc31ea2..d34fd725 100644 --- a/signal.c +++ b/signal.c @@ -876,14 +876,24 @@ sys_sigreturn(struct tcb *tcp) } #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