Diff below simplifies setjmp(3) and longjmp(3) on sparc64 by not using
sigreturn(2).  This basically uses the logic from _setjmp(3) and
_longjmp(3) to save and restore the state (but additionally saves and
restores the signal mask).  I believe this may make us lose the
capability to longjmp() out of a signal handler when running on an
alternate stack.  But that shouldn't be a big issue since on amd64 we
don't go through extra hoops to support that either.

The setjmp regression tests still pass with this, except for the
setjmp-fpu test which already fails on sparc64 (and amd64).

ok?


Index: libc/arch/sparc64/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/gen/setjmp.S,v
retrieving revision 1.5
diff -u -p -r1.5 setjmp.S
--- libc/arch/sparc64/gen/setjmp.S      29 Jan 2004 18:56:14 -0000      1.5
+++ libc/arch/sparc64/gen/setjmp.S      26 Apr 2016 13:00:51 -0000
@@ -34,9 +34,7 @@
  * SUCH DAMAGE.
  */
 
-#define _LOCORE
 #include <machine/asm.h>
-#include <machine/frame.h>
 
 /*
  * C library -- setjmp, longjmp
@@ -45,71 +43,39 @@
  * will generate a "return(v)" from
  * the last call to
  *     setjmp(a)
- * by restoring registers from the stack,
- * and a struct sigcontext, see <signal.h>
+ * by restoring the previous context.
+ * The previous signal state is restored.
  */
 
 #include "SYS.h"
 
 #define STACK_T_SZ
 ENTRY(setjmp)
-       /*
-        * We use the part of the sigcontext structure, the sp, pc, and npc
-        * fields, for the sigaltstack call so we don't need to get our own
-        * stackframe. It won't be filled out till later anyway.
-        */
        mov     %o0, %o3                /* Save our jmp_buf in %o3 */
 
-       stx     %sp, [%o3 + 0x08]       /* sc.sc_sp = sp (both ours and 
caller's) */
-       add     %o7, 8, %o0
-       stx     %o0, [%o3 + 0x10]       /* sc.sc_pc = return_pc */
-       add     %o7, 12, %o0
-       stx     %o0, [%o3 + 0x18]       /* sc.sc_npc = return_pc + 4 */
-       stx     %g0, [%o3 + 0x20]       /* sc.sc_psr = (clean psr) */
-       stx     %fp, [%o3 + 0x28]       /* sc.sc_g1 = %fp (misuse, but what the 
heck) */
-                                       /* sc.sc_o0 = random(), set in longjmp 
*/
-
        mov     1, %o0                  /* SIG_BLOCK */
-       mov     SYS_sigprocmask, %g1
+       mov     SYS_sigprocmask, %g1    
        clr     %o1                     /* sigprocmask(SIG_BLOCK, 0) */
        t       ST_SYSCALL
+       stx     %o0, [%o3 + 0x10]
 
-       st      %o0, [%o3 + 0x38]       /* sc.sc_mask = current mask; */
-
-       mov     SYS_sigaltstack, %g1
-       clr     %o0                     /* sigaltstack(NULL, &foo) */
-       add     %o3, 0x40, %o1          /* (foo being the sigcontext sc_mask) */
-       t       ST_SYSCALL
-       
-       lduw    [%o3 + 0x40+0x10], %o0  /* foo.ss_flags */
-       and     %o0, 1, %o1             /* onstack = foo.ss_flags & 1; */
-       st      %o1, [%o3 + 0x00]       /* sc.sc_onstack = current onstack; */
-
-       retl                            /* return 0 */
-        clr    %o0
+       stx     %sp, [%o3 + 0x00]       /* store caller's stack pointer */
+       stx     %o7, [%o3 + 0x08]       /* ... and return pc */
+       retl
+        clr    %o0                     /* return 0 */
 
-/*
- * All we need to do here is force sigreturn to load a new stack pointer,
- * new <pc,npc>, and appropriate %o0 return value from the sigcontext built
- * in setjmp.  The %i and %l registers will be reloaded from the place to
- * which %sp points, due to sigreturn() semantics (sigreturn does not modify
- * the window pointer in the psr, hence it must force all windows to reload).
- */
 ENTRY(longjmp)
        save    %sp, -CC64FSZ, %sp
-       ldx     [%i0 + 0x08], %o2       /* make sure sc->sc_sp, sc->sc_fp 
nonzero */
-       ldx     [%i0 + 0x28], %o3
-       orcc    %o2, %o3, %g0
-       bz,pn   %xcc, Lbotch
-        nop
-       movrz   %i1, 1, %i1             /* if (v == 0) v = 1; */
-       st      %i1, [%i0 + 0x34]       /* sc.sc_o0 = v; */
-       mov     SYS_sigreturn, %g1
-       mov     %i0, %o0
-       t       ST_SYSCALL              /* sigreturn(scp); */
-
-Lbotch:
-       /* oops, caller botched it */
-       call    _C_LABEL(longjmperror)
-        nop
-       unimp   0
+       flushw
+       
+       mov     3, %o0                  /* SIG_SETMASK */
+       ldx     [%i0 + 0x10], %o1
+       mov     SYS_sigprocmask, %g1    
+       t       ST_SYSCALL
+       
+       ldx     [%i0 + 0x00], %fp
+       ldx     [%i0 + 0x08], %i7
+       mov     1, %i0
+       movrnz  %i1, %i1, %i0           ! compute v ? v : 1
+       ret
+        restore

Reply via email to