diff --git a/lib/libc/arch/i386/gen/setjmp.S b/lib/libc/arch/i386/gen/setjmp.S index 0bc6ce0e8ed3..8116ba5ec9e3 100644 --- a/lib/libc/arch/i386/gen/setjmp.S +++ b/lib/libc/arch/i386/gen/setjmp.S @@ -1,4 +1,4 @@ -/* $NetBSD: setjmp.S,v 1.17 2014/05/23 03:05:56 uebayasi Exp $ */ +/* $NetBSD: setjmp.S,v 1.18 2024/04/04 00:46:41 riastradh Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -36,7 +36,7 @@ #include #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.18 2024/04/04 00:46:41 riastradh 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 signal mask. */ - movl 4(%esp),%ecx - leal 24(%ecx),%edx - - PIC_PROLOGUE - pushl $0 - pushl %edx - pushl $3 /* SIG_SETMASK */ -#ifdef __PIC__ - call PIC_PLT(_C_LABEL(__sigprocmask14)) -#else - call _C_LABEL(__sigprocmask14) -#endif - addl $12,%esp - PIC_EPILOGUE - - movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx + /* + * 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 - testl %eax,%eax - jnz 1f - incl %eax -1: movl %ecx,0(%esp) - ret + movl %ecx,0(%esp) /* restore return address */ + + /* Restore the signal mask. */ + leal 24(%edx),%edx + + pushl %eax /* save val@eax */ + + PIC_PROLOGUE + 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 /* pop sigprocmask args */ + PIC_EPILOGUE + + 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) diff --git a/lib/libc/arch/i386/gen/sigsetjmp.S b/lib/libc/arch/i386/gen/sigsetjmp.S index 25924de52fc7..dca8f98ed1d7 100644 --- a/lib/libc/arch/i386/gen/sigsetjmp.S +++ b/lib/libc/arch/i386/gen/sigsetjmp.S @@ -1,4 +1,4 @@ -/* $NetBSD: sigsetjmp.S,v 1.18 2014/05/23 02:34:19 uebayasi Exp $ */ +/* $NetBSD: sigsetjmp.S,v 1.19 2024/04/04 00:46:41 riastradh Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -36,76 +36,104 @@ #include #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.19 2024/04/04 00:46:41 riastradh 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) - /* Check to see if we need to restore the signal mask. */ - movl 4(%esp),%ecx - cmpl $0,40(%ecx) - jz 2f /* no, skip */ - - /* Restore the signal mask. */ - leal 24(%ecx),%edx - - PIC_PROLOGUE - pushl $0 - pushl %edx - pushl $3 /* SIG_SETMASK */ -#ifdef __PIC__ - call PIC_PLT(_C_LABEL(__sigprocmask14)) -#else - call _C_LABEL(__sigprocmask14) -#endif - addl $12,%esp - PIC_EPILOGUE - -2: movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx + /* + * 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 - testl %eax,%eax - jnz 3f - incl %eax -3: movl %ecx,0(%esp) - ret + movl %ecx,0(%esp) /* restore return address */ + + /* Check to see if we need to restore the signal mask. */ + cmpl $0,40(%edx) /* savemask == 0 */ + jz 2f /* jump if savemask == 0 */ + + /* Restore the signal mask. */ + leal 24(%edx),%edx + + pushl %eax /* save val@eax */ + + PIC_PROLOGUE + 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 /* pop sigprocmask args */ + PIC_EPILOGUE + + 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) diff --git a/tests/lib/libc/setjmp/t_sigstack.c b/tests/lib/libc/setjmp/t_sigstack.c index 513def9d8066..7d2f3487bb88 100644 --- a/tests/lib/libc/setjmp/t_sigstack.c +++ b/tests/lib/libc/setjmp/t_sigstack.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_sigstack.c,v 1.8 2024/04/04 00:46:30 riastradh Exp $ */ +/* $NetBSD: t_sigstack.c,v 1.9 2024/04/04 00:46:42 riastradh Exp $ */ /*- * Copyright (c) 2024 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ */ #include -__RCSID("$NetBSD: t_sigstack.c,v 1.8 2024/04/04 00:46:30 riastradh Exp $"); +__RCSID("$NetBSD: t_sigstack.c,v 1.9 2024/04/04 00:46:42 riastradh Exp $"); #include #include @@ -81,10 +81,18 @@ on_sigusr1(int signo, siginfo_t *si, void *ctx) * On some architectures, this is broken. Those that appear to * get this right are: * - * aarch64, alpha, m68k, or1k, powerpc, powerpc64, riscv, - * vax, x86_64 + * aarch64 + * alpha + * i386 + * m68k + * or1k + * powerpc + * powerpc64 + * riscv + * vax + * x86_64 */ -#if defined __arm__ || defined __hppa__ || defined __i386__ || \ +#if defined __arm__ || defined __hppa__ || \ defined __ia64__ || defined __mips__ || defined __sh3__ || \ defined __sparc__ || defined __sparc64__ if (nentries > 0)