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>
This commit is contained in:
parent
b723ec272e
commit
7c96ab0b43
|
@ -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>
|
2015-07-15 Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
|
||||||
* libc/machine/aarch64/memset.S (memset):
|
* libc/machine/aarch64/memset.S (memset):
|
||||||
|
|
|
@ -381,6 +381,13 @@ typedef int sigjmp_buf[_JBLEN+1+(sizeof (sigset_t)/sizeof (int))];
|
||||||
#define __SIGMASK_FUNC sigprocmask
|
#define __SIGMASK_FUNC sigprocmask
|
||||||
#endif
|
#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__)
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
#define sigsetjmp(env, savemask) \
|
#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.
|
are equivalent to sigsetjmp/siglongjmp when not saving the signal mask.
|
||||||
New applications should use sigsetjmp/siglongjmp instead. */
|
New applications should use sigsetjmp/siglongjmp instead. */
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
extern void _longjmp(jmp_buf, int);
|
extern void _longjmp (jmp_buf, int) __attribute__ ((__noreturn__));
|
||||||
extern int _setjmp(jmp_buf);
|
extern int _setjmp (jmp_buf);
|
||||||
#else
|
#else
|
||||||
#define _setjmp(env) sigsetjmp ((env), 0)
|
#define _setjmp(env) sigsetjmp ((env), 0)
|
||||||
#define _longjmp(env, val) siglongjmp ((env), (val))
|
#define _longjmp(env, val) siglongjmp ((env), (val))
|
||||||
|
|
|
@ -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>
|
2015-07-19 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cygwin/signal.h (MINSIGSTKSZ): Define as 8K, unconditionally.
|
* include/cygwin/signal.h (MINSIGSTKSZ): Define as 8K, unconditionally.
|
||||||
|
|
|
@ -1110,6 +1110,7 @@ sighold SIGFE
|
||||||
sigignore SIGFE
|
sigignore SIGFE
|
||||||
siginterrupt SIGFE
|
siginterrupt SIGFE
|
||||||
sigismember SIGFE
|
sigismember SIGFE
|
||||||
|
siglongjmp NOSIGFE
|
||||||
signal SIGFE
|
signal SIGFE
|
||||||
significand NOSIGFE
|
significand NOSIGFE
|
||||||
significandf NOSIGFE
|
significandf NOSIGFE
|
||||||
|
@ -1119,6 +1120,7 @@ sigprocmask SIGFE
|
||||||
sigqueue SIGFE
|
sigqueue SIGFE
|
||||||
sigrelse SIGFE
|
sigrelse SIGFE
|
||||||
sigset SIGFE
|
sigset SIGFE
|
||||||
|
sigsetjmp NOSIGFE
|
||||||
sigsuspend SIGFE
|
sigsuspend SIGFE
|
||||||
sigwait SIGFE
|
sigwait SIGFE
|
||||||
sigwaitinfo SIGFE
|
sigwaitinfo SIGFE
|
||||||
|
|
|
@ -590,21 +590,32 @@ sub longjmp {
|
||||||
if ($is64bit) {
|
if ($is64bit) {
|
||||||
return <<EOF;
|
return <<EOF;
|
||||||
|
|
||||||
|
.globl sigsetjmp
|
||||||
|
.seh_proc sigsetjmp
|
||||||
|
sigsetjmp:
|
||||||
|
.seh_endprologue
|
||||||
|
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 setjmp
|
.globl setjmp
|
||||||
.seh_proc setjmp
|
.seh_proc setjmp
|
||||||
setjmp:
|
setjmp:
|
||||||
.seh_endprologue
|
.seh_endprologue
|
||||||
leaq 8(%rsp),%rdx
|
# We use the Windows jmp_buf layout with two small twists.
|
||||||
jmp __setjmpex
|
# - we store the tls stackptr in Frame, MSVCRT stores a second copy
|
||||||
.seh_endproc
|
# of %rbp in Frame (twice? why?)
|
||||||
|
# - we just store %rsp as is, MSVCRT stores %rsp of the caller in Rsp
|
||||||
.globl __setjmpex
|
|
||||||
.seh_proc __setjmpex
|
|
||||||
__setjmpex:
|
|
||||||
.seh_endprologue
|
|
||||||
# We use the Windows jmp_buf layout.
|
|
||||||
# Store alternative stackptr in Spare.
|
|
||||||
movq %rdx,(%rcx)
|
|
||||||
movq %rbx,0x8(%rcx)
|
movq %rbx,0x8(%rcx)
|
||||||
movq %rsp,0x10(%rcx)
|
movq %rsp,0x10(%rcx)
|
||||||
movq %rbp,0x18(%rcx)
|
movq %rbp,0x18(%rcx)
|
||||||
|
@ -616,6 +627,8 @@ __setjmpex:
|
||||||
movq %r15,0x48(%rcx)
|
movq %r15,0x48(%rcx)
|
||||||
movq (%rsp),%r10
|
movq (%rsp),%r10
|
||||||
movq %r10,0x50(%rcx)
|
movq %r10,0x50(%rcx)
|
||||||
|
stmxcsr 0x58(%rcx)
|
||||||
|
fnstcw 0x5c(%rcx)
|
||||||
# jmp_buf is potentially unaligned!
|
# jmp_buf is potentially unaligned!
|
||||||
movdqu %xmm6,0x60(%rcx)
|
movdqu %xmm6,0x60(%rcx)
|
||||||
movdqu %xmm7,0x70(%rcx)
|
movdqu %xmm7,0x70(%rcx)
|
||||||
|
@ -632,27 +645,47 @@ __setjmpex:
|
||||||
call stabilize_sig_stack # returns tls in r11
|
call stabilize_sig_stack # returns tls in r11
|
||||||
popq %rcx
|
popq %rcx
|
||||||
movq $tls::stackptr(%r11),%r10
|
movq $tls::stackptr(%r11),%r10
|
||||||
movq %r10,0x58(%rcx)
|
movq %r10,(%rcx)
|
||||||
decl $tls::stacklock(%r11)
|
decl $tls::stacklock(%r11)
|
||||||
movl \$0,%eax
|
xorl %eax,%eax
|
||||||
ret
|
ret
|
||||||
.seh_endproc
|
.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
|
.globl longjmp
|
||||||
.seh_proc longjmp
|
.seh_proc longjmp
|
||||||
longjmp:
|
longjmp:
|
||||||
pushq %rcx
|
pushq %rcx
|
||||||
.seh_pushreg %rcx
|
.seh_pushreg %rcx
|
||||||
.seh_endprologue
|
.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
|
call stabilize_sig_stack # returns tls in r11
|
||||||
popq %rcx
|
popq %rcx
|
||||||
movl %r12d,%eax # restore return value
|
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
|
movq %r10,$tls::stackptr(%r11) # restore
|
||||||
decl $tls::stacklock(%r11) # relinquish lock
|
decl $tls::stacklock(%r11) # relinquish lock
|
||||||
xorl %r10d,%r10d
|
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 0x8(%rcx),%rbx
|
||||||
movq 0x10(%rcx),%rsp
|
movq 0x10(%rcx),%rsp
|
||||||
movq 0x18(%rcx),%rbp
|
movq 0x18(%rcx),%rbp
|
||||||
|
@ -664,6 +697,9 @@ longjmp:
|
||||||
movq 0x48(%rcx),%r15
|
movq 0x48(%rcx),%r15
|
||||||
movq 0x50(%rcx),%r10
|
movq 0x50(%rcx),%r10
|
||||||
movq %r10,(%rsp)
|
movq %r10,(%rsp)
|
||||||
|
ldmxcsr 0x58(%rcx)
|
||||||
|
fnclex
|
||||||
|
fldcw 0x5c(%rcx)
|
||||||
# jmp_buf is potentially unaligned!
|
# jmp_buf is potentially unaligned!
|
||||||
movdqu 0x60(%rcx),%xmm6
|
movdqu 0x60(%rcx),%xmm6
|
||||||
movdqu 0x70(%rcx),%xmm7
|
movdqu 0x70(%rcx),%xmm7
|
||||||
|
@ -684,12 +720,33 @@ EOF
|
||||||
} else {
|
} else {
|
||||||
return <<EOF;
|
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
|
.globl _setjmp
|
||||||
_setjmp:
|
_setjmp:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
pushl %edi
|
pushl %edi
|
||||||
movl 8(%ebp),%edi
|
movl 8(%ebp),%edi
|
||||||
|
1:
|
||||||
movl %eax,0(%edi)
|
movl %eax,0(%edi)
|
||||||
movl %ebx,4(%edi)
|
movl %ebx,4(%edi)
|
||||||
movl %ecx,8(%edi)
|
movl %ecx,8(%edi)
|
||||||
|
@ -717,7 +774,7 @@ _setjmp:
|
||||||
fnstcw 48(%edi)
|
fnstcw 48(%edi)
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
call stabilize_sig_stack
|
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)
|
decl $tls::stacklock(%ebx)
|
||||||
popl %ebx
|
popl %ebx
|
||||||
movl %eax,52(%edi)
|
movl %eax,52(%edi)
|
||||||
|
@ -796,17 +853,36 @@ ___ljfault:
|
||||||
popfl
|
popfl
|
||||||
ret
|
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
|
.globl _longjmp
|
||||||
_longjmp:
|
_longjmp:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp,%ebp
|
movl %esp,%ebp
|
||||||
movl 8(%ebp),%edi # address of buffer
|
movl 8(%ebp),%edi # &jmp_buf
|
||||||
|
1:
|
||||||
call stabilize_sig_stack
|
call stabilize_sig_stack
|
||||||
movl 52(%edi),%eax # get old signal stack
|
movl 52(%edi),%eax # get old signal stack
|
||||||
movl %eax,$tls::stackptr(%ebx) # restore
|
movl %eax,$tls::stackptr(%ebx) # restore
|
||||||
decl $tls::stacklock(%ebx) # relinquish lock
|
decl $tls::stacklock(%ebx) # relinquish lock
|
||||||
xorl %eax,%eax
|
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
|
movl 12(%ebp),%eax
|
||||||
testl %eax,%eax
|
testl %eax,%eax
|
||||||
|
|
|
@ -470,13 +470,14 @@ details. */
|
||||||
286: Export cabsl, cimagl, creall, finitel, hypotl, sqrtl.
|
286: Export cabsl, cimagl, creall, finitel, hypotl, sqrtl.
|
||||||
287: Export issetugid.
|
287: Export issetugid.
|
||||||
288: Export getcontext, makecontext, setcontext, swapcontext.
|
288: Export getcontext, makecontext, setcontext, swapcontext.
|
||||||
|
289: Export sigsetjmp, siglongjmp.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
||||||
sigaltstack, sethostname. */
|
sigaltstack, sethostname. */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#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
|
/* There is also a compatibity version number associated with the
|
||||||
shared memory regions. It is incremented when incompatible
|
shared memory regions. It is incremented when incompatible
|
||||||
|
|
|
@ -3,6 +3,10 @@ What's new:
|
||||||
|
|
||||||
- New APIs: getcontext, setcontext, makecontext, swapcontext.
|
- 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:
|
What changed:
|
||||||
-------------
|
-------------
|
||||||
|
|
|
@ -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>
|
2015-07-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* new-features.xml (ov-new2.2): Add new section. Document getcontext,
|
* new-features.xml (ov-new2.2): Add new section. Document getcontext,
|
||||||
|
|
|
@ -12,6 +12,14 @@
|
||||||
New APIs: getcontext, setcontext, makecontext, swapcontext.
|
New APIs: getcontext, setcontext, makecontext, swapcontext.
|
||||||
</para></listitem>
|
</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>
|
</itemizedlist>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
Loading…
Reference in New Issue