Module Name: src Committed By: martin Date: Fri Aug 23 16:59:53 UTC 2024
Modified Files: src/distrib/sets/lists/debug [netbsd-9]: mi src/distrib/sets/lists/tests [netbsd-9]: mi src/lib/libc/arch/arm/gen [netbsd-9]: setjmp.S src/lib/libc/arch/i386/gen [netbsd-9]: setjmp.S sigsetjmp.S src/lib/libc/arch/sh3/gen [netbsd-9]: setjmp.S sigsetjmp.S src/lib/libc/arch/x86_64/gen [netbsd-9]: __setjmp14.S __sigsetjmp14.S src/tests/lib/libc/setjmp [netbsd-9]: Makefile Added Files: src/tests/lib/libc/setjmp [netbsd-9]: t_sigstack.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #795): tests/lib/libc/setjmp/Makefile: revision 1.3 distrib/sets/lists/debug/mi: revision 1.425 lib/libc/arch/sh3/gen/setjmp.S: revision 1.12 lib/libc/arch/i386/gen/sigsetjmp.S: revision 1.19 lib/libc/arch/x86_64/gen/__setjmp14.S: revision 1.4 tests/lib/libc/setjmp/t_sigstack.c: revision 1.10 tests/lib/libc/setjmp/t_sigstack.c: revision 1.11 tests/lib/libc/setjmp/t_sigstack.c: revision 1.12 tests/lib/libc/setjmp/t_sigstack.c: revision 1.1 lib/libc/arch/sh3/gen/sigsetjmp.S: revision 1.11 tests/lib/libc/setjmp/t_sigstack.c: revision 1.2 tests/lib/libc/setjmp/t_sigstack.c: revision 1.3 tests/lib/libc/setjmp/t_sigstack.c: revision 1.4 tests/lib/libc/setjmp/t_sigstack.c: revision 1.5 tests/lib/libc/setjmp/t_sigstack.c: revision 1.6 lib/libc/arch/arm/gen/setjmp.S: revision 1.19 tests/lib/libc/setjmp/t_sigstack.c: revision 1.7 tests/lib/libc/setjmp/t_sigstack.c: revision 1.8 tests/lib/libc/setjmp/t_sigstack.c: revision 1.9 lib/libc/arch/i386/gen/setjmp.S: revision 1.18 lib/libc/arch/x86_64/gen/__sigsetjmp14.S: revision 1.4 distrib/sets/lists/tests/mi: revision 1.1306 (patch) longjmp(3): Add test for PR lib/57946. longjmp(3): Paranoia: more error checking in PR lib/57946 test. longjmp(3): Test signal mask vs stack restore with siglongjmp too. PR lib/57946 longjmp(3) t_sigstack: Print which entry failed. PR lib/57946 longjmp(3) t_sigstack: Note aarch64 seems to DTRT. But only by code inspection; it appears to have another problem: on re-entry, the signal handler is called on the normal stack, not on the alternate signal stack. PR lib/57946 longjmp(3) t_sigstack: Use a sigaltstack per handler entry. longjmp evidently doesn't reset the state of whether the process is executing on the alternate signal stack. So when we re-enter the signal handler, the alternate stack appears to be still in use, and the system chooses the original stack for the second call to the signal handler -- which trips our assertion asking to verify that the signal handler is always using an alternate stack. Not strictly necessary for the signal handler to use an alternate stack on re-entry, but this makes it clearer that the signal handler itself is always using the alternate stack so we can verify that the interrupted code is _not_ in the signal handler. With this change, the test now passes on aarch64. PR lib/57946 longjmp(3) t_sigstack: Fix fencepost error. Extremely unlikely to cause trouble, but let's just turn that into `never' to keep it easier for readers. PR lib/57946 amd64 longjmp: Restore stack first, then signal mask. Otherwise, a pending signal may be delivered on the wrong stack when we restore the signal mask. While here: - Tidy the code a little bit. - Sprinkle comments to explain what's going on. - Use `xorl %eXX,%eXX' instead of `xorq %rXX,%rXX'. => Same effect, one byte shorter, breaks dep chain on more uarches. - Use forward branches for statically predicted not-taken. => val==0 is unlikely in longjmp PR lib/57946 i386 longjmp: Restore stack first, then signal mask. Otherwise, a pending signal may be delivered on the wrong stack when we restore the signal mask. While here: - Tidy the code a little bit. - Sprinkle comments to explain what's going on. - Use forward branches for statically predicted not-taken. => val==0 is unlikely in longjmp PR lib/57946 arm longjmp: Restore stack first, then signal mask. Otherwise, a pending signal may be delivered on the wrong stack when we restore the signal mask. While here: - Move the botched sp and lr tests earlier. PR lib/57946 arm has been fixed tests/lib/libc/setjmp/t_sigstack: Add missing comment for 1.10. PR lib/57946 sh3: siglongjmp - restore register context first (PR lib/57946) To generate a diff of this commit: cvs rdiff -u -r1.285.2.7 -r1.285.2.8 src/distrib/sets/lists/debug/mi cvs rdiff -u -r1.818.2.5 -r1.818.2.6 src/distrib/sets/lists/tests/mi cvs rdiff -u -r1.17 -r1.17.28.1 src/lib/libc/arch/arm/gen/setjmp.S cvs rdiff -u -r1.17 -r1.17.26.1 src/lib/libc/arch/i386/gen/setjmp.S cvs rdiff -u -r1.18 -r1.18.26.1 src/lib/libc/arch/i386/gen/sigsetjmp.S cvs rdiff -u -r1.10 -r1.10.88.1 src/lib/libc/arch/sh3/gen/setjmp.S cvs rdiff -u -r1.9 -r1.9.88.1 src/lib/libc/arch/sh3/gen/sigsetjmp.S cvs rdiff -u -r1.3 -r1.3.26.1 src/lib/libc/arch/x86_64/gen/__setjmp14.S \ src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S cvs rdiff -u -r1.2 -r1.2.46.1 src/tests/lib/libc/setjmp/Makefile cvs rdiff -u -r0 -r1.12.4.2 src/tests/lib/libc/setjmp/t_sigstack.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/debug/mi diff -u src/distrib/sets/lists/debug/mi:1.285.2.7 src/distrib/sets/lists/debug/mi:1.285.2.8 --- src/distrib/sets/lists/debug/mi:1.285.2.7 Mon Mar 25 14:26:15 2024 +++ src/distrib/sets/lists/debug/mi Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.285.2.7 2024/03/25 14:26:15 martin Exp $ +# $NetBSD: mi,v 1.285.2.8 2024/08/23 16:59:52 martin Exp $ ./etc/mtree/set.debug comp-sys-root ./usr/lib comp-sys-usr compatdir ./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib,compatfile @@ -2025,6 +2025,7 @@ ./usr/libdata/debug/usr/tests/lib/libc/rpc/t_rpc.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/rpc/t_xdr.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/setjmp/t_setjmp.debug tests-lib-debug debug,atf,compattestfile +./usr/libdata/debug/usr/tests/lib/libc/setjmp/t_sigstack.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/setjmp/t_threadjmp.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/ssp/h_fgets.debug tests-lib-debug debug,atf,ssp,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/ssp/h_getcwd.debug tests-lib-debug debug,atf,ssp,compattestfile Index: src/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.818.2.5 src/distrib/sets/lists/tests/mi:1.818.2.6 --- src/distrib/sets/lists/tests/mi:1.818.2.5 Mon Mar 25 14:26:15 2024 +++ src/distrib/sets/lists/tests/mi Fri Aug 23 16:59:53 2024 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.818.2.5 2024/03/25 14:26:15 martin Exp $ +# $NetBSD: mi,v 1.818.2.6 2024/08/23 16:59:53 martin Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -2701,6 +2701,7 @@ ./usr/tests/lib/libc/setjmp/Atffile tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/setjmp/Kyuafile tests-lib-tests compattestfile,atf,kyua ./usr/tests/lib/libc/setjmp/t_setjmp tests-lib-tests compattestfile,atf +./usr/tests/lib/libc/setjmp/t_sigstack tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/setjmp/t_threadjmp tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/ssp tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/ssp/Atffile tests-lib-tests compattestfile,atf,ssp Index: src/lib/libc/arch/arm/gen/setjmp.S diff -u src/lib/libc/arch/arm/gen/setjmp.S:1.17 src/lib/libc/arch/arm/gen/setjmp.S:1.17.28.1 --- src/lib/libc/arch/arm/gen/setjmp.S:1.17 Sat Nov 30 20:20:42 2013 +++ src/lib/libc/arch/arm/gen/setjmp.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: setjmp.S,v 1.17 2013/11/30 20:20:42 joerg Exp $ */ +/* $NetBSD: setjmp.S,v 1.17.28.1 2024/08/23 16:59:52 martin Exp $ */ /* * Copyright (c) 1997 Mark Brinicombe @@ -142,6 +142,25 @@ ENTRY(__longjmp14) cmp r3, ip bne .Lbotch + /* Validate sp and lr */ + ldr r2, [r0, #(_JB_REG_R13 * 4)] +#if defined(__thumb__) && defined(_ARM_ARCH_T2) + cbz r2, .Lbotch +#else + cmp r2, #0 + beq .Lbotch +#endif + + ldr r3, [r0, #(_JB_REG_R14 * 4)] +#if defined(__thumb__) && defined(_ARM_ARCH_T2) + cbz r3, .Lbotch +#else + cmp r3, #0 + beq .Lbotch +#endif + mov sp, r2 + mov lr, r3 + /* Restore the signal mask. */ push {r0-r2, lr} movs r2, #0 @@ -186,25 +205,6 @@ ENTRY(__longjmp14) adds r0, r0, #4 /* skip ip(r12) */ #endif - ldmia r0!, {r2-r3} - - /* Validate sp and lr */ -#if defined(__thumb__) && defined(_ARM_ARCH_T2) - cbz r2, .Lbotch -#else - cmp r2, #0 - beq .Lbotch -#endif - mov sp, r2 - -#if defined(__thumb__) && defined(_ARM_ARCH_T2) - cbz r3, .Lbotch -#else - cmp r3, #0 - beq .Lbotch -#endif - mov lr, r3 - /* Set return value */ movs r0, r1 #if !defined(__thumb__) Index: src/lib/libc/arch/i386/gen/setjmp.S diff -u src/lib/libc/arch/i386/gen/setjmp.S:1.17 src/lib/libc/arch/i386/gen/setjmp.S:1.17.26.1 --- src/lib/libc/arch/i386/gen/setjmp.S:1.17 Fri May 23 03:05:56 2014 +++ src/lib/libc/arch/i386/gen/setjmp.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: setjmp.S,v 1.17 2014/05/23 03:05:56 uebayasi Exp $ */ +/* $NetBSD: setjmp.S,v 1.17.26.1 2024/08/23 16:59:52 martin Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -36,7 +36,7 @@ #include <machine/asm.h> #if defined(LIBC_SCCS) - RCSID("$NetBSD: setjmp.S,v 1.17 2014/05/23 03:05:56 uebayasi Exp $") + RCSID("$NetBSD: setjmp.S,v 1.17.26.1 2024/08/23 16:59:52 martin Exp $") #endif /* @@ -49,12 +49,24 @@ * The previous signal state is restored. */ +/* + * setjmp(jmp_buf env@esp[4,8)) + * + * ELF symbol: __setjmp14, because the size of jmp_buf changed on some + * platforms in 1.4. + */ ENTRY(__setjmp14) - movl 4(%esp),%ecx - movl 0(%esp),%edx - movl %edx, 0(%ecx) - movl %ebx, 4(%ecx) - movl %esp, 8(%ecx) + /* + * Save the callee-saves registers: %ebp, %ebx, %edi, %esi, + * plus %esp and the return address on the stack since it + * will be overwritten if the caller makes any subroutine + * calls before longjmp. + */ + movl 4(%esp),%ecx /* ecx := env */ + movl 0(%esp),%edx /* edx := return address */ + movl %edx,0(%ecx) + movl %ebx,4(%ecx) + movl %esp,8(%ecx) movl %ebp,12(%ecx) movl %esi,16(%ecx) movl %edi,20(%ecx) @@ -63,49 +75,65 @@ ENTRY(__setjmp14) leal 24(%ecx),%edx PIC_PROLOGUE - pushl %edx - pushl $0 - pushl $0 + pushl %edx /* oset (signal mask saved to) */ + pushl $0 /* set := NULL */ + pushl $0 /* how := 0 (ignored) */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif - addl $12,%esp + addl $12,%esp /* pop sigprocmask args */ PIC_EPILOGUE - xorl %eax,%eax + xorl %eax,%eax /* return 0 first time around */ ret END(__setjmp14) +/* + * longjmp(jmp_buf env@esp[4,8), int val@[8,12)) + * + * ELF symbol: __longjmp14, because the size of jmp_buf changed on some + * platforms in 1.4. + */ ENTRY(__longjmp14) + /* + * Restore the callee-saves registers: %ebp, %ebx, %edi, %esi, + * plus %esp and the return address on the stack. + */ + movl 4(%esp),%edx /* edx := env */ + movl 8(%esp),%eax /* eax := val */ + movl 0(%edx),%ecx /* ecx := return address */ + movl 4(%edx),%ebx + movl 8(%edx),%esp + movl 12(%edx),%ebp + movl 16(%edx),%esi + movl 20(%edx),%edi + movl %ecx,0(%esp) /* restore return address */ + /* Restore the signal mask. */ - movl 4(%esp),%ecx - leal 24(%ecx),%edx + leal 24(%edx),%edx + + pushl %eax /* save val@eax */ PIC_PROLOGUE - pushl $0 - pushl %edx - pushl $3 /* SIG_SETMASK */ + pushl $0 /* oset := NULL */ + pushl %edx /* set (signal mask restored from) */ + pushl $3 /* how := SIG_SETMASK */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif - addl $12,%esp + addl $12,%esp /* pop sigprocmask args */ PIC_EPILOGUE - movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx - movl 4(%edx),%ebx - movl 8(%edx),%esp - movl 12(%edx),%ebp - movl 16(%edx),%esi - movl 20(%edx),%edi - testl %eax,%eax - jnz 1f - incl %eax -1: movl %ecx,0(%esp) - ret + popl %eax /* restore val@eax */ + + testl %eax,%eax /* val == 0? */ + jz 3f /* jump if val == 0 */ + ret /* return val@eax */ + +3: incl %eax /* val@eax := 1 */ + ret /* return val@eax */ END(__longjmp14) Index: src/lib/libc/arch/i386/gen/sigsetjmp.S diff -u src/lib/libc/arch/i386/gen/sigsetjmp.S:1.18 src/lib/libc/arch/i386/gen/sigsetjmp.S:1.18.26.1 --- src/lib/libc/arch/i386/gen/sigsetjmp.S:1.18 Fri May 23 02:34:19 2014 +++ src/lib/libc/arch/i386/gen/sigsetjmp.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: sigsetjmp.S,v 1.18 2014/05/23 02:34:19 uebayasi Exp $ */ +/* $NetBSD: sigsetjmp.S,v 1.18.26.1 2024/08/23 16:59:52 martin Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -36,76 +36,104 @@ #include <machine/asm.h> #if defined(LIBC_SCCS) - RCSID("$NetBSD: sigsetjmp.S,v 1.18 2014/05/23 02:34:19 uebayasi Exp $") + RCSID("$NetBSD: sigsetjmp.S,v 1.18.26.1 2024/08/23 16:59:52 martin Exp $") #endif +/* + * sigsetjmp(sigjmp_buf env@esp[4,8), savemask@esp[8,12)) + * + * ELF symbol: __sigsetjmp14, because the size of sigjmp_buf changed on + * some platforms in 1.4. + */ ENTRY(__sigsetjmp14) - movl 4(%esp),%ecx - movl 0(%esp),%edx - movl %edx, 0(%ecx) - movl %ebx, 4(%ecx) - movl %esp, 8(%ecx) + /* + * Save the callee-saves registers: %ebp, %ebx, %edi, %esi, + * plus %esp and the return address on the stack since it + * will be overwritten if the caller makes any subroutine + * calls before siglongjmp. + */ + movl 4(%esp),%ecx /* ecx := env */ + movl 0(%esp),%edx /* edx := return address */ + movl %edx,0(%ecx) + movl %ebx,4(%ecx) + movl %esp,8(%ecx) movl %ebp,12(%ecx) movl %esi,16(%ecx) movl %edi,20(%ecx) /* Check if we should save the signal mask, and remember it. */ - movl 8(%esp),%eax + movl 8(%esp),%eax /* eax := savemask */ movl %eax,40(%ecx) - testl %eax,%eax - jz 2f /* no, skip */ + testl %eax,%eax /* savemask == 0? */ + jz 2f /* jump if savemask == 0 */ /* Get the signal mask. */ leal 24(%ecx),%edx PIC_PROLOGUE - pushl %edx - pushl $0 - pushl $0 + pushl %edx /* oset (signal mask saved to) */ + pushl $0 /* set := NULL */ + pushl $0 /* how := 0 (ignored) */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif - addl $12,%esp + addl $12,%esp /* pop sigprocmask args */ PIC_EPILOGUE -2: xorl %eax,%eax +2: xorl %eax,%eax /* return 0 first time around */ ret END(__sigsetjmp14) +/* + * siglongjmp(sigjmp_buf env@esp[4,8), int val@[8,12)) + * + * ELF symbol: __siglongjmp14, because the size of sigjmp_buf changed + * on some platforms in 1.4. + */ ENTRY(__siglongjmp14) + /* + * Restore the callee-saves registers: %ebp, %ebx, %edi, %esi, + * plus %esp and the return address on the stack. + */ + movl 4(%esp),%edx /* edx := env */ + movl 8(%esp),%eax /* eax := val */ + movl 0(%edx),%ecx /* ecx := return address */ + movl 4(%edx),%ebx + movl 8(%edx),%esp + movl 12(%edx),%ebp + movl 16(%edx),%esi + movl 20(%edx),%edi + movl %ecx,0(%esp) /* restore return address */ + /* Check to see if we need to restore the signal mask. */ - movl 4(%esp),%ecx - cmpl $0,40(%ecx) - jz 2f /* no, skip */ + cmpl $0,40(%edx) /* savemask == 0 */ + jz 2f /* jump if savemask == 0 */ /* Restore the signal mask. */ - leal 24(%ecx),%edx + leal 24(%edx),%edx + + pushl %eax /* save val@eax */ PIC_PROLOGUE - pushl $0 - pushl %edx - pushl $3 /* SIG_SETMASK */ + pushl $0 /* oset := NULL */ + pushl %edx /* set (signal mask restored from) */ + pushl $3 /* how := SIG_SETMASK */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif - addl $12,%esp + addl $12,%esp /* pop sigprocmask args */ PIC_EPILOGUE -2: movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx - movl 4(%edx),%ebx - movl 8(%edx),%esp - movl 12(%edx),%ebp - movl 16(%edx),%esi - movl 20(%edx),%edi - testl %eax,%eax - jnz 3f - incl %eax -3: movl %ecx,0(%esp) - ret + popl %eax /* restore val@eax */ + +2: testl %eax,%eax /* val == 0? */ + jz 3f /* jump if val == 0 */ + ret /* return val@eax */ + +3: incl %eax /* val@eax := 1 */ + ret /* return val@eax */ END(__siglongjmp14) Index: src/lib/libc/arch/sh3/gen/setjmp.S diff -u src/lib/libc/arch/sh3/gen/setjmp.S:1.10 src/lib/libc/arch/sh3/gen/setjmp.S:1.10.88.1 --- src/lib/libc/arch/sh3/gen/setjmp.S:1.10 Thu Jan 5 19:21:37 2006 +++ src/lib/libc/arch/sh3/gen/setjmp.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: setjmp.S,v 1.10 2006/01/05 19:21:37 uwe Exp $ */ +/* $NetBSD: setjmp.S,v 1.10.88.1 2024/08/23 16:59:52 martin Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -38,7 +38,7 @@ #include <machine/setjmp.h> #if defined(LIBC_SCCS) - RCSID("$NetBSD: setjmp.S,v 1.10 2006/01/05 19:21:37 uwe Exp $") + RCSID("$NetBSD: setjmp.S,v 1.10.88.1 2024/08/23 16:59:52 martin Exp $") #endif /* @@ -90,39 +90,40 @@ ENTRY(__setjmp14) ENTRY(__longjmp14) - /* we won't return here, so we don't need to save pr and r12 */ - PIC_PROLOGUE_NOSAVE(.L_got_2) - mov.l r5, @-sp - mov.l r4, @-sp + // return value can't be zero, adjust to 1 if it is + tst r5, r5 + bf/s 0f + mov.l @(_JB_REG_PR * 4, r4), r0 + mov #1, r5 +0: + // restore context first (callee-saved regs) + mov.l @(_JB_REG_R8 * 4, r4), r8 + mov.l @(_JB_REG_R9 * 4, r4), r9 + mov.l @(_JB_REG_R10 * 4, r4), r10 + mov.l @(_JB_REG_R11 * 4, r4), r11 + mov.l @(_JB_REG_R12 * 4, r4), r12 + mov.l @(_JB_REG_R13 * 4, r4), r13 + mov.l @(_JB_REG_R14 * 4, r4), r14 + mov.l @(_JB_REG_R15 * 4, r4), r15 + + // create a frame + mov.l r5, @-sp // future return value (pre-adjusted) + mov.l r0, @-sp // caller's PR from the jumpbuf + PIC_PROLOGUE(.L_got_2) - mov.l .L___sigprocmask14_2, r0 + // restore signal mask from &a[_JB_SIGMASK] + mov #0, r6 // oset = NULL mov r4, r5 - mov #3, r4 /* how = SIG_SETMASK */ - add #(_JB_SIGMASK * 4), r5 /* new = &sigmask */ + mov.l .L___sigprocmask14_2, r0 + add #(_JB_SIGMASK * 4), r5 // set = &a[_JB_SIGMASK] 1: CALL r0 - mov #0, r6 /* old = NULL */ + mov #3, r4 // how = SIG_SETMASK - mov.l @sp+, r4 - mov.l @sp+, r5 - - /* identical to _longjmp */ - lds.l @r4+, pr - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - - mov r5, r0 - tst r0, r0 /* make sure return value is non-zero */ - bf .L0 - add #1, r0 -.L0: + // return "from" setjmp + PIC_EPILOGUE + lds.l @sp+, pr rts - nop + mov.l @sp+, r0 .align 2 .L_got_2: PIC_GOT_DATUM Index: src/lib/libc/arch/sh3/gen/sigsetjmp.S diff -u src/lib/libc/arch/sh3/gen/sigsetjmp.S:1.9 src/lib/libc/arch/sh3/gen/sigsetjmp.S:1.9.88.1 --- src/lib/libc/arch/sh3/gen/sigsetjmp.S:1.9 Thu Jan 5 19:21:37 2006 +++ src/lib/libc/arch/sh3/gen/sigsetjmp.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: sigsetjmp.S,v 1.9 2006/01/05 19:21:37 uwe Exp $ */ +/* $NetBSD: sigsetjmp.S,v 1.9.88.1 2024/08/23 16:59:52 martin Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -38,7 +38,7 @@ #include <machine/setjmp.h> #if defined(LIBC_SCCS) - RCSID("$NetBSD: sigsetjmp.S,v 1.9 2006/01/05 19:21:37 uwe Exp $") + RCSID("$NetBSD: sigsetjmp.S,v 1.9.88.1 2024/08/23 16:59:52 martin Exp $") #endif ENTRY(__sigsetjmp14) @@ -85,44 +85,49 @@ ENTRY(__sigsetjmp14) ENTRY(__siglongjmp14) - mov.l @(_JB_HAS_MASK * 4, r4), r0 - tst r0, r0 - bt 2f /* if no mask */ - - /* identical to longjmp */ - /* we won't return here, so we don't need to save pr and r12 */ - PIC_PROLOGUE_NOSAVE(.L_got_2) - mov.l r5, @-sp - mov.l r4, @-sp + // return value can't be zero, adjust to 1 if it is + tst r5, r5 + bf/s 0f + mov.l @(_JB_REG_PR * 4, r4), r0 + mov #1, r5 +0: + // restore context first (callee-saved regs) + mov.l @(_JB_REG_R8 * 4, r4), r8 + mov.l @(_JB_REG_R9 * 4, r4), r9 + mov.l @(_JB_REG_R10 * 4, r4), r10 + mov.l @(_JB_REG_R11 * 4, r4), r11 + mov.l @(_JB_REG_R12 * 4, r4), r12 + mov.l @(_JB_REG_R13 * 4, r4), r13 + mov.l @(_JB_REG_R14 * 4, r4), r14 + mov.l @(_JB_REG_R15 * 4, r4), r15 + + // do we need to restore signal mask? + mov.l @(_JB_HAS_MASK * 4, r4), r7 + tst r7, r7 + bf/s 0f + mov #0, r6 // sigprocmask: oset = NULL + // ... no, just the registers + lds r0, pr + rts + mov r5, r0 +0: + // create a frame + mov.l r5, @-sp // future return value (pre-adjusted) + mov.l r0, @-sp // caller's PR from the jumpbuf + PIC_PROLOGUE(.L_got_2) - mov.l .L___sigprocmask14_2, r0 + // restore signal mask from &a[_JB_SIGMASK] mov r4, r5 - mov #3, r4 /* how = SIG_SETMASK */ - add #(_JB_SIGMASK * 4), r5 /* new = &sigmask */ + mov.l .L___sigprocmask14_2, r0 + add #(_JB_SIGMASK * 4), r5 // set = &a[_JB_SIGMASK] 1: CALL r0 - mov #0, r6 /* old = NULL */ + mov #3, r4 // how = SIG_SETMASK - mov.l @sp+, r4 - mov.l @sp+, r5 - -2: /* identical to _longjmp */ - lds.l @r4+, pr - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - - mov r5, r0 - tst r0, r0 /* make sure return value is non-zero */ - bf .L0 - add #1, r0 -.L0: + // return "from" setjmp + PIC_EPILOGUE + lds.l @sp+, pr rts - nop + mov.l @sp+, r0 .align 2 .L_got_2: PIC_GOT_DATUM Index: src/lib/libc/arch/x86_64/gen/__setjmp14.S diff -u src/lib/libc/arch/x86_64/gen/__setjmp14.S:1.3 src/lib/libc/arch/x86_64/gen/__setjmp14.S:1.3.26.1 --- src/lib/libc/arch/x86_64/gen/__setjmp14.S:1.3 Thu May 22 15:01:56 2014 +++ src/lib/libc/arch/x86_64/gen/__setjmp14.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: __setjmp14.S,v 1.3 2014/05/22 15:01:56 uebayasi Exp $ */ +/* $NetBSD: __setjmp14.S,v 1.3.26.1 2024/08/23 16:59:52 martin Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -40,7 +40,7 @@ #include <machine/setjmp.h> #if defined(LIBC_SCCS) - RCSID("$NetBSD: __setjmp14.S,v 1.3 2014/05/22 15:01:56 uebayasi Exp $") + RCSID("$NetBSD: __setjmp14.S,v 1.3.26.1 2024/08/23 16:59:52 martin Exp $") #endif /* @@ -53,7 +53,19 @@ * The previous signal state is restored. */ +/* + * setjmp(jmp_buf env@rdi) + * + * ELF symbol: __setjmp14, because the size of jmp_buf changed on some + * platforms in 1.4. + */ ENTRY(__setjmp14) + /* + * Save the callee-saves registers: %rbx, %rbp, %r12-r15, + * plus %rsp and the return address on the stack since it + * will be overwritten if the caller makes any subroutine + * calls before longjmp. + */ movq (%rsp),%r11 movq %rbx,(_JB_RBX * 8)(%rdi) movq %rbp,(_JB_RBP * 8)(%rdi) @@ -64,47 +76,62 @@ ENTRY(__setjmp14) movq %rsp,(_JB_RSP * 8)(%rdi) movq %r11,(_JB_PC * 8)(%rdi) - leaq (_JB_SIGMASK * 8)(%rdi),%rdx - xorl %edi,%edi - xorq %rsi,%rsi + leaq (_JB_SIGMASK * 8)(%rdi),%rdx /* oset@rdx */ + xorl %edi,%edi /* how@edi := 0 (ignored) */ + xorl %esi,%esi /* set@rsi := NULL */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif -2: xorl %eax,%eax + xorl %eax,%eax ret END(__setjmp14) +/* + * longjmp(jmp_buf env@rdi, int val@esi) + * + * ELF symbol: __longjmp14, because the size of jmp_buf changed on some + * platforms in 1.4 + */ ENTRY(__longjmp14) - movq %rdi,%r12 - movl %esi,%r8d - - leaq (_JB_SIGMASK * 8)(%rdi),%rsi - movl $3,%edi /* SIG_SETMASK */ - xorq %rdx,%rdx + /* + * Restore the callee-saves registers: %rbx, %rbp, %r12-r15, + * plus %rsp and the return address on the stack. + */ + movq (_JB_RBX * 8)(%rdi),%rbx + movq (_JB_RBP * 8)(%rdi),%rbp + movq (_JB_R12 * 8)(%rdi),%r12 + movq (_JB_R13 * 8)(%rdi),%r13 + movq (_JB_R14 * 8)(%rdi),%r14 + movq (_JB_R15 * 8)(%rdi),%r15 + movq (_JB_RSP * 8)(%rdi),%rsp + movq (_JB_PC * 8)(%rdi),%r11 + movq %r11,0(%rsp) + + /* + * Use pushq %rsi instead of pushl %esi in order to keep + * 16-byte stack alignment, even though we only care about the + * 32-bit int in esi. + */ + pushq %rsi /* save val@esi */ + + leaq (_JB_SIGMASK * 8)(%rdi),%rsi /* set@rsi */ + movl $3,%edi /* how@edi := SIG_SETMASK */ + xorl %edx,%edx /* oset@rdx := NULL */ - pushq %r8 #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif - popq %r8 - movq (_JB_RBX * 8)(%r12),%rbx - movq (_JB_RBP * 8)(%r12),%rbp - movq (_JB_R13 * 8)(%r12),%r13 - movq (_JB_R14 * 8)(%r12),%r14 - movq (_JB_R15 * 8)(%r12),%r15 - movq (_JB_RSP * 8)(%r12),%rsp - movq (_JB_PC * 8)(%r12),%r11 - movq (_JB_R12 * 8)(%r12),%r12 - - movl %r8d,%eax - testl %eax,%eax - jnz 1f - incl %eax -1: movq %r11,0(%rsp) - ret + + popq %rax /* restore val@eax */ + + testl %eax,%eax /* val@eax == 0? */ + jz 1f /* jump if val@eax == 0 */ + ret /* return val@eax */ +1: incl %eax /* val@eax := 1 */ + ret /* return val@eax */ END(__longjmp14) Index: src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S diff -u src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S:1.3 src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S:1.3.26.1 --- src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S:1.3 Thu May 22 15:01:56 2014 +++ src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S Fri Aug 23 16:59:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: __sigsetjmp14.S,v 1.3 2014/05/22 15:01:56 uebayasi Exp $ */ +/* $NetBSD: __sigsetjmp14.S,v 1.3.26.1 2024/08/23 16:59:52 martin Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -40,7 +40,7 @@ #include <machine/setjmp.h> #if defined(LIBC_SCCS) - RCSID("$NetBSD: __sigsetjmp14.S,v 1.3 2014/05/22 15:01:56 uebayasi Exp $") + RCSID("$NetBSD: __sigsetjmp14.S,v 1.3.26.1 2024/08/23 16:59:52 martin Exp $") #endif /* @@ -53,7 +53,19 @@ * The previous signal state is restored. */ +/* + * sigsetjmp(sigjmp_buf env@rdi, int savemask@esi) + * + * ELF symbol: __sigsetjmp14, because the size of sigjmp_buf changed on + * some platforms in 1.4. + */ ENTRY(__sigsetjmp14) + /* + * Save the callee-saves registers: %rbx, %rbp, %r12-r15, + * plus %rsp and the return address on the stack since it + * will be overwritten if the caller makes any subroutine + * calls before siglongjmp. + */ movq (%rsp),%r11 movq %rbx,(_JB_RBX * 8)(%rdi) movq %rbp,(_JB_RBP * 8)(%rdi) @@ -64,51 +76,69 @@ ENTRY(__sigsetjmp14) movq %rsp,(_JB_RSP * 8)(%rdi) movq %r11,(_JB_PC * 8)(%rdi) - movq %rsi,(_JB_SIGFLAG * 8)(%rdi) - testl %esi,%esi - jz 2f - - leaq (_JB_SIGMASK * 8)(%rdi),%rdx - xorl %edi,%edi - xorq %rsi,%rsi + movq %rsi,(_JB_SIGFLAG * 8)(%rdi) /* store savemask */ + testl %esi,%esi /* savemask == 0? */ + jz 2f /* jump if savemask == 0 */ + + leaq (_JB_SIGMASK * 8)(%rdi),%rdx /* oset@rdx */ + xorl %edi,%edi /* how@edi := 0 (ignored) */ + xorl %esi,%esi /* set@rsi := NULL */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif -2: xorl %eax,%eax +2: xorl %eax,%eax /* return 0 first time around */ ret END(__sigsetjmp14) +/* + * siglongjmp(sigjmp_buf env@rdi, int val@esi) + * + * ELF symbol: __siglongjmp14, because the size of sigjmp_buf changed + * on some platforms in 1.4. + */ ENTRY(__siglongjmp14) - movq %rdi,%r12 - pushq %rsi - cmpl $0, (_JB_SIGFLAG * 8)(%rdi) - - jz 2f - leaq (_JB_SIGMASK * 8)(%rdi),%rsi - movl $3,%edi /* SIG_SETMASK */ - xorq %rdx,%rdx + /* + * Restore the callee-saves registers: %rbx, %rbp, %r12-r15, + * plus %rsp and the return address on the stack. + */ + movq (_JB_RBX * 8)(%rdi),%rbx + movq (_JB_RBP * 8)(%rdi),%rbp + movq (_JB_R12 * 8)(%rdi),%r12 + movq (_JB_R13 * 8)(%rdi),%r13 + movq (_JB_R14 * 8)(%rdi),%r14 + movq (_JB_R15 * 8)(%rdi),%r15 + movq (_JB_RSP * 8)(%rdi),%rsp + movq (_JB_PC * 8)(%rdi),%r11 + movq %r11,0(%rsp) + + /* + * Use pushq %rsi instead of pushl %esi in order to keep + * 16-byte stack alignment, even though we only care about the + * 32-bit int in esi. + */ + pushq %rsi /* save val@esi */ + + cmpl $0, (_JB_SIGFLAG * 8)(%rdi) /* test savemask == 0? */ + jz 2f /* jump if savemask == 0 */ + + leaq (_JB_SIGMASK * 8)(%rdi),%rsi /* set@rsi */ + movl $3,%edi /* how@edi := SIG_SETMASK */ + xorl %edx,%edx /* oset@rdx := NULL */ #ifdef __PIC__ call PIC_PLT(_C_LABEL(__sigprocmask14)) #else call _C_LABEL(__sigprocmask14) #endif -2: popq %rax - movq (_JB_RBX * 8)(%r12),%rbx - movq (_JB_RBP * 8)(%r12),%rbp - movq (_JB_R13 * 8)(%r12),%r13 - movq (_JB_R14 * 8)(%r12),%r14 - movq (_JB_R15 * 8)(%r12),%r15 - movq (_JB_RSP * 8)(%r12),%rsp - movq (_JB_PC * 8)(%r12),%r11 - movq (_JB_R12 * 8)(%r12),%r12 - - testl %eax,%eax - jnz 1f - incl %eax -1: movq %r11,0(%rsp) - ret + +2: popq %rax /* restore val@eax */ + + testl %eax,%eax /* val@eax == 0? */ + jz 1f /* jump if val@eax == 0 */ + ret /* return val@eax */ +1: incl %eax /* val@eax := 1 */ + ret /* return val@eax */ END(__siglongjmp14) Index: src/tests/lib/libc/setjmp/Makefile diff -u src/tests/lib/libc/setjmp/Makefile:1.2 src/tests/lib/libc/setjmp/Makefile:1.2.46.1 --- src/tests/lib/libc/setjmp/Makefile:1.2 Thu Apr 21 18:58:20 2011 +++ src/tests/lib/libc/setjmp/Makefile Fri Aug 23 16:59:51 2024 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.2 2011/04/21 18:58:20 martin Exp $ +# $NetBSD: Makefile,v 1.2.46.1 2024/08/23 16:59:51 martin Exp $ NOMAN= # defined @@ -9,6 +9,7 @@ WARNS= 4 TESTSDIR= ${TESTSBASE}/lib/libc/setjmp TESTS_C+= t_setjmp +TESTS_C+= t_sigstack TESTS_C+= t_threadjmp LDFLAGS.t_threadjmp+= -pthread Added files: Index: src/tests/lib/libc/setjmp/t_sigstack.c diff -u /dev/null src/tests/lib/libc/setjmp/t_sigstack.c:1.12.4.2 --- /dev/null Fri Aug 23 16:59:53 2024 +++ src/tests/lib/libc/setjmp/t_sigstack.c Fri Aug 23 16:59:52 2024 @@ -0,0 +1,262 @@ +/* $NetBSD: t_sigstack.c,v 1.12.4.2 2024/08/23 16:59:52 martin Exp $ */ + +/*- + * Copyright (c) 2024 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_sigstack.c,v 1.12.4.2 2024/08/23 16:59:52 martin Exp $"); + +#include <setjmp.h> +#include <signal.h> +#include <stddef.h> +#include <stdlib.h> +#include <ucontext.h> + +#include "h_macros.h" + +struct sigaltstack ss[3]; +jmp_buf jmp; +sigjmp_buf sigjmp; +unsigned nentries; +const char *bailname; +void (*bailfn)(void) __dead; + +static void +on_sigusr1(int signo, siginfo_t *si, void *ctx) +{ + ucontext_t *uc = ctx; + void *sp = (void *)(uintptr_t)_UC_MACHINE_SP(uc); + void *fp = __builtin_frame_address(0); + struct sigaltstack *ssp; + + /* + * Ensure we haven't re-entered the signal handler too many + * times. We should enter only twice. + */ + ATF_REQUIRE_MSG(nentries < 2, + "%u recursive signal handler entries is too many in this test", + nentries + 1); + + /* + * Ensure that the signal handler was called in the alternate + * signal stack. + */ + ssp = &ss[nentries]; + ATF_REQUIRE_MSG((fp >= ssp->ss_sp && + fp < (void *)((char *)ssp->ss_sp + ssp->ss_size)), + "sigaltstack failed to take effect on entry %u --" + " signal handler's frame pointer %p doesn't lie in sigaltstack" + " [%p, %p), size 0x%zx", + nentries, + fp, ssp->ss_sp, (char *)ssp->ss_sp + ssp->ss_size, ssp->ss_size); + + /* + * Ensure that if we enter the signal handler, we are entering + * it from the original stack, not from any of the alternate + * signal stacks. + * + * On some architectures, this is broken. Those that appear to + * get this right are: + * + * aarch64 + * alpha + * arm + * i386 + * m68k + * or1k + * powerpc + * powerpc64 + * riscv + * vax + * x86_64 + */ +#if defined __hppa__ || \ + defined __ia64__ || defined __mips__ || \ + defined __sparc__ || defined __sparc64__ + if (nentries > 0) + atf_tc_expect_fail("PR lib/57946"); +#endif + for (ssp = &ss[0]; ssp < &ss[__arraycount(ss)]; ssp++) { + ATF_REQUIRE_MSG((sp < ssp->ss_sp || + sp >= (void *)((char *)ssp->ss_sp + ssp->ss_size)), + "%s failed to restore stack" + " before allowing signal on entry %u --" + " interrupted stack pointer %p lies in sigaltstack %zd" + " [%p, %p), size 0x%zx", + bailname, + nentries, + sp, ssp - ss, + ssp->ss_sp, (char *)ssp->ss_sp + ssp->ss_size, + ssp->ss_size); + } + + /* + * First time through, we want to test whether longjmp restores + * the signal mask first, or restores the stack pointer first. + * The signal should be blocked at this point, so we re-raise + * the signal to queue it up for delivery as soon as it is + * unmasked -- which should wait until the stack pointer has + * been restored in longjmp. + */ + if (nentries++ == 0) + RL(raise(SIGUSR1)); + + /* + * Set up the next sigaltstack. We can't reuse the current one + * for the next signal handler re-entry until the system clears + * the SS_ONSTACK process state -- which normal return from + * signal handler does, but which longjmp does not. So to keep + * it simple (ha), we just use another sigaltstack. + */ + RL(sigaltstack(&ss[nentries], NULL)); + + /* + * Jump back to the original context. + */ + (*bailfn)(); +} + +static void +go(const char *name, void (*fn)(void) __dead) +{ + struct sigaction sa; + unsigned i; + + bailname = name; + bailfn = fn; + + /* + * Allocate a stack for the signal handler to run in, and + * configure the system to use the first one. + * + * XXX Should maybe use a guard page but this is simpler. + */ + for (i = 0; i < __arraycount(ss); i++) { + ss[i].ss_size = SIGSTKSZ; + REQUIRE_LIBC(ss[i].ss_sp = malloc(ss[i].ss_size), NULL); + } + RL(sigaltstack(&ss[0], NULL)); + + /* + * Set up a test signal handler for SIGUSR1. Allow all + * signals, except SIGUSR1 (which is masked by default) -- that + * way we don't inadvertently obscure weird crashes in the + * signal handler. + * + * Set SA_SIGINFO so the system will pass siginfo -- and, more + * to the point, ucontext, so the signal handler can determine + * the stack pointer of the logic it interrupted. + * + * Set SA_ONSTACK so the system will use the alternate signal + * stack to call the signal handler -- that way, it can tell + * whether the stack was restored before the second time + * around. + */ + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = &on_sigusr1; + RL(sigemptyset(&sa.sa_mask)); + sa.sa_flags = SA_SIGINFO|SA_ONSTACK; + RL(sigaction(SIGUSR1, &sa, NULL)); + + /* + * Raise the signal to enter the signal handler the first time. + */ + RL(raise(SIGUSR1)); + + /* + * If we ever reach this point, something went seriously wrong. + */ + atf_tc_fail("unreachable"); +} + +static void __dead +bail_longjmp(void) +{ + + longjmp(jmp, 1); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test longjmp restores stack first, then signal mask"); +} +ATF_TC_BODY(setjmp, tc) +{ + + /* + * Set up a return point for the signal handler: when the + * signal handler does longjmp(jmp, 1), it comes flying out of + * here. + */ + if (setjmp(jmp) == 1) + return; + + /* + * Run the test with longjmp. + */ + go("longjmp", &bail_longjmp); +} + +static void __dead +bail_siglongjmp(void) +{ + + siglongjmp(sigjmp, 1); +} + +ATF_TC(sigsetjmp); +ATF_TC_HEAD(sigsetjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test siglongjmp restores stack first, then signal mask"); +} +ATF_TC_BODY(sigsetjmp, tc) +{ + + /* + * Set up a return point for the signal handler: when the + * signal handler does siglongjmp(sigjmp, 1), it comes flying + * out of here. + */ + if (sigsetjmp(sigjmp, /*savesigmask*/1) == 1) + return; + + /* + * Run the test with siglongjmp. + */ + go("siglongjmp", &bail_siglongjmp); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp); + + return atf_no_error(); +}