Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-07-21 18:31:02 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-07-21 18:31:02 +0300
commit7c96ab0b434ea7d1f998841f39a5a704b84a87d2 (patch)
tree2006925253b9172b5066a3779e7a420499399880
parentb723ec272e5a1e7be453e0b75ed6b71fc5871f3a (diff)
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>
-rw-r--r--newlib/ChangeLog7
-rw-r--r--newlib/libc/include/machine/setjmp.h11
-rw-r--r--winsup/cygwin/ChangeLog14
-rw-r--r--winsup/cygwin/common.din2
-rwxr-xr-xwinsup/cygwin/gendef120
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/release/2.2.04
-rw-r--r--winsup/doc/ChangeLog4
-rw-r--r--winsup/doc/new-features.xml8
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 <corinna@vinschen.de>
+
+ * 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 <wdijkstr@arm.com>
* 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 <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 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 <<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 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 <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 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.
</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>