diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2024-02-20 14:45:29 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2024-02-21 00:26:11 +0000 |
commit | 8271d9b99a3b98c662ee9a6257a144284b7e1728 (patch) | |
tree | a6ebf1b86e90040a333790593c9b2752b5617090 /lib/libsys | |
parent | af9758deff9abb118ce189cbab0a830b02fc63db (diff) | |
download | src-8271d9b99a3b98c662ee9a6257a144284b7e1728.tar.gz src-8271d9b99a3b98c662ee9a6257a144284b7e1728.zip |
Diffstat (limited to 'lib/libsys')
-rw-r--r-- | lib/libsys/Makefile.sys | 1 | ||||
-rw-r--r-- | lib/libsys/_once_stub.c | 63 | ||||
-rw-r--r-- | lib/libsys/auxv.c | 20 |
3 files changed, 18 insertions, 66 deletions
diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys index cb9ca1749ba8..e33a11bacb57 100644 --- a/lib/libsys/Makefile.sys +++ b/lib/libsys/Makefile.sys @@ -33,7 +33,6 @@ PSEUDO+= _clock_gettime.o _gettimeofday.o SRCS+= \ __error.c \ __getosreldate.c \ - _once_stub.c \ getpagesize.c \ getpagesizes.c \ interposing_table.c diff --git a/lib/libsys/_once_stub.c b/lib/libsys/_once_stub.c deleted file mode 100644 index 518072cbd28f..000000000000 --- a/lib/libsys/_once_stub.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2009 Hudson River Trading LLC - * Written by: John H. Baldwin <jhb@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. 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 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. - */ - -#include "namespace.h" -#include <pthread.h> -#include "un-namespace.h" -#include "libc_private.h" - -/* This implements pthread_once() for the single-threaded case. */ -static int -_libc_once(pthread_once_t *once_control, void (*init_routine)(void)) -{ - - if (once_control->state == PTHREAD_DONE_INIT) - return (0); - init_routine(); - once_control->state = PTHREAD_DONE_INIT; - return (0); -} - -/* - * This is the internal interface provided to libc. It will use - * pthread_once() from the threading library in a multi-threaded - * process and _libc_once() for a single-threaded library. Because - * _libc_once() uses the same ABI for the values in the pthread_once_t - * structure as the threading library, it is safe for a process to - * switch from _libc_once() to pthread_once() when threading is - * enabled. - */ -int -_once(pthread_once_t *once_control, void (*init_routine)(void)) -{ - - if (__isthreaded) - return (_pthread_once(once_control, init_routine)); - return (_libc_once(once_control, init_routine)); -} diff --git a/lib/libsys/auxv.c b/lib/libsys/auxv.c index b0b3a8ed708b..88f49ef53be1 100644 --- a/lib/libsys/auxv.c +++ b/lib/libsys/auxv.c @@ -31,6 +31,7 @@ #include <errno.h> #include <link.h> #include <pthread.h> +#include <stdbool.h> #include <string.h> #include <sys/auxv.h> #include "un-namespace.h" @@ -40,6 +41,8 @@ extern int _DYNAMIC; #pragma weak _DYNAMIC void *__elf_aux_vector; + +#ifndef PIC static pthread_once_t aux_vector_once = PTHREAD_ONCE_INIT; static void @@ -61,8 +64,9 @@ __init_elf_aux_vector(void) return; _once(&aux_vector_once, init_aux_vector_once); } +#endif -static pthread_once_t aux_once = PTHREAD_ONCE_INIT; +static bool aux_once = false; static int pagesize, osreldate, canary_len, ncpus, pagesizes_len, bsdflags; static int hwcap_present, hwcap2_present; static char *canary, *pagesizes, *execpath; @@ -77,11 +81,19 @@ static void _init_aux_powerpc_fixup(void); int _powerpc_elf_aux_info(int, void *, int); #endif +/* + * This function might be called and actual body executed more than + * once in multithreading environment. Due to this, it is and must + * continue to be idempotent. All stores are atomic (no store + * tearing), because we only assign to int/long/ptr. + */ static void init_aux(void) { Elf_Auxinfo *aux; + if (aux_once) + return; for (aux = __elf_aux_vector; aux->a_type != AT_NULL; aux++) { switch (aux->a_type) { case AT_BSDFLAGS: @@ -166,6 +178,8 @@ init_aux(void) if (!powerpc_new_auxv_format) _init_aux_powerpc_fixup(); #endif + + aux_once = true; } #ifdef __powerpc__ @@ -256,10 +270,12 @@ _elf_aux_info(int aux, void *buf, int buflen) { int res; +#ifndef PIC __init_elf_aux_vector(); +#endif if (__elf_aux_vector == NULL) return (ENOSYS); - _once(&aux_once, init_aux); + init_aux(); /* idempotent */ if (buflen < 0) return (EINVAL); |