diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2015-07-21 17:31:02 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2015-07-21 17:31:02 +0200 |
commit | 7c96ab0b434ea7d1f998841f39a5a704b84a87d2 (patch) | |
tree | 2006925253b9172b5066a3779e7a420499399880 /winsup | |
parent | b723ec272e5a1e7be453e0b75ed6b71fc5871f3a (diff) | |
download | newlib-7c96ab0b434ea7d1f998841f39a5a704b84a87d2.zip newlib-7c96ab0b434ea7d1f998841f39a5a704b84a87d2.tar.gz newlib-7c96ab0b434ea7d1f998841f39a5a704b84a87d2.tar.bz2 |
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 <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 14 | ||||
-rw-r--r-- | winsup/cygwin/common.din | 2 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 120 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/release/2.2.0 | 4 | ||||
-rw-r--r-- | winsup/doc/ChangeLog | 4 | ||||
-rw-r--r-- | winsup/doc/new-features.xml | 8 |
7 files changed, 132 insertions, 23 deletions
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 <corinna@vinschen.de> + + * 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 <corinna@vinschen.de> * 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 <corinna@vinschen.de> + + * new-features.xml (ov-new2.2): Document sigsetjmp, siglongjmp. + 2015-07-17 Corinna Vinschen <corinna@vinschen.de> * 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> |