aboutsummaryrefslogtreecommitdiff
path: root/lib/libsys
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2024-02-20 14:45:29 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2024-02-21 00:26:11 +0000
commit8271d9b99a3b98c662ee9a6257a144284b7e1728 (patch)
treea6ebf1b86e90040a333790593c9b2752b5617090 /lib/libsys
parentaf9758deff9abb118ce189cbab0a830b02fc63db (diff)
downloadsrc-8271d9b99a3b98c662ee9a6257a144284b7e1728.tar.gz
src-8271d9b99a3b98c662ee9a6257a144284b7e1728.zip
Diffstat (limited to 'lib/libsys')
-rw-r--r--lib/libsys/Makefile.sys1
-rw-r--r--lib/libsys/_once_stub.c63
-rw-r--r--lib/libsys/auxv.c20
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);