diff options
46 files changed, 557 insertions, 129 deletions
diff --git a/lib/csu/crtbegin.c b/lib/csu/crtbegin.c index e1ffc16bb1b..2917bd38260 100644 --- a/lib/csu/crtbegin.c +++ b/lib/csu/crtbegin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crtbegin.c,v 1.18 2015/04/04 18:05:05 guenther Exp $ */ +/* $OpenBSD: crtbegin.c,v 1.19 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: crtbegin.c,v 1.1 1996/09/12 16:59:03 cgd Exp $ */ /* @@ -91,6 +91,19 @@ atexit(void (*fn)(void)) return (__cxa_atexit((void (*)(void *))fn, NULL, NULL)); } +/* + * Ditto for pthread_atfork() + */ +int _thread_atfork(void (*)(void), void (*)(void), void (*)(void), void *) + __attribute__((weak)); + +int +pthread_atfork(void (*prep)(void), void (*parent)(void), void (*child)(void)) +{ + return (_thread_atfork(prep, parent, child, NULL)); +} +asm(".weak pthread_atfork"); + static const init_f __CTOR_LIST__[1] __attribute__((section(".ctors"))) = { (void *)-1 }; /* XXX */ diff --git a/lib/csu/crtbeginS.c b/lib/csu/crtbeginS.c index 152bfa5ec79..f97d30f22b0 100644 --- a/lib/csu/crtbeginS.c +++ b/lib/csu/crtbeginS.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crtbeginS.c,v 1.15 2015/04/04 18:05:05 guenther Exp $ */ +/* $OpenBSD: crtbeginS.c,v 1.16 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: crtbegin.c,v 1.1 1996/09/12 16:59:03 cgd Exp $ */ /* @@ -80,6 +80,20 @@ atexit(void (*fn)(void)) } asm(".hidden atexit"); +/* + * Ditto for pthread_atfork() + */ +int _thread_atfork(void (*)(void), void (*)(void), void (*)(void), void *) + __attribute__((weak)); + +int +pthread_atfork(void (*prep)(void), void (*parent)(void), void (*child)(void)) +{ + return (_thread_atfork(prep, parent, child, &__dso_handle)); +} +/* hppa doesn't permit directives in first column, so space after newline */ +asm(".hidden pthread_atfork\n .weak pthread_atfork"); + static init_f __CTOR_LIST__[1] __attribute__((section(".ctors"))) = { (void *)-1 }; /* XXX */ diff --git a/lib/libc/arch/alpha/SYS.h b/lib/libc/arch/alpha/SYS.h index bc2ea4ca888..f1d15c6a501 100644 --- a/lib/libc/arch/alpha/SYS.h +++ b/lib/libc/arch/alpha/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.9 2002/10/06 23:23:18 art Exp $ */ +/* $OpenBSD: SYS.h,v 1.10 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: SYS.h,v 1.4 1996/10/17 03:03:53 cgd Exp $ */ /* @@ -90,6 +90,7 @@ __END(p,label); __SYSCALL_NOERROR(_thread_sys_,x) # define RSYSCALL(x) ALIAS(_thread_sys_,x) \ __RSYSCALL(_thread_sys_,x) +# define RSYSCALL_HIDDEN(x) __RSYSCALL(_thread_sys_,x) # define RSYSCALL_NOERROR(x) ALIAS(_thread_sys_,x) \ __RSYSCALL_NOERROR(_thread_sys_,x) # define PSEUDO(x,y) ALIAS(_thread_sys_,x) \ diff --git a/lib/libc/arch/alpha/sys/fork.S b/lib/libc/arch/alpha/sys/fork.S index d2509858586..59b96139585 100644 --- a/lib/libc/arch/alpha/sys/fork.S +++ b/lib/libc/arch/alpha/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.6 2015/03/31 04:32:01 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.7 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: fork.S,v 1.1 1995/02/10 17:50:34 cgd Exp $ */ /* @@ -30,4 +30,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/amd64/SYS.h b/lib/libc/arch/amd64/SYS.h index f5710a879c4..82eedd460fc 100644 --- a/lib/libc/arch/amd64/SYS.h +++ b/lib/libc/arch/amd64/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.9 2014/06/04 20:13:49 matthew Exp $ */ +/* $OpenBSD: SYS.h,v 1.10 2015/04/07 01:27:06 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -40,10 +40,13 @@ #define SYSTRAP(x) movl $(SYS_ ## x),%eax; movq %rcx, %r10; syscall + #define SYSENTRY(x) \ ENTRY(_thread_sys_ ## x); \ .weak _C_LABEL(x); \ _C_LABEL(x) = _C_LABEL(_thread_sys_ ## x) +#define SYSENTRY_HIDDEN(x) \ + ENTRY(_thread_sys_ ## x) \ #define CERROR _C_LABEL(__cerror) #define _CERROR _C_LABEL(___cerror) @@ -52,6 +55,9 @@ #define _SYSCALL_NOERROR(x,y) \ SYSENTRY(x); \ SYSTRAP(y) +#define _SYSCALL_HIDDEN_NOERROR(x,y) \ + SYSENTRY_HIDDEN(x); \ + SYSTRAP(y) #ifdef __PIC__ #define _SYSCALL(x,y) \ @@ -60,12 +66,23 @@ jmp *%rcx; \ _SYSCALL_NOERROR(x,y); \ jc 2b +#define _SYSCALL_HIDDEN(x,y) \ + .text; _ALIGN_TEXT; \ + 2: mov PIC_GOT(CERROR), %rcx; \ + jmp *%rcx; \ + _SYSCALL_HIDDEN_NOERROR(x,y); \ + jc 2b #else #define _SYSCALL(x,y) \ .text; _ALIGN_TEXT; \ 2: jmp CERROR; \ _SYSCALL_NOERROR(x,y); \ jc 2b +#define _SYSCALL_HIDDEN(x,y) \ + .text; _ALIGN_TEXT; \ + 2: jmp CERROR; \ + _SYSCALL_HIDDEN_NOERROR(x,y); \ + jc 2b #endif #define SYSCALL_NOERROR(x) \ @@ -81,15 +98,16 @@ #define PSEUDO(x,y) \ _SYSCALL(x,y); \ ret +#define PSEUDO_HIDDEN(x,y) \ + _SYSCALL_HIDDEN(x,y); \ + ret #define RSYSCALL_NOERROR(x) \ PSEUDO_NOERROR(x,x) #define RSYSCALL(x) \ PSEUDO(x,x) - -#define WSYSCALL(weak,strong) \ - WEAK_ALIAS(weak,strong); \ - PSEUDO(strong,weak) +#define RSYSCALL_HIDDEN(x) \ + PSEUDO_HIDDEN(x,x) .globl CERROR diff --git a/lib/libc/arch/amd64/sys/fork.S b/lib/libc/arch/amd64/sys/fork.S index d0a2ea33178..6582d8a9a32 100644 --- a/lib/libc/arch/amd64/sys/fork.S +++ b/lib/libc/arch/amd64/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:01 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: fork.S,v 1.2 2003/02/13 02:50:51 nathanw Exp $ */ /*- @@ -39,4 +39,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/arm/SYS.h b/lib/libc/arch/arm/SYS.h index c6cfdbc4fcd..2fb7c3a91ba 100644 --- a/lib/libc/arch/arm/SYS.h +++ b/lib/libc/arch/arm/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.8 2015/03/31 12:31:19 jsing Exp $ */ +/* $OpenBSD: SYS.h,v 1.9 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: SYS.h,v 1.8 2003/08/07 16:42:02 agc Exp $ */ /*- @@ -42,6 +42,8 @@ .weak _C_LABEL(x); \ _C_LABEL(x) = _C_LABEL(_thread_sys_ ## x); \ ENTRY(_thread_sys_ ## x) +#define SYSENTRY_HIDDEN(x) \ + ENTRY(_thread_sys_ ## x) #define SYSTRAP(x) \ ldr r12, =SYS_ ## x; \ @@ -54,10 +56,16 @@ #define _SYSCALL_NOERROR(x,y) \ SYSENTRY(x); \ SYSTRAP(y) +#define _SYSCALL_HIDDEN_NOERROR(x,y) \ + SYSENTRY_HIDDEN(x); \ + SYSTRAP(y) #define _SYSCALL(x, y) \ _SYSCALL_NOERROR(x,y); \ bcs PIC_SYM(CERROR, PLT) +#define _SYSCALL_HIDDEN(x, y) \ + _SYSCALL_HIDDEN_NOERROR(x,y); \ + bcs PIC_SYM(CERROR, PLT) #define SYSCALL_NOERROR(x) \ _SYSCALL_NOERROR(x,x) @@ -73,6 +81,9 @@ #define PSEUDO(x,y) \ _SYSCALL(x,y); \ mov r15, r14 +#define PSEUDO_HIDDEN(x,y) \ + _SYSCALL_HIDDEN(x,y); \ + mov r15, r14 #define RSYSCALL_NOERROR(x) \ @@ -80,5 +91,7 @@ #define RSYSCALL(x) \ PSEUDO(x,x) +#define RSYSCALL_HIDDEN(x) \ + PSEUDO_HIDDEN(x,x) .globl CERROR diff --git a/lib/libc/arch/arm/sys/fork.S b/lib/libc/arch/arm/sys/fork.S index 9836d80a975..8d92b286369 100644 --- a/lib/libc/arch/arm/sys/fork.S +++ b/lib/libc/arch/arm/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:01 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:06 guenther Exp $ */ /* $NetBSD: fork.S,v 1.5 2003/08/07 16:42:04 agc Exp $ */ /*- @@ -34,4 +34,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/hppa/SYS.h b/lib/libc/arch/hppa/SYS.h index 2c1f6a8e9e1..a2dbef50244 100644 --- a/lib/libc/arch/hppa/SYS.h +++ b/lib/libc/arch/hppa/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.16 2010/10/01 05:02:19 guenther Exp $ */ +/* $OpenBSD: SYS.h,v 1.17 2015/04/07 01:27:06 guenther Exp $ */ /* * Copyright (c) 1998-2002 Michael Shalayeff @@ -36,6 +36,8 @@ #define SYSENTRY(x) !\ LEAF_ENTRY(__CONCAT(_thread_sys_,x)) !\ WEAK_ALIAS(x,__CONCAT(_thread_sys_,x)) +#define SYSENTRY_HIDDEN(x) !\ +LEAF_ENTRY(__CONCAT(_thread_sys_,x)) #define SYSEXIT(x) !\ EXIT(__CONCAT(_thread_sys_,x)) @@ -54,6 +56,12 @@ SYSENTRY(x) !\ bv r0(rp) !\ nop !\ SYSEXIT(x) +#define PSEUDO_HIDDEN(x,y) !\ +SYSENTRY_HIDDEN(x) !\ + SYSCALL(y) !\ + bv r0(rp) !\ + nop !\ +SYSEXIT(x) #define PSEUDO_NOERROR(x,y) !\ SYSENTRY(x) !\ @@ -66,5 +74,6 @@ SYSENTRY(x) !\ nop !\ SYSEXIT(x) -#define RSYSCALL(x) PSEUDO(x,x) +#define RSYSCALL(x) PSEUDO(x,x) +#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x) diff --git a/lib/libc/arch/hppa/sys/fork.S b/lib/libc/arch/hppa/sys/fork.S index 6a4efd8f3de..8bb3bc545b9 100644 --- a/lib/libc/arch/hppa/sys/fork.S +++ b/lib/libc/arch/hppa/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.12 2015/03/31 04:32:01 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.13 2015/04/07 01:27:06 guenther Exp $ */ /* * Copyright (c) 1999 Michael Shalayeff @@ -28,4 +28,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/hppa64/SYS.h b/lib/libc/arch/hppa64/SYS.h index d60f389285d..510ab2c5fba 100644 --- a/lib/libc/arch/hppa64/SYS.h +++ b/lib/libc/arch/hppa64/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.6 2011/09/19 13:01:28 kettenis Exp $ */ +/* $OpenBSD: SYS.h,v 1.7 2015/04/07 01:27:06 guenther Exp $ */ /* * Copyright (c) 1998-2002 Michael Shalayeff @@ -36,6 +36,8 @@ #define SYSENTRY(x) !\ LEAF_ENTRY(__CONCAT(_thread_sys_,x)) !\ WEAK_ALIAS(x,__CONCAT(_thread_sys_,x)) +#define SYSENTRY_HIDDEN(x) !\ +LEAF_ENTRY(__CONCAT(_thread_sys_,x)) #define SYSEXIT(x) !\ EXIT(__CONCAT(_thread_sys_,x)) @@ -56,6 +58,12 @@ SYSENTRY(x) !\ bv %r0(%rp) !\ nop !\ SYSEXIT(x) +#define PSEUDO_HIDDEN(x,y) !\ +SYSENTRY_HIDDEN(x) !\ + SYSCALL(y) !\ + bv %r0(%rp) !\ + nop !\ +SYSEXIT(x) #define PSEUDO_NOERROR(x,y) !\ SYSENTRY(x) !\ @@ -69,5 +77,6 @@ SYSENTRY(x) !\ nop !\ SYSEXIT(x) -#define RSYSCALL(x) PSEUDO(x,x) +#define RSYSCALL(x) PSEUDO(x,x) +#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x) diff --git a/lib/libc/arch/hppa64/sys/fork.S b/lib/libc/arch/hppa64/sys/fork.S index ce870ec4024..7602c801601 100644 --- a/lib/libc/arch/hppa64/sys/fork.S +++ b/lib/libc/arch/hppa64/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.5 2015/03/31 04:32:01 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.6 2015/04/07 01:27:06 guenther Exp $ */ /* * Copyright (c) 1999 Michael Shalayeff @@ -28,4 +28,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/i386/SYS.h b/lib/libc/arch/i386/SYS.h index cc199d6bf3d..a6c1c852c03 100644 --- a/lib/libc/arch/i386/SYS.h +++ b/lib/libc/arch/i386/SYS.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: SYS.h,v 1.19 2014/06/04 20:13:49 matthew Exp $ + * $OpenBSD: SYS.h,v 1.20 2015/04/07 01:27:06 guenther Exp $ */ #include <machine/asm.h> @@ -49,6 +49,8 @@ ENTRY(_thread_sys_ ## x); \ .weak _C_LABEL(x); \ _C_LABEL(x) = _C_LABEL(_thread_sys_ ## x) +#define SYSENTRY_HIDDEN(x) \ + ENTRY(_thread_sys_ ## x) #define __DO_SYSCALL(x) \ movl $(SYS_ ## x),%eax; \ @@ -62,6 +64,9 @@ #define _SYSCALL_NOERROR(x,y) \ SYSENTRY(x); \ __DO_SYSCALL(y); +#define _SYSCALL_HIDDEN_NOERROR(x,y) \ + SYSENTRY_HIDDEN(x); \ + __DO_SYSCALL(y); #define SYSCALL_NOERROR(x) \ _SYSCALL_NOERROR(x,x) @@ -77,6 +82,15 @@ jmp *%ecx; \ _SYSCALL_NOERROR(x,y) \ jc 2b +#define _SYSCALL_HIDDEN(x,y) \ + .text; \ + .align 2; \ + 2: PIC_PROLOGUE; \ + movl PIC_GOT(CERROR), %ecx; \ + PIC_EPILOGUE; \ + jmp *%ecx; \ + _SYSCALL_HIDDEN_NOERROR(x,y) \ + jc 2b #else #define _SYSCALL(x,y) \ .text; \ @@ -85,6 +99,13 @@ jmp PIC_PLT(CERROR); \ _SYSCALL_NOERROR(x,y) \ jc 2b +#define _SYSCALL_HIDDEN(x,y) \ + .text; \ + .align 2; \ + 2: \ + jmp PIC_PLT(CERROR); \ + _SYSCALL_HIDDEN_NOERROR(x,y) \ + jc 2b #endif #define SYSCALL(x) \ @@ -99,9 +120,14 @@ #define PSEUDO(x,y) \ _SYSCALL(x,y); \ ret +#define PSEUDO_HIDDEN(x,y) \ + _SYSCALL_HIDDEN(x,y); \ + ret /* perform a syscall with the same name, set errno, return */ #define RSYSCALL(x) \ PSEUDO(x,x); +#define RSYSCALL_HIDDEN(x) \ + PSEUDO_HIDDEN(x,x) .globl CERROR diff --git a/lib/libc/arch/i386/sys/fork.S b/lib/libc/arch/i386/sys/fork.S index 205ae5942c1..1e750d3f0d6 100644 --- a/lib/libc/arch/i386/sys/fork.S +++ b/lib/libc/arch/i386/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.5 2015/03/31 04:32:01 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.6 2015/04/07 01:27:06 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -33,4 +33,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/m88k/SYS.h b/lib/libc/arch/m88k/SYS.h index 9d6de9d755e..70292c9d585 100644 --- a/lib/libc/arch/m88k/SYS.h +++ b/lib/libc/arch/m88k/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.18 2014/06/04 20:13:49 matthew Exp $*/ +/* $OpenBSD: SYS.h,v 1.19 2015/04/07 01:27:06 guenther Exp $*/ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -83,10 +83,16 @@ __ENTRY(p,x); \ __ALIAS(p,x); \ __DO_SYSCALL(y) +#define __SYSCALL_HIDDEN__NOERROR(p,x,y) \ + __ENTRY(p,x); \ + __DO_SYSCALL(y) #define __SYSCALL(p,x,y) \ __SYSCALL__NOERROR(p,x,y); \ br CERROR +#define __SYSCALL_HIDDEN(p,x,y) \ + __SYSCALL_HIDDEN__NOERROR(p,x,y); \ + br CERROR #define __PSEUDO_NOERROR(p,x,y) \ __SYSCALL__NOERROR(p,x,y); \ @@ -97,6 +103,10 @@ __SYSCALL(p,x,y); \ jmp %r1; \ __END(p,x) +#define __PSEUDO_HIDDEN(p,x,y) \ + __SYSCALL_HIDDEN(p,x,y); \ + jmp %r1; \ + __END(p,x) /* * System calls entry points are really named _thread_sys_{syscall}, @@ -105,6 +115,7 @@ */ #define SYSCALL(x) __SYSCALL(_thread_sys_,x,x) #define RSYSCALL(x) __PSEUDO(_thread_sys_,x,x) +#define RSYSCALL_HIDDEN(x) __PSEUDO_HIDDEN(_thread_sys_,x,x) #define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y) #define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y) #define SYSENTRY(x) __ENTRY(_thread_sys_,x); \ diff --git a/lib/libc/arch/m88k/sys/fork.S b/lib/libc/arch/m88k/sys/fork.S index 3c88e9f65d0..2c664f74fd2 100644 --- a/lib/libc/arch/m88k/sys/fork.S +++ b/lib/libc/arch/m88k/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.8 2013/09/08 18:01:56 miod Exp $ */ +/* $OpenBSD: fork.S,v 1.9 2015/04/07 01:27:06 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -35,4 +35,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/mips64/SYS.h b/lib/libc/arch/mips64/SYS.h index 885ca700cec..55926724eb9 100644 --- a/lib/libc/arch/mips64/SYS.h +++ b/lib/libc/arch/mips64/SYS.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: SYS.h,v 1.6 2014/06/04 20:13:49 matthew Exp $ + * $OpenBSD: SYS.h,v 1.7 2015/04/07 01:27:06 guenther Exp $ */ #include <sys/syscall.h> @@ -71,9 +71,24 @@ PTR_ADDU sp,32; \ jr t9; \ __END2(p,x) +#define __PSEUDO_HIDDEN(p,x,y) \ + LEAF(p ## x,32); \ + PTR_SUBU sp,32; \ + SETUP_GP64(16,__CLABEL2(p,x)); \ + __DO_SYSCALL(y); \ + bne a3,zero,err; \ + RESTORE_GP64; \ + PTR_ADDU sp,32; \ + j ra; \ + err: LA t9,CERROR; \ + RESTORE_GP64; \ + PTR_ADDU sp,32; \ + jr t9; \ + END(p ## x) #define RSYSCALL(x) __PSEUDO(_thread_sys_,x,x) +#define RSYSCALL_HIDDEN(x) __PSEUDO_HIDDEN(_thread_sys_,x,x) #define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y) #define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y) diff --git a/lib/libc/arch/mips64/sys/fork.S b/lib/libc/arch/mips64/sys/fork.S index 39aebd47385..be3b2851414 100644 --- a/lib/libc/arch/mips64/sys/fork.S +++ b/lib/libc/arch/mips64/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.6 2015/03/31 04:32:02 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.7 2015/04/07 01:27:06 guenther Exp $ */ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -33,4 +33,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/powerpc/SYS.h b/lib/libc/arch/powerpc/SYS.h index 218c49f5878..fdd4e8913e3 100644 --- a/lib/libc/arch/powerpc/SYS.h +++ b/lib/libc/arch/powerpc/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.15 2014/06/04 20:13:49 matthew Exp $ */ +/* $OpenBSD: SYS.h,v 1.16 2015/04/07 01:27:06 guenther Exp $ */ /*- * Copyright (c) 1994 * Andrew Cagney. All rights reserved. @@ -68,9 +68,11 @@ sc ; \ PSEUDO_NOERROR_SUFFIX -#define PSEUDO(x,y) ALIAS(_thread_sys_,x) \ - PSEUDO_PREFIX(_thread_sys_,x,y) ; \ +#define PSEUDO_HIDDEN(x,y) PSEUDO_PREFIX(_thread_sys_,x,y) ; \ sc ; \ PSEUDO_SUFFIX +#define PSEUDO(x,y) ALIAS(_thread_sys_,x) \ + PSEUDO_HIDDEN(x,y) #define RSYSCALL(x) PSEUDO(x,x) +#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x) diff --git a/lib/libc/arch/powerpc/sys/fork.S b/lib/libc/arch/powerpc/sys/fork.S index d07de61737b..ace55a4a4d1 100644 --- a/lib/libc/arch/powerpc/sys/fork.S +++ b/lib/libc/arch/powerpc/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.2 2002/10/07 04:47:12 drahn Exp $ */ +/* $OpenBSD: fork.S,v 1.3 2015/04/07 01:27:06 guenther Exp $ */ /* * Copyright (c) 1996 Dale Rahn @@ -29,4 +29,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/sh/SYS.h b/lib/libc/arch/sh/SYS.h index 4a9f22ac32c..468e265c947 100644 --- a/lib/libc/arch/sh/SYS.h +++ b/lib/libc/arch/sh/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.5 2014/06/04 20:13:49 matthew Exp $ */ +/* $OpenBSD: SYS.h,v 1.6 2015/04/07 01:27:06 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -40,6 +40,8 @@ #define SYSENTRY(x) \ WEAK_ALIAS(x,_thread_sys_ ## x); \ ENTRY(_thread_sys_ ## x) +#define SYSENTRY_HIDDEN(x) \ + ENTRY(_thread_sys_ ## x) #define SYSTRAP(x) \ mov.l 903f, r0; \ @@ -56,6 +58,9 @@ #define _SYSCALL_NOERROR(x,y) \ SYSENTRY(x); \ SYSTRAP(y) +#define _SYSCALL_HIDDEN_NOERROR(x,y) \ + SYSENTRY_HIDDEN(x); \ + SYSTRAP(y) #ifdef __PIC__ @@ -88,6 +93,11 @@ 911: JUMP_CERROR; \ _SYSCALL_NOERROR(x,y); \ bf 911b +#define _SYSCALL_HIDDEN(x,y) \ + .text; \ + 911: JUMP_CERROR; \ + _SYSCALL_HIDDEN_NOERROR(x,y); \ + bf 911b #define SYSCALL_NOERROR(x) \ _SYSCALL_NOERROR(x,x) @@ -105,10 +115,13 @@ rts; \ nop -#define RSYSCALL_NOERROR(x) \ - PSEUDO_NOERROR(x,x) +#define PSEUDO_HIDDEN(x,y) \ + _SYSCALL_HIDDEN(x,y); \ + rts; \ + nop -#define RSYSCALL(x) \ - PSEUDO(x,x) +#define RSYSCALL_NOERROR(x) PSEUDO_NOERROR(x,x) +#define RSYSCALL(x) PSEUDO(x,x) +#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x) .globl CERROR diff --git a/lib/libc/arch/sh/sys/fork.S b/lib/libc/arch/sh/sys/fork.S index cf552fd07b2..4ee5a0442df 100644 --- a/lib/libc/arch/sh/sys/fork.S +++ b/lib/libc/arch/sh/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:02 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:07 guenther Exp $ */ /* $NetBSD: fork.S,v 1.10 2006/01/06 05:11:29 uwe Exp $ */ /*- @@ -37,4 +37,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/sparc/SYS.h b/lib/libc/arch/sparc/SYS.h index f010285062d..729c386bfaa 100644 --- a/lib/libc/arch/sparc/SYS.h +++ b/lib/libc/arch/sparc/SYS.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: SYS.h,v 1.16 2014/06/04 20:13:49 matthew Exp $ + * $OpenBSD: SYS.h,v 1.17 2015/04/07 01:27:07 guenther Exp $ */ #include <machine/asm.h> @@ -39,7 +39,8 @@ #define _CAT(x,y) x##y -#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x ; x = _CAT(p,x) +#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x ; x = _CAT(p,x) +#define __ENTRY_HIDDEN(p,x) ENTRY(_CAT(p,x)) /* * ERROR branches to cerror. @@ -71,6 +72,8 @@ */ #define __SYSCALL(p,x) \ __ENTRY(p,x); mov _CAT(SYS_,x),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1: +#define __SYSCALL_HIDDEN(p,x) \ + __ENTRY_HIDDEN(p,x); mov _CAT(SYS_,x),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1: /* * RSYSCALL is used when the system call should just return. Here @@ -97,6 +100,7 @@ # define SYSCALL(x) __SYSCALL(_thread_sys_,x) # define RSYSCALL(x) __RSYSCALL(_thread_sys_,x) +# define RSYSCALL_HIDDEN(x) __RSYSCALL(_thread_sys_,x) # define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y) # define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y) # define SYSENTRY(x) __ENTRY(_thread_sys_,x) diff --git a/lib/libc/arch/sparc/sys/fork.S b/lib/libc/arch/sparc/sys/fork.S index 83916669e78..911fce204dd 100644 --- a/lib/libc/arch/sparc/sys/fork.S +++ b/lib/libc/arch/sparc/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.5 2015/03/31 04:32:02 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.6 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -34,4 +34,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/sparc64/SYS.h b/lib/libc/arch/sparc64/SYS.h index f47a4d47da7..3f934da0323 100644 --- a/lib/libc/arch/sparc64/SYS.h +++ b/lib/libc/arch/sparc64/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.11 2014/06/04 20:13:49 matthew Exp $ */ +/* $OpenBSD: SYS.h,v 1.12 2015/04/07 01:27:07 guenther Exp $ */ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -43,7 +43,8 @@ #define _CAT(x,y) x##y -#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x; x = _CAT(p,x) +#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x; x = _CAT(p,x) +#define __ENTRY_HIDDEN(p,x) ENTRY(_CAT(p,x)) /* * ERROR branches to cerror. This is done with a macro so that I can @@ -71,18 +72,26 @@ */ #define _SYSCALL(p,x,y) \ __ENTRY(p,x); mov _CAT(SYS_,y),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1: +#define _SYSCALL_HIDDEN(p,x,y) \ + __ENTRY_HIDDEN(p,x); mov _CAT(SYS_,y),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1: #define __SYSCALL(p,x) \ _SYSCALL(p,x,x) +#define __SYSCALL_HIDDEN(p,x) \ + _SYSCALL_HIDDEN(p,x,x) + /* * RSYSCALL is used when the system call should just return. Here * we use the SYSCALL_G2RFLAG to put the `success' return address in %g2 * and avoid a branch. */ #define __RSYSCALL(p,x) \ - __ENTRY(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; add %o7,8,%g2; \ - t ST_SYSCALL; ERROR() + __ENTRY(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; \ + add %o7,8,%g2; t ST_SYSCALL; ERROR() +#define __RSYSCALL_HIDDEN(p,x) \ + __ENTRY_HIDDEN(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; \ + add %o7,8,%g2; t ST_SYSCALL; ERROR() /* * PSEUDO(x,y) is like RSYSCALL(y) except that the name is x. @@ -126,6 +135,7 @@ #define SYSCALL(x) __SYSCALL(_thread_sys_,x) #define RSYSCALL(x) __RSYSCALL(_thread_sys_,x) +#define RSYSCALL_HIDDEN(x) __RSYSCALL_HIDDEN(_thread_sys_,x) #define RSYSCALL_NOERROR(x,y) __RSYSCALL_NOERROR(_thread_sys_,x,y) #define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y) #define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y) diff --git a/lib/libc/arch/sparc64/sys/fork.S b/lib/libc/arch/sparc64/sys/fork.S index ffb32b62ad0..f432448d4ad 100644 --- a/lib/libc/arch/sparc64/sys/fork.S +++ b/lib/libc/arch/sparc64/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:02 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 1992, 1993 @@ -37,4 +37,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/arch/vax/SYS.h b/lib/libc/arch/vax/SYS.h index 816c700f2ff..2449243f186 100644 --- a/lib/libc/arch/vax/SYS.h +++ b/lib/libc/arch/vax/SYS.h @@ -1,4 +1,4 @@ -/* $OpenBSD: SYS.h,v 1.16 2014/06/04 20:13:49 matthew Exp $ */ +/* $OpenBSD: SYS.h,v 1.17 2015/04/07 01:27:07 guenther Exp $ */ /* $NetBSD: SYS.h,v 1.4 1997/05/02 18:15:32 kleink Exp $ */ /* @@ -66,6 +66,7 @@ __SYSCALL(_thread_sys_,x,x) #define RSYSCALL(x) __ALIAS(_thread_sys_,x) \ __PSEUDO(_thread_sys_,x,x) +#define RSYSCALL_HIDDEN(x) __PSEUDO(_thread_sys_,x,x) #define PSEUDO(x,y) __ALIAS(_thread_sys_,x) \ __PSEUDO(_thread_sys_,x,y) #define PSEUDO_NOERROR(x,y) __ALIAS(_thread_sys_,x) \ diff --git a/lib/libc/arch/vax/sys/fork.S b/lib/libc/arch/vax/sys/fork.S index 9204b5af8b2..4848c1e21ec 100644 --- a/lib/libc/arch/vax/sys/fork.S +++ b/lib/libc/arch/vax/sys/fork.S @@ -1,4 +1,4 @@ -/* $OpenBSD: fork.S,v 1.6 2015/03/31 04:32:02 guenther Exp $ */ +/* $OpenBSD: fork.S,v 1.7 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. @@ -30,4 +30,5 @@ #include "SYS.h" -RSYSCALL(fork) +RSYSCALL_HIDDEN(fork) +WEAK_ALIAS(_thread_fork,_thread_sys_fork) diff --git a/lib/libc/include/atfork.h b/lib/libc/include/atfork.h new file mode 100644 index 00000000000..8ec611098c1 --- /dev/null +++ b/lib/libc/include/atfork.h @@ -0,0 +1,44 @@ +/* $OpenBSD: atfork.h,v 1.1 2015/04/07 01:27:07 guenther Exp $ */ + +/* + * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org> + * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org> + * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $ + */ + +#include <sys/queue.h> + +struct atfork_fn { + TAILQ_ENTRY(atfork_fn) fn_next; + void (*fn_prepare)(void); + void (*fn_parent)(void); + void (*fn_child)(void); + void *fn_dso; +}; + +extern TAILQ_HEAD(atfork_listhead, atfork_fn) _atfork_list; + diff --git a/lib/libc/include/thread_private.h b/lib/libc/include/thread_private.h index 673fb9c6a69..43ebf7d96e8 100644 --- a/lib/libc/include/thread_private.h +++ b/lib/libc/include/thread_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: thread_private.h,v 1.25 2011/10/16 06:29:56 guenther Exp $ */ +/* $OpenBSD: thread_private.h,v 1.26 2015/04/07 01:27:07 guenther Exp $ */ /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ @@ -160,6 +160,18 @@ void _thread_atexit_unlock(void); _thread_atexit_unlock();\ } while (0) +void _thread_atfork_lock(void); +void _thread_atfork_unlock(void); + +#define _ATFORK_LOCK() do { \ + if (__isthreaded) \ + _thread_atfork_lock(); \ + } while (0) +#define _ATFORK_UNLOCK() do { \ + if (__isthreaded) \ + _thread_atfork_unlock();\ + } while (0) + void _thread_arc4_lock(void); void _thread_arc4_unlock(void); @@ -172,4 +184,9 @@ void _thread_arc4_unlock(void); _thread_arc4_unlock();\ } while (0) +/* + * Wrapper for _thread_sys_fork() + */ +pid_t _thread_fork(void); + #endif /* _THREAD_PRIVATE_H_ */ diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 72264f2e9ce..add7e4a9c1c 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ -major=78 -minor=1 +major=79 +minor=0 # note: If changes were made to include/thread_private.h or if system # calls were added/changed then librthread/shlib_version also be updated. diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c index 6532b382eab..a33080571fe 100644 --- a/lib/libc/stdlib/atexit.c +++ b/lib/libc/stdlib/atexit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atexit.c,v 1.20 2014/07/11 09:51:37 kettenis Exp $ */ +/* $OpenBSD: atexit.c,v 1.21 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 2002 Daniel Hartmeier * All rights reserved. @@ -35,6 +35,7 @@ #include <string.h> #include <unistd.h> #include "atexit.h" +#include "atfork.h" #include "thread_private.h" struct atexit *__atexit; @@ -161,6 +162,23 @@ restart: __atexit = NULL; } _ATEXIT_UNLOCK(); + + /* + * If unloading a DSO, unregister any atfork handlers registered + * by it. Skip the locking if the list is currently empty. + */ + if (dso != NULL && TAILQ_FIRST(&_atfork_list) != NULL) { + struct atfork_fn *af, *afnext; + + _ATFORK_LOCK(); + TAILQ_FOREACH_SAFE(af, &_atfork_list, fn_next, afnext) + if (af->fn_dso == dso) { + TAILQ_REMOVE(&_atfork_list, af, fn_next); + free(af); + } + _ATFORK_UNLOCK(); + + } } /* diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 6cf739c5530..ee9b8ff6737 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.124 2014/12/08 20:56:11 guenther Exp $ +# $OpenBSD: Makefile.inc,v 1.125 2015/04/07 01:27:07 guenther Exp $ # $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $ # @(#)Makefile.inc 8.1 (Berkeley) 6/17/93 @@ -11,7 +11,7 @@ SRCS+= Ovfork.S brk.S cerror.S exect.S fork.S \ sigsuspend.S syscall.S tfork_thread.S # glue to offer userland wrappers for some syscalls -SRCS+= posix_madvise.c +SRCS+= posix_madvise.c w_fork.c # glue to provide compatibility between GCC 1.X and 2.X and for compat # with old syscall interfaces. diff --git a/lib/libc/sys/w_fork.c b/lib/libc/sys/w_fork.c new file mode 100644 index 00000000000..1c6080e0cbd --- /dev/null +++ b/lib/libc/sys/w_fork.c @@ -0,0 +1,74 @@ +/* $OpenBSD: w_fork.c,v 1.1 2015/04/07 01:27:07 guenther Exp $ */ + +/* + * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org> + * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org> + * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $ + */ + +#include <unistd.h> +#include "thread_private.h" +#include "atfork.h" + +/* define and initialize the list */ +struct atfork_listhead _atfork_list = TAILQ_HEAD_INITIALIZER(_atfork_list); + +pid_t _thread_fork(void); + +pid_t +fork(void) +{ + struct atfork_fn *p; + pid_t newid; + + /* + * In the common case the list is empty; remain async-signal-safe + * then by skipping the locking and just forking + */ + if (TAILQ_FIRST(&_atfork_list) == NULL) + return (_thread_fork()); + + _ATFORK_LOCK(); + TAILQ_FOREACH_REVERSE(p, &_atfork_list, atfork_listhead, fn_next) + if (p->fn_prepare) + p->fn_prepare(); + + newid = _thread_fork(); + + if (newid == 0) { + TAILQ_FOREACH(p, &_atfork_list, fn_next) + if (p->fn_child) + p->fn_child(); + } else { + TAILQ_FOREACH(p, &_atfork_list, fn_next) + if (p->fn_parent) + p->fn_parent(); + } + _ATFORK_UNLOCK(); + + return (newid); +} diff --git a/lib/libc/thread/Makefile.inc b/lib/libc/thread/Makefile.inc index 248e6ede8cf..b5d3cb147dc 100644 --- a/lib/libc/thread/Makefile.inc +++ b/lib/libc/thread/Makefile.inc @@ -1,5 +1,5 @@ -# $OpenBSD: Makefile.inc,v 1.8 2014/07/16 20:02:17 okan Exp $ +# $OpenBSD: Makefile.inc,v 1.9 2015/04/07 01:27:07 guenther Exp $ .PATH: ${LIBCSRCDIR}/thread -SRCS+= unithread_malloc_lock.c unithread_mutex.c unithread_tag.c +SRCS+= unithread_malloc_lock.c unithread_mutex.c unithread_tag.c atfork.c diff --git a/lib/libc/thread/atfork.c b/lib/libc/thread/atfork.c new file mode 100644 index 00000000000..e4ae398df5a --- /dev/null +++ b/lib/libc/thread/atfork.c @@ -0,0 +1,56 @@ +/* $OpenBSD: atfork.c,v 1.1 2015/04/07 01:27:07 guenther Exp $ */ + +/* + * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org> + * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org> + * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $ + */ + +#include <errno.h> +#include <stdlib.h> + +#include "thread_private.h" +#include "atfork.h" + +int +_thread_atfork(void (*prepare)(void), void (*parent)(void), + void (*child)(void), void *dso) +{ + struct atfork_fn *af; + + if ((af = malloc(sizeof *af)) == NULL) + return (ENOMEM); + + af->fn_prepare = prepare; + af->fn_parent = parent; + af->fn_child = child; + af->fn_dso = dso; + _ATFORK_LOCK(); + TAILQ_INSERT_TAIL(&_atfork_list, af, fn_next); + _ATFORK_UNLOCK(); + return (0); +} diff --git a/lib/libc/thread/unithread_malloc_lock.c b/lib/libc/thread/unithread_malloc_lock.c index 920250139b8..d813bc708f2 100644 --- a/lib/libc/thread/unithread_malloc_lock.c +++ b/lib/libc/thread/unithread_malloc_lock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: unithread_malloc_lock.c,v 1.8 2008/06/13 21:18:43 otto Exp $ */ +/* $OpenBSD: unithread_malloc_lock.c,v 1.9 2015/04/07 01:27:07 guenther Exp $ */ #include <sys/time.h> #include "thread_private.h" @@ -15,6 +15,12 @@ WEAK_PROTOTYPE(_thread_atexit_unlock); WEAK_ALIAS(_thread_atexit_lock); WEAK_ALIAS(_thread_atexit_unlock); +WEAK_PROTOTYPE(_thread_atfork_lock); +WEAK_PROTOTYPE(_thread_atfork_unlock); + +WEAK_ALIAS(_thread_atfork_lock); +WEAK_ALIAS(_thread_atfork_unlock); + WEAK_PROTOTYPE(_thread_arc4_lock); WEAK_PROTOTYPE(_thread_arc4_unlock); @@ -46,6 +52,18 @@ WEAK_NAME(_thread_atexit_unlock)(void) } void +WEAK_NAME(_thread_atfork_lock)(void) +{ + return; +} + +void +WEAK_NAME(_thread_atfork_unlock)(void) +{ + return; +} + +void WEAK_NAME(_thread_arc4_lock)(void) { return; diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index 632308ef5db..688f438a27b 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.79 2014/11/16 05:26:20 guenther Exp $ */ +/* $OpenBSD: rthread.c,v 1.80 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -736,6 +736,8 @@ static void *__libc_overrides[] __used = { &_thread_arc4_unlock, &_thread_atexit_lock, &_thread_atexit_unlock, + &_thread_atfork_lock, + &_thread_atfork_unlock, &_thread_malloc_lock, &_thread_malloc_unlock, &_thread_mutex_destroy, diff --git a/lib/librthread/rthread_fork.c b/lib/librthread/rthread_fork.c index cb76421d2a1..c9086daf595 100644 --- a/lib/librthread/rthread_fork.c +++ b/lib/librthread/rthread_fork.c @@ -1,8 +1,8 @@ -/* $OpenBSD: rthread_fork.c,v 1.10 2013/11/29 16:27:40 guenther Exp $ */ +/* $OpenBSD: rthread_fork.c,v 1.11 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org> - * Copyright (c) 2008 Philip Guenther <guenther@gmail.com> + * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org> * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> * All rights reserved. * @@ -46,18 +46,6 @@ #include "rthread.h" -struct rthread_atfork { - TAILQ_ENTRY(rthread_atfork) next; - void (*prepare)(void); - void (*parent)(void); - void (*child)(void); -}; - -static TAILQ_HEAD(atfork_listhead, rthread_atfork) _atfork_list = - TAILQ_HEAD_INITIALIZER(_atfork_list); - -static struct _spinlock _atfork_lock = _SPINLOCK_UNLOCKED; - pid_t _thread_sys_fork(void); pid_t _thread_sys_vfork(void); pid_t _dofork(int); @@ -144,27 +132,9 @@ _dofork(int is_vfork) } pid_t -fork(void) +_thread_fork(void) { - struct rthread_atfork *p; - pid_t newid; - - _spinlock(&_atfork_lock); - TAILQ_FOREACH_REVERSE(p, &_atfork_list, atfork_listhead, next) - if (p->prepare) - p->prepare(); - newid = _dofork(0); - if (newid == 0) { - TAILQ_FOREACH(p, &_atfork_list, next) - if (p->child) - p->child(); - } else { - TAILQ_FOREACH(p, &_atfork_list, next) - if (p->parent) - p->parent(); - } - _spinunlock(&_atfork_lock); - return newid; + return _dofork(0); } pid_t @@ -172,21 +142,3 @@ vfork(void) { return _dofork(1); } - -int -pthread_atfork(void (*prepare)(void), void (*parent)(void), - void (*child)(void)) -{ - struct rthread_atfork *af; - - if ((af = malloc(sizeof *af)) == NULL) - return (ENOMEM); - - af->prepare = prepare; - af->parent = parent; - af->child = child; - _spinlock(&_atfork_lock); - TAILQ_INSERT_TAIL(&_atfork_list, af, next); - _spinunlock(&_atfork_lock); - return (0); -} diff --git a/lib/librthread/rthread_libc.c b/lib/librthread/rthread_libc.c index 13df27c498e..018368a84dd 100644 --- a/lib/librthread/rthread_libc.c +++ b/lib/librthread/rthread_libc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_libc.c,v 1.11 2013/06/01 20:47:40 tedu Exp $ */ +/* $OpenBSD: rthread_libc.c,v 1.12 2015/04/07 01:27:07 guenther Exp $ */ /* $snafu: libc_tag.c,v 1.4 2004/11/30 07:00:06 marc Exp $ */ /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ @@ -184,6 +184,23 @@ _thread_atexit_unlock(void) } /* + * atfork lock + */ +static struct _spinlock atfork_lock = _SPINLOCK_UNLOCKED; + +void +_thread_atfork_lock(void) +{ + _spinlock(&atfork_lock); +} + +void +_thread_atfork_unlock(void) +{ + _spinunlock(&atfork_lock); +} + +/* * arc4random lock */ static struct _spinlock arc4_lock = _SPINLOCK_UNLOCKED; diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version index 7c92aff4893..0aab0406bf8 100644 --- a/lib/librthread/shlib_version +++ b/lib/librthread/shlib_version @@ -1,2 +1,2 @@ -major=18 -minor=1 +major=19 +minor=0 diff --git a/regress/lib/csu/callbacks/Makefile b/regress/lib/csu/callbacks/Makefile index 48474134a56..b74854fb45c 100644 --- a/regress/lib/csu/callbacks/Makefile +++ b/regress/lib/csu/callbacks/Makefile @@ -1,7 +1,6 @@ -# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ +# $OpenBSD: Makefile,v 1.2 2015/04/07 01:27:07 guenther Exp $ -SUBDIR+= libaa libab atexit -# not yet: pthread_atfork +SUBDIR+= libaa libab atexit pthread_atfork install: diff --git a/regress/lib/csu/callbacks/pthread_atfork/Makefile b/regress/lib/csu/callbacks/pthread_atfork/Makefile index 8e685447d7b..ecefb366a9b 100644 --- a/regress/lib/csu/callbacks/pthread_atfork/Makefile +++ b/regress/lib/csu/callbacks/pthread_atfork/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $ +# $OpenBSD: Makefile,v 1.2 2015/04/07 01:27:07 guenther Exp $ .include <bsd.obj.mk> @@ -31,7 +31,7 @@ NOMAN= CLEANFILES= parent_out child_out -TESTS= 0 +TESTS= 0 1 2 3 regress-pthread_atfork: ${PROG} for i in ${TESTS}; do \ diff --git a/regress/lib/csu/callbacks/pthread_atfork/expected_child.out b/regress/lib/csu/callbacks/pthread_atfork/expected_child.out new file mode 100644 index 00000000000..345d837c844 --- /dev/null +++ b/regress/lib/csu/callbacks/pthread_atfork/expected_child.out @@ -0,0 +1,20 @@ +testp atfork1_child +libaa atfork_child +testp atfork2_child +libab atfork_child +testp atfork3_child +finished 0 + +testp atfork1_child +testp atfork2_child +testp atfork3_child +finished 1 + +testp atfork1_child +testp atfork3_child +finished 2 + +testp atfork1_child +testp atfork2_child +finished 3 + diff --git a/regress/lib/csu/callbacks/pthread_atfork/expected_parent.out b/regress/lib/csu/callbacks/pthread_atfork/expected_parent.out new file mode 100644 index 00000000000..18cdc22e663 --- /dev/null +++ b/regress/lib/csu/callbacks/pthread_atfork/expected_parent.out @@ -0,0 +1,37 @@ +testp atfork3_prepare +libab atfork_prepare +testp atfork2_prepare +libaa atfork_prepare +testp atfork1_prepare +testp atfork1_parent +libaa atfork_parent +testp atfork2_parent +libab atfork_parent +testp atfork3_parent +finished 0 + +testp atfork3_prepare +testp atfork2_prepare +testp atfork1_prepare +testp atfork1_parent +testp atfork2_parent +testp atfork3_parent +finished 1 + +testp atfork3_prepare +libab atfork_prepare +exe atfork_dlclose begin +exe atfork_dlclose end +testp atfork1_prepare +testp atfork1_parent +testp atfork3_parent +finished 2 + +exe atfork_dlclose begin +exe atfork_dlclose end +testp atfork2_prepare +testp atfork1_prepare +testp atfork1_parent +testp atfork2_parent +finished 3 + diff --git a/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c b/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c index c6a93a0e080..225e5f1f1af 100644 --- a/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c +++ b/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pthread_atfork_test.c,v 1.1 2014/11/23 08:46:49 guenther Exp $ */ +/* $OpenBSD: pthread_atfork_test.c,v 1.2 2015/04/07 01:27:07 guenther Exp $ */ /* * Copyright (c) 2014 Philip Guenther <guenther@openbsd.org> @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <sys/wait.h> #include <dlfcn.h> #include <err.h> #include <pthread.h> @@ -86,7 +87,7 @@ int main(int argc, char **argv) { pid_t pid; - int test; + int test, status; otherf = fdopen(3, "w"); if (otherf == NULL) @@ -150,5 +151,6 @@ main(int argc, char **argv) fflush(otherf); pid = fork(); + waitpid(pid, &status, 0); return (0); } |