https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=7c96ab0b434ea7d1f998841f39a5a704b84a87d2

commit 7c96ab0b434ea7d1f998841f39a5a704b84a87d2
Author: Corinna Vinschen <[email protected]>
Date:   Tue Jul 21 17:31:02 2015 +0200

    Cygwin: Implement siglongjmp and sigsetjmp functions.
    
        * libc/include/machine/setjmp.h (siglongjmp): Declare as function on
        Cygwin.
        (sigsetjmp): Ditto.
        (_longjmp): Mark as noreturn function on Cygwin.
    
        * common.din (siglongjmp): Export.
        (sigsetjmp): Export.
        * gendef: Change formatting of some comments.
        (sigsetjmp): Implement.
        (siglongjmp): Implement.
        (__setjmpex): x86_64 only: Drop entry point.
        (setjmp): x86_64 only: Store tls stackptr in Frame now, store MXCSR
        and FPUCW registers in Spare, as MSVCRT does.
        (longjmp): x86_64 only: Restore tls stackptr from Frame now, restore
        MXCSR and FPUCW registers from Spare.
        * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
    
        * new-features.xml (ov-new2.2): Document sigsetjmp, siglongjmp.
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 newlib/ChangeLog                       |   7 ++
 newlib/libc/include/machine/setjmp.h   |  11 ++-
 winsup/cygwin/ChangeLog                |  14 ++++
 winsup/cygwin/common.din               |   2 +
 winsup/cygwin/gendef                   | 120 +++++++++++++++++++++++++++------
 winsup/cygwin/include/cygwin/version.h |   3 +-
 winsup/cygwin/release/2.2.0            |   4 ++
 winsup/doc/ChangeLog                   |   4 ++
 winsup/doc/new-features.xml            |   8 +++
 9 files changed, 148 insertions(+), 25 deletions(-)

diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 4131b6c..27f7395 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,10 @@
+2015-07-21  Corinna Vinschen  <[email protected]>
+
+       * libc/include/machine/setjmp.h (siglongjmp): Declare as function on
+       Cygwin.
+       (sigsetjmp): Ditto.
+       (_longjmp): Mark as noreturn function on Cygwin.
+
 2015-07-15  Wilco Dijkstra  <[email protected]>
 
        * libc/machine/aarch64/memset.S (memset):
diff --git a/newlib/libc/include/machine/setjmp.h 
b/newlib/libc/include/machine/setjmp.h
index ec6644a..b25684d 100644
--- a/newlib/libc/include/machine/setjmp.h
+++ b/newlib/libc/include/machine/setjmp.h
@@ -381,6 +381,13 @@ typedef int sigjmp_buf[_JBLEN+1+(sizeof (sigset_t)/sizeof 
(int))];
 #define __SIGMASK_FUNC sigprocmask
 #endif
 
+#ifdef __CYGWIN__
+/* Per POSIX, siglongjmp has to be implemented as function.  Cygwin
+   provides functions for both, siglongjmp and sigsetjmp since 2.2.0. */
+extern void siglongjmp (sigjmp_buf, int) __attribute__ ((__noreturn__));
+extern int sigsetjmp (sigjmp_buf, int);
+#endif
+
 #if defined(__GNUC__)
 
 #define sigsetjmp(env, savemask) \
@@ -418,8 +425,8 @@ typedef int sigjmp_buf[_JBLEN+1+(sizeof (sigset_t)/sizeof 
(int))];
    are equivalent to sigsetjmp/siglongjmp when not saving the signal mask.
    New applications should use sigsetjmp/siglongjmp instead. */
 #ifdef __CYGWIN__
