aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile3
-rw-r--r--elf/Versions8
-rw-r--r--elf/dl-catch.c (renamed from elf/dl-error-skeleton.c)154
-rw-r--r--elf/dl-error-minimal.c23
-rw-r--r--elf/dl-error.c27
-rw-r--r--elf/rtld.c2
6 files changed, 79 insertions, 138 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 5f7d222bb1..eca7b28ab5 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -34,7 +34,6 @@ routines = \
dl-addr \
dl-addr-obj \
dl-early_allocate \
- dl-error \
dl-iteratephdr \
dl-libc \
dl-origin \
@@ -54,6 +53,7 @@ routines = \
dl-routines = \
dl-call-libc-early-init \
dl-call_fini \
+ dl-catch \
dl-close \
dl-debug \
dl-debug-symbols \
@@ -134,7 +134,6 @@ rtld-routines = \
dl-diagnostics-cpu \
dl-diagnostics-kernel \
dl-environ \
- dl-error-minimal \
dl-hwcaps \
dl-hwcaps-subdirs \
dl-hwcaps_split \
diff --git a/elf/Versions b/elf/Versions
index a9ff278de7..4614acea3e 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -31,10 +31,6 @@ libc {
GLIBC_PRIVATE {
# functions used in other libraries
__libc_early_init;
-
- # Internal error handling support. Interposes the functions in ld.so.
- _dl_signal_exception; _dl_catch_exception;
- _dl_signal_error; _dl_catch_error;
}
}
@@ -77,10 +73,8 @@ ld {
# Internal error handling support.
_dl_exception_create; _dl_exception_create_format; _dl_exception_free;
-
- # Internal error handling support. Interposed by libc.so.
_dl_signal_exception; _dl_catch_exception;
- _dl_signal_error; _dl_catch_error;
+ _dl_signal_error;
# Set value of a tunable.
__tunable_get_val;
diff --git a/elf/dl-error-skeleton.c b/elf/dl-catch.c
index 8abf437f87..54763dd34e 100644
--- a/elf/dl-error-skeleton.c
+++ b/elf/dl-catch.c
@@ -1,4 +1,4 @@
-/* Template for error handling for runtime dynamic linker.
+/* Exception handling in the dynamic linker.
Copyright (C) 1995-2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,16 +16,6 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-/* The following macro needs to be defined before including this
- skeleton file:
-
- DL_ERROR_BOOTSTRAP
-
- If 1, do not use TLS and implement _dl_signal_cerror and
- _dl_receive_error. If 0, TLS is used, and the variants with
- error callbacks are not provided. */
-
-
#include <libintl.h>
#include <setjmp.h>
#include <stdbool.h>
@@ -34,39 +24,54 @@
#include <unistd.h>
#include <ldsodefs.h>
#include <stdio.h>
+#include <tls.h>
/* This structure communicates state between _dl_catch_error and
_dl_signal_error. */
-struct catch
+struct rtld_catch
{
struct dl_exception *exception; /* The exception data is stored there. */
volatile int *errcode; /* Return value of _dl_signal_error. */
jmp_buf env; /* longjmp here on error. */
};
-/* Multiple threads at once can use the `_dl_catch_error' function. The
- calls can come from `_dl_map_object_deps', `_dlerror_run', or from
- any of the libc functionality which loads dynamic objects (NSS, iconv).
- Therefore we have to be prepared to save the state in thread-local
- memory. */
-#if !DL_ERROR_BOOTSTRAP
-static __thread struct catch *catch_hook attribute_tls_model_ie;
-#else
-/* The version of this code in ld.so cannot use thread-local variables
- and is used during bootstrap only. */
-static struct catch *catch_hook;
+/* Multiple threads at once can use the `_dl_catch_error' function.
+ The calls can come from `_dl_map_object_deps', `_dlerror_run', or
+ from any of the libc functionality which loads dynamic objects
+ (NSS, iconv). Therefore we have to be prepared to save the state
+ in thread-local memory. We use THREAD_GETMEM and THREAD_SETMEM
+ instead of ELF TLS because ELF TLS is not available in the dynamic
+ loader. Additionally, the exception handling mechanism must be
+ usable before the TCB has been set up, which is why
+ rtld_catch_notls is used if !__rtld_tls_init_tp_called. This is
+ not needed for static builds, where initialization completes before
+ static dlopen etc. can be called. */
+
+#if IS_IN (rtld)
+static struct rtld_catch *rtld_catch_notls;
#endif
-#if DL_ERROR_BOOTSTRAP
-/* This points to a function which is called when an continuable error is
- received. Unlike the handling of `catch' this function may return.
- The arguments will be the `errstring' and `objname'.
+static struct rtld_catch *
+get_catch (void)
+{
+#if IS_IN (rtld)
+ if (!__rtld_tls_init_tp_called)
+ return rtld_catch_notls;
+ else
+#endif
+ return THREAD_GETMEM (THREAD_SELF, rtld_catch);
+}
- Since this functionality is not used in normal programs (only in ld.so)
- we do not care about multi-threaded programs here. We keep this as a
- global variable. */
-static receiver_fct receiver;
-#endif /* DL_ERROR_BOOTSTRAP */
+static void
+set_catch (struct rtld_catch *catch)
+{
+#if IS_IN (rtld)
+ if (!__rtld_tls_init_tp_called)
+ rtld_catch_notls = catch;
+ else
+#endif
+ THREAD_SETMEM (THREAD_SELF, rtld_catch, catch);
+}
/* Lossage while resolving the program's own symbols is always fatal. */
static void
@@ -89,7 +94,7 @@ void
_dl_signal_exception (int errcode, struct dl_exception *exception,
const char *occasion)
{
- struct catch *lcatch = catch_hook;
+ struct rtld_catch *lcatch = get_catch ();
if (lcatch != NULL)
{
*lcatch->exception = *exception;
@@ -101,13 +106,13 @@ _dl_signal_exception (int errcode, struct dl_exception *exception,
else
fatal_error (errcode, exception->objname, occasion, exception->errstring);
}
-libc_hidden_def (_dl_signal_exception)
+rtld_hidden_def (_dl_signal_exception)
void
_dl_signal_error (int errcode, const char *objname, const char *occation,
const char *errstring)
{
- struct catch *lcatch = catch_hook;
+ struct rtld_catch *lcatch = get_catch ();
if (! errstring)
errstring = N_("DYNAMIC LINKER BUG!!!");
@@ -123,10 +128,18 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
else
fatal_error (errcode, objname, occation, errstring);
}
-libc_hidden_def (_dl_signal_error)
+rtld_hidden_def (_dl_signal_error)
+
+#if IS_IN (rtld)
+/* This points to a function which is called when a continuable error is
+ received. Unlike the handling of `catch' this function may return.
+ The arguments will be the `errstring' and `objname'.
+ Since this functionality is not used in normal programs (only in ld.so)
+ we do not care about multi-threaded programs here. We keep this as a
+ global variable. */
+static receiver_fct receiver;
-#if DL_ERROR_BOOTSTRAP
void
_dl_signal_cexception (int errcode, struct dl_exception *exception,
const char *occasion)
@@ -167,7 +180,23 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
else
_dl_signal_error (errcode, objname, occation, errstring);
}
-#endif /* DL_ERROR_BOOTSTRAP */
+
+void
+_dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
+{
+ struct rtld_catch *old_catch = get_catch ();
+ receiver_fct old_receiver = receiver;
+
+ /* Set the new values. */
+ set_catch (NULL);
+ receiver = fct;
+
+ (*operate) (args);
+
+ set_catch (old_catch);
+ receiver = old_receiver;
+}
+#endif
int
_dl_catch_exception (struct dl_exception *exception,
@@ -177,11 +206,11 @@ _dl_catch_exception (struct dl_exception *exception,
Exceptions during operate (args) are fatal. */
if (exception == NULL)
{
- struct catch *const old = catch_hook;
- catch_hook = NULL;
+ struct rtld_catch *old_catch = get_catch ();
+ set_catch (NULL);
operate (args);
/* If we get here, the operation was successful. */
- catch_hook = old;
+ set_catch (old_catch);
return 0;
}
@@ -194,19 +223,19 @@ _dl_catch_exception (struct dl_exception *exception,
in _dl_signal_error (before longjmp). */
volatile int errcode;
- struct catch c;
+ struct rtld_catch c;
/* Don't use an initializer since we don't need to clear C.env. */
c.exception = exception;
c.errcode = &errcode;
- struct catch *const old = catch_hook;
- catch_hook = &c;
+ struct rtld_catch *old = get_catch ();
+ set_catch (&c);
/* Do not save the signal mask. */
if (__builtin_expect (__sigsetjmp (c.env, 0), 0) == 0)
{
(*operate) (args);
- catch_hook = old;
+ set_catch (old);
*exception = (struct dl_exception) { NULL };
return 0;
}
@@ -214,10 +243,10 @@ _dl_catch_exception (struct dl_exception *exception,
/* We get here only if we longjmp'd out of OPERATE.
_dl_signal_exception has already stored values into
*EXCEPTION. */
- catch_hook = old;
+ set_catch (old);
return errcode;
}
-libc_hidden_def (_dl_catch_exception)
+rtld_hidden_def (_dl_catch_exception)
int
_dl_catch_error (const char **objname, const char **errstring,
@@ -230,34 +259,3 @@ _dl_catch_error (const char **objname, const char **errstring,
*mallocedp = exception.message_buffer == exception.errstring;
return errorcode;
}
-libc_hidden_def (_dl_catch_error)
-
-#if DL_ERROR_BOOTSTRAP
-void
-_dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
-{
- struct catch *old_catch = catch_hook;
- receiver_fct old_receiver = receiver;
-
- /* Set the new values. */
- catch_hook = NULL;
- receiver = fct;
-
- (*operate) (args);
-
- catch_hook = old_catch;
- receiver = old_receiver;
-}
-
-/* Forwarder used for initializing GLRO (_dl_catch_error). */
-int
-_rtld_catch_error (const char **objname, const char **errstring,
- bool *mallocedp, void (*operate) (void *),
- void *args)
-{
- /* The reference to _dl_catch_error will eventually be relocated to
- point to the implementation in libc.so. */
- return _dl_catch_error (objname, errstring, mallocedp, operate, args);
-}
-
-#endif /* DL_ERROR_BOOTSTRAP */
diff --git a/elf/dl-error-minimal.c b/elf/dl-error-minimal.c
deleted file mode 100644
index 9b833b90c0..0000000000
--- a/elf/dl-error-minimal.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Error handling for runtime dynamic linker, minimal version.
- Copyright (C) 1995-2022 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-/* This version does lives in ld.so, does not use thread-local data
- and supports _dl_signal_cerror and _dl_receive_error. */
-
-#define DL_ERROR_BOOTSTRAP 1
-#include "dl-error-skeleton.c"
diff --git a/elf/dl-error.c b/elf/dl-error.c
deleted file mode 100644
index 0b7332a84f..0000000000
--- a/elf/dl-error.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Error handling for runtime dynamic linker, full version.
- Copyright (C) 1995-2022 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-/* This implementation lives in libc.so because it uses thread-local
- data, which is not available in ld.so. It interposes the version
- in dl-error-minimal.c after ld.so bootstrap.
-
- The signal/catch mechanism is used by the audit framework, which
- means that even in ld.so, not all errors are fatal. */
-
-#define DL_ERROR_BOOTSTRAP 0
-#include "dl-error-skeleton.c"
diff --git a/elf/rtld.c b/elf/rtld.c
index 221be5c71e..8671594f1f 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -370,7 +370,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
._dl_lookup_symbol_x = _dl_lookup_symbol_x,
._dl_open = _dl_open,
._dl_close = _dl_close,
- ._dl_catch_error = _rtld_catch_error,
+ ._dl_catch_error = _dl_catch_error,
._dl_error_free = _dl_error_free,
._dl_tls_get_addr_soft = _dl_tls_get_addr_soft,
._dl_libc_freeres = __rtld_libc_freeres,