]> granicus.if.org Git - strace/commitdiff
sparc, sparc64: fix sigreturn decoding
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 4 Mar 2015 17:52:42 +0000 (17:52 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 4 Mar 2015 17:54:25 +0000 (17:54 +0000)
* 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.

linux/sparc/arch_regs.h
signal.c

index 4dcae3bb1fce591839333eabda9416b9980faf96..ac11a1df689a035297307d0b73f8ebf635f42743 100644 (file)
@@ -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
index 0dc31ea2c02eeb500a8fd0ffaa1bebe03230198e..d34fd725b2a00709a5c462e96bd39eac5c293889 100644 (file)
--- 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