-extern void _longjmp(jmp_buf, int);
-extern int _setjmp(jmp_buf);
+extern void _longjmp (jmp_buf, int) __attribute__ ((__noreturn__));
+extern int _setjmp (jmp_buf);
 #else
 #define _setjmp(env)           sigsetjmp ((env), 0)
 #define _longjmp(env, val)     siglongjmp ((env), (val))
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0d9df3b..2d8475b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,17 @@
+2015-07-21  Corinna Vinschen  <[email protected]>
+
+       * common.din (siglongjmp): Export.
+       (sigsetjmp): Export.
+       * gendef: Change formatting of some comments.
+       (sigsetjmp): Implement.
+       (siglongjmp): Implement.
+       (__setjmpex): x86_64 only: Drop entry point.
+       (setjmp): x86_64 only: Store tls stackptr in Frame now, store MXCSR
+       and FPUCW registers in Spare, as MSVCRT does.
+       (longjmp): x86_64 only: Restore tls stackptr from Frame now, restore
+       MXCSR and FPUCW registers from Spare.
+       * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
+
 2015-07-19  Corinna Vinschen  <[email protected]>
 
        * include/cygwin/signal.h (MINSIGSTKSZ): Define as 8K, unconditionally.
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index e89a6bd..71a0c9b 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -1110,6 +1110,7 @@ sighold SIGFE
 sigignore SIGFE
 siginterrupt SIGFE
 sigismember SIGFE
+siglongjmp NOSIGFE
 signal SIGFE
 significand NOSIGFE
 significandf NOSIGFE
@@ -1119,6 +1120,7 @@ sigprocmask SIGFE
 sigqueue SIGFE
 sigrelse SIGFE
 sigset SIGFE
+sigsetjmp NOSIGFE
 sigsuspend SIGFE
 sigwait SIGFE
 sigwaitinfo SIGFE
diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef
index 480f2d9..9868277 100755
--- a/winsup/cygwin/gendef
+++ b/winsup/cygwin/gendef
@@ -590,21 +590,32 @@ sub longjmp {
     if ($is64bit) {
        return <<EOF;
 
-       .globl  setjmp
-       .seh_proc setjmp
-setjmp:
+       .globl  sigsetjmp
+       .seh_proc sigsetjmp
+sigsetjmp:
        .seh_endprologue
-       leaq    8(%rsp),%rdx
-       jmp     __setjmpex
+       movl    %edx,0x100(%rcx)                # store savemask
+       testl   %edx,%edx                       # savemask != 0?
+       je      setjmp                          # no, skip fetching sigmask
+       pushq   %rcx
+       subq    \$0x20,%rsp
+       leaq    0x108(%rcx),%r8                 # &sigjmp_buf.sigmask
+       xorq    %rdx,%rdx                       # NULL
+       xorl    %ecx,%ecx                       # SIG_SETMASK
+       call    pthread_sigmask
+       addq    \$0x20,%rsp
+       popq    %rcx
+       jmp     setjmp
        .seh_endproc
 
-       .globl  __setjmpex
-       .seh_proc __setjmpex
-__setjmpex:
+       .globl  setjmp
+       .seh_proc setjmp
+setjmp:
        .seh_endprologue
-       # We use the Windows jmp_buf layout.
-       # Store alternative stackptr in Spare.
-       movq    %rdx,(%rcx)
+       # We use the Windows jmp_buf layout with two small twists.
+       # - we store the tls stackptr in Frame, MSVCRT stores a second copy
+       #   of %rbp in Frame (twice? why?)
+       # - we just store %rsp as is, MSVCRT stores %rsp of the caller in Rsp
        movq    %rbx,0x8(%rcx)
        movq    %rsp,0x10(%rcx)
        movq    %rbp,0x18(%rcx)
@@ -616,6 +627,8 @@ __setjmpex:
        movq    %r15,0x48(%rcx)
        movq    (%rsp),%r10
        movq    %r10,0x50(%rcx)
+       stmxcsr 0x58(%rcx)
+       fnstcw  0x5c(%rcx)
        # jmp_buf is potentially unaligned!
        movdqu  %xmm6,0x60(%rcx)
        movdqu  %xmm7,0x70(%rcx)
@@ -632,27 +645,47 @@ __setjmpex:
        call    stabilize_sig_stack             # returns tls in r11
        popq    %rcx
        movq    $tls::stackptr(%r11),%r10
-       movq    %r10,0x58(%rcx)
+       movq    %r10,(%rcx)
        decl    $tls::stacklock(%r11)
-       movl    \$0,%eax
+       xorl    %eax,%eax
        ret
        .seh_endproc
 
+       .globl  siglongjmp
+       .seh_proc siglongjmp
+siglongjmp:
+       pushq   %rcx
+       .seh_pushreg %rcx
+       .seh_endprologue
+       movl    %edx, %r12d
+       movl    0x100(%rcx),%r8d                # savemask
+       testl   %r8d,%r8d                       # savemask != 0?
+       je      1f                              # no, jmp to longjmp
+       xorq    %r8,%r8                         # NULL
+       leaq    0x108(%rcx),%rdx                # &sigjmp_buf.sigmask
+       xorl    %ecx,%ecx                       # SIG_SETMASK
+       subq    \$0x20,%rsp
+       call    pthread_sigmask
+       addq    \$0x20,%rsp
+       jmp     1f
+       .seh_endproc
+
        .globl  longjmp
        .seh_proc longjmp
 longjmp:
        pushq   %rcx
        .seh_pushreg %rcx
        .seh_endprologue
-       movl    %edx,%r12d                      # save return value (r12 is 
overwritten anyway)
+       movl    %edx,%r12d                      # save return value
+1:
        call    stabilize_sig_stack             # returns tls in r11
        popq    %rcx
        movl    %r12d,%eax                      # restore return value
-       movq    0x58(%rcx),%r10                 # get old signal stack
+       movq    (%rcx),%r10                     # get old signal stack
        movq    %r10,$tls::stackptr(%r11)       # restore
        decl    $tls::stacklock(%r11)           # relinquish lock
        xorl    %r10d,%r10d
-       movl    %r10d,$tls::incyg(%r11)         # we're definitely not in 
cygwin anymore
+       movl    %r10d,$tls::incyg(%r11)         # we're not in cygwin anymore
        movq    0x8(%rcx),%rbx
        movq    0x10(%rcx),%rsp
        movq    0x18(%rcx),%rbp
@@ -664,6 +697,9 @@ longjmp:
        movq    0x48(%rcx),%r15
        movq    0x50(%rcx),%r10
        movq    %r10,(%rsp)
+       ldmxcsr 0x58(%rcx)
+       fnclex
+       fldcw   0x5c(%rcx)
        # jmp_buf is potentially unaligned!
        movdqu  0x60(%rcx),%xmm6
        movdqu  0x70(%rcx),%xmm7
@@ -684,12 +720,33 @@ EOF
     } else {
        return <<EOF;
 
+       .globl  _sigsetjmp
+_sigsetjmp:
+       pushl   %ebp
+       movl    %esp,%ebp
+       pushl   %edi
+       movl    8(%ebp),%edi                    # &sigjmp_buf
+       movl    12(%ebp),%eax                   # savemask
+       movl    %eax,208(%edi)                  # store savemask
+       testl   %eax,%eax                       # savemask != 0?
+       je      1f                              # no, skip fetching sigmask
+       subl    \$12,%esp
+       leal    212(%edi),%eax                  # &sigjmp_buf.sigmask
+       movl    %eax,8(%esp)                    # -> 3rd param "oldset"
+       xorl    %eax,%eax
+       movl    %eax,4(%esp)                    # NULL -> 2nd param "set"
+       movl    %eax,(%esp)                     # SIG_SETMASK -> 1st param "how"
+       call    _pthread_sigmask
+       addl    \$12,%esp
+       jmp     1f
+
        .globl  _setjmp
 _setjmp:
        pushl   %ebp
        movl    %esp,%ebp
        pushl   %edi
        movl    8(%ebp),%edi
+1:
        movl    %eax,0(%edi)
        movl    %ebx,4(%edi)
        movl    %ecx,8(%edi)
@@ -717,7 +774,7 @@ _setjmp:
        fnstcw  48(%edi)
        pushl   %ebx
        call    stabilize_sig_stack
-       movl    $tls::stackptr(%ebx),%eax               # save stack pointer 
contents
+       movl    $tls::stackptr(%ebx),%eax       # save stack pointer contents
        decl    $tls::stacklock(%ebx)
        popl    %ebx
        movl    %eax,52(%edi)
@@ -796,17 +853,36 @@ ___ljfault:
        popfl
        ret
 
+       .globl  _siglongjmp
+_siglongjmp:
+       pushl   %ebp
+       movl    %esp,%ebp
+       movl    8(%ebp),%edi                    # &sigjmp_buf
+       movl    208(%edi),%eax                  # load savemask
+       testl   %eax,%eax                       # savemask != 0?
+       je      1f                              # no, skip restoring sigmask
+       subl    \$12,%esp
+       leal    212(%edi),%eax                  # &sigjmp_buf.sigmask
+       movl    %eax,4(%esp)                    # -> 2nd param "set"
+       xorl    %eax,%eax
+       movl    %eax,8(%esp)                    # NULL -> 3rd param "oldset"
+       movl    %eax,(%esp)                     # SIG_SETMASK -> 1st param "how"
+       call    _pthread_sigmask
+       addl    \$12,%esp
+       jmp     1f
+
        .globl  _longjmp
 _longjmp:
        pushl   %ebp
        movl    %esp,%ebp
-       movl    8(%ebp),%edi                            # address of buffer
+       movl    8(%ebp),%edi                    # &jmp_buf
+1:
        call    stabilize_sig_stack
-       movl    52(%edi),%eax                           # get old signal stack
-       movl    %eax,$tls::stackptr(%ebx)               # restore
-       decl    $tls::stacklock(%ebx)                   # relinquish lock
+       movl    52(%edi),%eax                   # get old signal stack
+       movl    %eax,$tls::stackptr(%ebx)       # restore
+       decl    $tls::stacklock(%ebx)           # relinquish lock
        xorl    %eax,%eax
-       movl    %eax,$tls::incyg(%ebx)                  # we're definitely not 
in cygwin anymore
+       movl    %eax,$tls::incyg(%ebx)          # we're not in cygwin anymore
 
        movl    12(%ebp),%eax
        testl   %eax,%eax
diff --git a/winsup/cygwin/include/cygwin/version.h 
b/winsup/cygwin/include/cygwin/version.h
index d909ec3..2c2d038 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -470,13 +470,14 @@ details. */
       286: Export cabsl, cimagl, creall, finitel, hypotl, sqrtl.
       287: Export issetugid.
       288: Export getcontext, makecontext, setcontext, swapcontext.
+      289: Export sigsetjmp, siglongjmp.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull,
        sigaltstack, sethostname. */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 288
+#define CYGWIN_VERSION_API_MINOR 289
 
      /* There is also a compatibity version number associated with the
        shared memory regions.  It is incremented when incompatible
diff --git a/winsup/cygwin/release/2.2.0 b/winsup/cygwin/release/2.2.0
index 4a8d923..2fab1f6 100644
--- a/winsup/cygwin/release/2.2.0
+++ b/winsup/cygwin/release/2.2.0
@@ -3,6 +3,10 @@ What's new:
 
 - New APIs: getcontext, setcontext, makecontext, swapcontext.
 
+- New functions: sigsetjmp, siglongjmp.
+  These were only available as macros up to now, but POSIX requires that
+  siglongjmp has to be available as function.
+
 
 What changed:
 -------------
diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog
index a4c3036..e3eb26f 100644
--- a/winsup/doc/ChangeLog
+++ b/winsup/doc/ChangeLog
@@ -1,3 +1,7 @@
+2015-07-21  Corinna Vinschen  <[email protected]>
+
+       * new-features.xml (ov-new2.2): Document sigsetjmp, siglongjmp.
+
 2015-07-17  Corinna Vinschen  <[email protected]>
 
        * new-features.xml (ov-new2.2): Add new section.  Document getcontext,
diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml
index 85d6ec7..ed8d61d 100644
--- a/winsup/doc/new-features.xml
+++ b/winsup/doc/new-features.xml
@@ -12,6 +12,14 @@
 New APIs: getcontext, setcontext, makecontext, swapcontext.
 </para></listitem>
 
+<listitem><para>
+New functions: sigsetjmp, siglongjmp.
+</para>
+<para>
+These were only available as macros up to now, but POSIX requires that
+siglongjmp has to be available as function.
+</para></listitem>
+
 </itemizedlist>
 
 </sect2>

Reply via email to