From 7c96ab0b434ea7d1f998841f39a5a704b84a87d2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 21 Jul 2015 17:31:02 +0200 Subject: [PATCH] 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 --- 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 4131b6cd1..27f7395e3 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,10 @@ +2015-07-21 Corinna Vinschen + + * 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 * libc/machine/aarch64/memset.S (memset): diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h index ec6644a7f..b25684dd5 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 0d9df3b9b..2d8475b14 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2015-07-21 Corinna Vinschen + + * 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 * include/cygwin/signal.h (MINSIGSTKSZ): Define as 8K, unconditionally. diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index e89a6bdb7..71a0c9be9 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 480f2d93a..986827773 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -590,21 +590,32 @@ sub longjmp { if ($is64bit) { return < 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 d909ec3ce..2c2d03827 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 4a8d92315..2fab1f64a 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 a4c30369a..e3eb26f0f 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,7 @@ +2015-07-21 Corinna Vinschen + + * new-features.xml (ov-new2.2): Document sigsetjmp, siglongjmp. + 2015-07-17 Corinna Vinschen * 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 85d6ec780..ed8d61d3a 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -12,6 +12,14 @@ 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. + +