GNU C Library master sources branch master updated. glibc-2.24-427-g9e78f6f
fw@sourceware.org
fw@sourceware.org
Wed Nov 30 15:00:00 GMT 2016
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, master has been updated
via 9e78f6f6e7134a5f299cc8de77370218f8019237 (commit)
from 705a79f82560ff6472cebed86aa5db04cdea3bce (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9e78f6f6e7134a5f299cc8de77370218f8019237
commit 9e78f6f6e7134a5f299cc8de77370218f8019237
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Nov 30 15:59:57 2016 +0100
Implement _dl_catch_error, _dl_signal_error in libc.so [BZ #16628]
This change moves the main implementation of _dl_catch_error,
_dl_signal_error to libc.so, where TLS variables can be used
directly. This removes a writable function pointer from the
rtld_global variable.
For use during initial relocation, minimal implementations of these
functions are provided in ld.so. These are eventually interposed
by the libc.so implementations. This is implemented by compiling
elf/dl-error-skeleton.c twice, via elf/dl-error.c and
elf/dl-error-minimal.c.
As a side effect of this change, the static version of dl-error.c
no longer includes support for the
_dl_signal_cerror/_dl_receive_error mechanism because it is only
used in ld.so.
diff --git a/ChangeLog b/ChangeLog
index c2cb608..d017478 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,83 @@
2016-11-30 Florian Weimer <fweimer@redhat.com>
+ [BZ #16628]
+ Implement _dl_catch_error, _dl_signal_error in libc.so.
+ * elf/dl-error-skeleton.c: Rename from elf/dl-error.c.
+ (catch_hook): Define as thread-local or regular variable,
+ depending on DL_ERROR_BOOTSTRAP.
+ (CATCH_HOOK): Remove.
+ (dl_signal_error, _dl_catch_error): Use
+ catch_hook. Add hidden definition for libc.
+ (_dl_receive_error, _dl_signal_cerror): Use catch_hook. Compile
+ for DL_ERROR_BOOTSTRAP only.
+ * elf/dl-error.c: New file.
+ * elf/dl-error-minimal.c: Likewise.
+ * elf/tst-latepthread.c: Likewise.
+ * elf/tst-latepthreadmod.c: Likewise.
+ * elf/Makefile (routines): Add dl-error.
+ (dl-routines): Remove dl-error.
+ (rtld-routines): Add dl-error-minimal.
+ [build-shared] (tests): Add tst-latepthread.
+ (module-names): Add tst-latepthreadmod.
+ (LDFLAGS-tst-latepthreadmod.so): Enable lazy binding to undefined
+ symbol.
+ (tst-latepthreadmod.so): Link against libpthread.
+ (tst-latepthread): Link against libdbl.
+ * elf/Versions [libc] (GLIBC_PRIVATE): Add _dl_signal_error,
+ _dl_catch_error.
+ [ld] (GLIBC_PRIVATE): Likewise.
+ * elf/dl-close.c (_dl_cose): Call _dl_signal_error directly.
+ * elf/dl-libc.c (dlerror_run): Call _dl_catch_error directly.
+ * elf/dl-sym.c (do_sym): Call _dl_signal_error, _dl_catch_error
+ directly.
+ * elf/dl-tsd.c: Remove file.
+ * elf/rtld.c (_rtld_global_ro): Remove initializers for
+ _dl_catch_error, _dl_signal_error.
+ (_dl_initial_error_catch_tsd): Remove definition.
+ (do_preload): Remove initialization of dl_error_catch_tsd.
+ * dlfcn/dlerror.c (_dlerror_run): Call _dl_catch_error directly.
+ * dlfcn/dlinfo.c (dlinfo_doit): Call _dl_signal_error directly.
+ * dlfcn/dlmopen.c (dlmopen_doit): Likewise.
+ * dlfcn/dlopen.c (dlopen_doit): Likewise.
+ * nptl/nptl-init.c (__pthread_initialize_minimal_internal): Do not
+ set dl_error_catch_tsd.
+ * sysdeps/generic/ldsodefs.h (struct rtld_global): Remove
+ _dl_error_catch_tsd member.
+ (struct rtld_global_ro): Remove _dl_catch_error, _dl_signal_error
+ members.
+ (_dl_initial_error_catch_tsd): Remove declaration.
+ (_dl_dprintf): Provide definition for use outside of ld.so.
+ [!rtld] (_dl_signal_cerror): Redirect to _dl_signal_error.
+ (_dl_signal_error, _dl_catch_error): Make public. Add hidden
+ prototype for libc.
+ * sysdeps/generic/localplt.data (ld.so): Add _dl_signal_error,
+ _dl_catch_error.
+ * sysdeps/unix/sysv/linux/aarch64/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/alpha/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/arm/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/hppa/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/i386/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/ia64/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/m68k/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/microblaze/localplt.data (ld.so):
+ Likewise.
+ * sysdeps/unix/sysv/linux/nios2/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
+ (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
+ (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data (ld.so):
+ Likewise.
+ * sysdeps/unix/sysv/linux/s390/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/sh/localplt.data (ld.so): Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data (ld.so):
+ Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data (ld.so):
+ Likewise.
+ * sysdeps/x86_64/localplt.data (ld.so): Likewise.
+
+2016-11-30 Florian Weimer <fweimer@redhat.com>
+
[BZ #4099]
* libio/filedoalloc.c (_IO_file_doallocate): Limit buffer size to
_IO_BUFSIZ (8192).
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 41b2bd6..e0e5648 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -160,8 +160,8 @@ _dlerror_run (void (*operate) (void *), void *args)
result->errstring = NULL;
}
- result->errcode = GLRO(dl_catch_error) (&result->objname, &result->errstring,
- &result->malloced, operate, args);
+ result->errcode = _dl_catch_error (&result->objname, &result->errstring,
+ &result->malloced, operate, args);
/* If no error we mark that no error string is available. */
result->returned = result->errstring == NULL;
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
index eeba8da..794e354 100644
--- a/dlfcn/dlinfo.c
+++ b/dlfcn/dlinfo.c
@@ -60,7 +60,7 @@ dlinfo_doit (void *argsblock)
break;
if (l == NULL)
- GLRO(dl_signal_error) (0, NULL, NULL, N_("\
+ _dl_signal_error (0, NULL, NULL, N_("\
RTLD_SELF used in code not dynamically loaded"));
}
# endif
@@ -69,7 +69,7 @@ RTLD_SELF used in code not dynamically loaded"));
{
case RTLD_DI_CONFIGADDR:
default:
- GLRO(dl_signal_error) (0, NULL, NULL, N_("unsupported dlinfo request"));
+ _dl_signal_error (0, NULL, NULL, N_("unsupported dlinfo request"));
break;
case RTLD_DI_LMID:
diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c
index 6da0d0d..4eed513 100644
--- a/dlfcn/dlmopen.c
+++ b/dlfcn/dlmopen.c
@@ -60,12 +60,12 @@ dlmopen_doit (void *a)
must be the main one. */
if (args->file == NULL)
# endif
- GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
+ _dl_signal_error (EINVAL, NULL, NULL, N_("invalid namespace"));
/* It makes no sense to use RTLD_GLOBAL when loading a DSO into
a namespace other than the base namespace. */
if (__glibc_unlikely (args->mode & RTLD_GLOBAL))
- GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid mode"));
+ _dl_signal_error (EINVAL, NULL, NULL, N_("invalid mode"));
}
args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
index 453efbd..5263fed 100644
--- a/dlfcn/dlopen.c
+++ b/dlfcn/dlopen.c
@@ -61,7 +61,7 @@ dlopen_doit (void *a)
if (args->mode & ~(RTLD_BINDING_MASK | RTLD_NOLOAD | RTLD_DEEPBIND
| RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE
| __RTLD_SPROF))
- GLRO(dl_signal_error) (0, NULL, NULL, _("invalid mode parameter"));
+ _dl_signal_error (0, NULL, NULL, _("invalid mode parameter"));
args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
args->caller,
diff --git a/elf/Makefile b/elf/Makefile
index 82c7e05..33b003b 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -24,12 +24,12 @@ include ../Makeconfig
headers = elf.h bits/elfclass.h link.h bits/link.h
routines = $(all-dl-routines) dl-support dl-iteratephdr \
dl-addr dl-addr-obj enbl-secure dl-profstub \
- dl-origin dl-libc dl-sym dl-tsd dl-sysdep
+ dl-origin dl-libc dl-sym dl-sysdep dl-error
# The core dynamic linking functions are in libc for the static and
# profiled libraries.
dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
- runtime error init fini debug misc \
+ runtime init fini debug misc \
version profile conflict tls origin scope \
execstack caller open close trampoline)
ifeq (yes,$(use-ldconfig))
@@ -43,7 +43,8 @@ shared-only-routines += dl-caller
# ld.so uses those routines, plus some special stuff for being the program
# interpreter and operating independent of libc.
-rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal
+rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \
+ dl-error-minimal
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
@@ -150,7 +151,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-nodelete) \
tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
- tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload
+ tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
+ tst-latepthread
# reldep9
ifeq ($(build-hardcoded-path-in-tests),yes)
tests += tst-dlopen-aout
@@ -224,7 +226,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-array5dep tst-null-argv-lib \
tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12
+ tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
+ tst-latepthreadmod
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
modules-names += tst-gnu2-tls1mod
@@ -1264,6 +1267,14 @@ tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so
$(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
+# Override -z defs, so that we can reference an undefined symbol.
+# Force lazy binding for the same reason.
+LDFLAGS-tst-latepthreadmod.so = \
+ -Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all
+$(objpfx)tst-latepthreadmod.so: $(shared-thread-library)
+$(objpfx)tst-latepthread: $(libdl)
+$(objpfx)tst-latepthread.out: $(objpfx)tst-latepthreadmod.so
+
tst-prelink-ENV = LD_TRACE_PRELINKING=1
$(objpfx)tst-prelink-conflict.out: $(objpfx)tst-prelink.out
diff --git a/elf/Versions b/elf/Versions
index 23deda9..05e5449 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -26,6 +26,9 @@ libc {
_dl_open_hook;
_dl_sym; _dl_vsym;
__libc_dlclose; __libc_dlopen_mode; __libc_dlsym;
+
+ # Internal error handling support. Interposes the functions in ld.so.
+ _dl_signal_error; _dl_catch_error;
}
}
@@ -64,5 +67,8 @@ ld {
# Pointer protection.
__pointer_chk_guard;
+
+ # Internal error handling support. Interposed by libc.so.
+ _dl_signal_error; _dl_catch_error;
}
}
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 687d7de..6489703 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -814,7 +814,7 @@ _dl_close (void *_map)
}
if (__builtin_expect (map->l_direct_opencount, 1) == 0)
- GLRO(dl_signal_error) (0, map->l_name, NULL, N_("shared object not open"));
+ _dl_signal_error (0, map->l_name, NULL, N_("shared object not open"));
/* Acquire the lock. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
diff --git a/elf/dl-error-minimal.c b/elf/dl-error-minimal.c
new file mode 100644
index 0000000..d535d65
--- /dev/null
+++ b/elf/dl-error-minimal.c
@@ -0,0 +1,23 @@
+/* Error handling for runtime dynamic linker, minimal version.
+ Copyright (C) 1995-2016 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
+ <http://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-skeleton.c
similarity index 85%
copy from elf/dl-error.c
copy to elf/dl-error-skeleton.c
index bd22ec6..beb31ae 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error-skeleton.c
@@ -1,4 +1,4 @@
-/* Error handling for runtime dynamic linker.
+/* Template for error handling for runtime dynamic linker.
Copyright (C) 1995-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,6 +16,16 @@
License along with the GNU C Library; if not, see
<http://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>
@@ -23,6 +33,7 @@
#include <string.h>
#include <unistd.h>
#include <ldsodefs.h>
+#include <stdio.h>
/* This structure communicates state between _dl_catch_error and
_dl_signal_error. */
@@ -40,16 +51,21 @@ struct catch
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. The _dl_error_catch_tsd function pointer is reset by the thread
- library so that it returns the address of a thread-local variable. */
-
+ 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;
+#endif
/* This message we return as a last resort. We define the string in a
variable since we have to avoid freeing it and so have to enable
a pointer comparison. See below and in dlfcn/dlerror.c. */
static const char _dl_out_of_memory[] = "out of memory";
-
+#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'.
@@ -58,25 +74,18 @@ static const char _dl_out_of_memory[] = "out of memory";
we do not care about multi-threaded programs here. We keep this as a
global variable. */
static receiver_fct receiver;
-
-#ifdef _LIBC_REENTRANT
-# define CATCH_HOOK (*(struct catch **) (*GL(dl_error_catch_tsd)) ())
-#else
-static struct catch *catch_hook;
-# define CATCH_HOOK catch_hook
-#endif
+#endif /* DL_ERROR_BOOTSTRAP */
void
internal_function
_dl_signal_error (int errcode, const char *objname, const char *occation,
const char *errstring)
{
- struct catch *lcatch;
+ struct catch *lcatch = catch_hook;
if (! errstring)
errstring = N_("DYNAMIC LINKER BUG!!!");
- lcatch = CATCH_HOOK;
if (objname == NULL)
objname = "";
if (lcatch != NULL)
@@ -132,8 +141,10 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
: ""));
}
}
+libc_hidden_def (_dl_signal_error)
+#if DL_ERROR_BOOTSTRAP
void
internal_function
_dl_signal_cerror (int errcode, const char *objname, const char *occation,
@@ -154,6 +165,7 @@ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
else
_dl_signal_error (errcode, objname, occation, errstring);
}
+#endif /* DL_ERROR_BOOTSTRAP */
int
@@ -177,15 +189,14 @@ _dl_catch_error (const char **objname, const char **errstring,
c.malloced = mallocedp;
c.errcode = &errcode;
- struct catch **const catchp = &CATCH_HOOK;
- struct catch *const old = *catchp;
- *catchp = &c;
+ struct catch *const old = catch_hook;
+ catch_hook = &c;
/* Do not save the signal mask. */
if (__builtin_expect (__sigsetjmp (c.env, 0), 0) == 0)
{
(*operate) (args);
- *catchp = old;
+ catch_hook = old;
*objname = NULL;
*errstring = NULL;
*mallocedp = false;
@@ -194,28 +205,26 @@ _dl_catch_error (const char **objname, const char **errstring,
/* We get here only if we longjmp'd out of OPERATE. _dl_signal_error has
already stored values into *OBJNAME, *ERRSTRING, and *MALLOCEDP. */
- *catchp = old;
+ catch_hook = old;
return errcode;
}
+libc_hidden_def (_dl_catch_error)
-
+#if DL_ERROR_BOOTSTRAP
void
internal_function
_dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
{
- struct catch **const catchp = &CATCH_HOOK;
- struct catch *old_catch;
- receiver_fct old_receiver;
-
- old_catch = *catchp;
- old_receiver = receiver;
+ struct catch *old_catch = catch_hook;
+ receiver_fct old_receiver = receiver;
/* Set the new values. */
- *catchp = NULL;
+ catch_hook = NULL;
receiver = fct;
(*operate) (args);
- *catchp = old_catch;
+ catch_hook = old_catch;
receiver = old_receiver;
}
+#endif /* DL_ERROR_BOOTSTRAP */
diff --git a/elf/dl-error.c b/elf/dl-error.c
index bd22ec6..7fe36b4 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -1,4 +1,4 @@
-/* Error handling for runtime dynamic linker.
+/* Error handling for runtime dynamic linker, full version.
Copyright (C) 1995-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,206 +16,12 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <libintl.h>
-#include <setjmp.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ldsodefs.h>
+/* 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.
-/* This structure communicates state between _dl_catch_error and
- _dl_signal_error. */
-struct catch
- {
- const char **objname; /* Object/File name. */
- const char **errstring; /* Error detail filled in here. */
- bool *malloced; /* Nonzero if the string is malloced
- by the libc malloc. */
- volatile int *errcode; /* Return value of _dl_signal_error. */
- jmp_buf env; /* longjmp here on error. */
- };
+ The signal/catch mechanism is used by the audit framework, which
+ means that even in ld.so, not all errors are fatal. */
-/* 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. The _dl_error_catch_tsd function pointer is reset by the thread
- library so that it returns the address of a thread-local variable. */
-
-
-/* This message we return as a last resort. We define the string in a
- variable since we have to avoid freeing it and so have to enable
- a pointer comparison. See below and in dlfcn/dlerror.c. */
-static const char _dl_out_of_memory[] = "out of memory";
-
-
-/* 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'.
-
- 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;
-
-#ifdef _LIBC_REENTRANT
-# define CATCH_HOOK (*(struct catch **) (*GL(dl_error_catch_tsd)) ())
-#else
-static struct catch *catch_hook;
-# define CATCH_HOOK catch_hook
-#endif
-
-void
-internal_function
-_dl_signal_error (int errcode, const char *objname, const char *occation,
- const char *errstring)
-{
- struct catch *lcatch;
-
- if (! errstring)
- errstring = N_("DYNAMIC LINKER BUG!!!");
-
- lcatch = CATCH_HOOK;
- if (objname == NULL)
- objname = "";
- if (lcatch != NULL)
- {
- /* We are inside _dl_catch_error. Return to it. We have to
- duplicate the error string since it might be allocated on the
- stack. The object name is always a string constant. */
- size_t len_objname = strlen (objname) + 1;
- size_t len_errstring = strlen (errstring) + 1;
-
- char *errstring_copy = malloc (len_objname + len_errstring);
- if (errstring_copy != NULL)
- {
- /* Make a copy of the object file name and the error string. */
- *lcatch->objname = memcpy (__mempcpy (errstring_copy,
- errstring, len_errstring),
- objname, len_objname);
- *lcatch->errstring = errstring_copy;
-
- /* If the main executable is relocated it means the libc's malloc
- is used. */
- bool malloced = true;
-#ifdef SHARED
- malloced = (GL(dl_ns)[LM_ID_BASE]._ns_loaded != NULL
- && (GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_relocated != 0));
-#endif
- *lcatch->malloced = malloced;
- }
- else
- {
- /* This is better than nothing. */
- *lcatch->objname = "";
- *lcatch->errstring = _dl_out_of_memory;
- *lcatch->malloced = false;
- }
-
- *lcatch->errcode = errcode;
-
- /* We do not restore the signal mask because none was saved. */
- __longjmp (lcatch->env[0].__jmpbuf, 1);
- }
- else
- {
- /* Lossage while resolving the program's own symbols is always fatal. */
- char buffer[1024];
- _dl_fatal_printf ("%s: %s: %s%s%s%s%s\n",
- RTLD_PROGNAME,
- occation ?: N_("error while loading shared libraries"),
- objname, *objname ? ": " : "",
- errstring, errcode ? ": " : "",
- (errcode
- ? __strerror_r (errcode, buffer, sizeof buffer)
- : ""));
- }
-}
-
-
-void
-internal_function
-_dl_signal_cerror (int errcode, const char *objname, const char *occation,
- const char *errstring)
-{
- if (__builtin_expect (GLRO(dl_debug_mask)
- & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
- _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
- errstring, receiver ? "continued" : "fatal");
-
- if (receiver)
- {
- /* We are inside _dl_receive_error. Call the user supplied
- handler and resume the work. The receiver will still be
- installed. */
- (*receiver) (errcode, objname, errstring);
- }
- else
- _dl_signal_error (errcode, objname, occation, errstring);
-}
-
-
-int
-internal_function
-_dl_catch_error (const char **objname, const char **errstring,
- bool *mallocedp, void (*operate) (void *), void *args)
-{
- /* We need not handle `receiver' since setting a `catch' is handled
- before it. */
-
- /* Only this needs to be marked volatile, because it is the only local
- variable that gets changed between the setjmp invocation and the
- longjmp call. All others are just set here (before setjmp) and read
- in _dl_signal_error (before longjmp). */
- volatile int errcode;
-
- struct catch c;
- /* Don't use an initializer since we don't need to clear C.env. */
- c.objname = objname;
- c.errstring = errstring;
- c.malloced = mallocedp;
- c.errcode = &errcode;
-
- struct catch **const catchp = &CATCH_HOOK;
- struct catch *const old = *catchp;
- *catchp = &c;
-
- /* Do not save the signal mask. */
- if (__builtin_expect (__sigsetjmp (c.env, 0), 0) == 0)
- {
- (*operate) (args);
- *catchp = old;
- *objname = NULL;
- *errstring = NULL;
- *mallocedp = false;
- return 0;
- }
-
- /* We get here only if we longjmp'd out of OPERATE. _dl_signal_error has
- already stored values into *OBJNAME, *ERRSTRING, and *MALLOCEDP. */
- *catchp = old;
- return errcode;
-}
-
-
-void
-internal_function
-_dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
-{
- struct catch **const catchp = &CATCH_HOOK;
- struct catch *old_catch;
- receiver_fct old_receiver;
-
- old_catch = *catchp;
- old_receiver = receiver;
-
- /* Set the new values. */
- *catchp = NULL;
- receiver = fct;
-
- (*operate) (args);
-
- *catchp = old_catch;
- receiver = old_receiver;
-}
+#define DL_ERROR_BOOTSTRAP 0
+#include "dl-error-skeleton.c"
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index d56de1a..dde44c8 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -43,8 +43,8 @@ dlerror_run (void (*operate) (void *), void *args)
const char *last_errstring = NULL;
bool malloced;
- int result = (GLRO(dl_catch_error) (&objname, &last_errstring, &malloced,
- operate, args)
+ int result = (_dl_catch_error (&objname, &last_errstring, &malloced,
+ operate, args)
?: last_errstring != NULL);
if (result && malloced)
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 6431c22..e00b286 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -123,8 +123,8 @@ do_sym (void *handle, const char *name, void *who,
const char *objname;
const char *errstring = NULL;
bool malloced;
- int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
- call_dl_lookup, &args);
+ int err = _dl_catch_error (&objname, &errstring, &malloced,
+ call_dl_lookup, &args);
THREAD_GSCOPE_RESET_FLAG ();
@@ -136,7 +136,7 @@ do_sym (void *handle, const char *name, void *who,
if (malloced)
free ((char *) errstring);
- GLRO(dl_signal_error) (err, objname_dup, NULL, errstring_dup);
+ _dl_signal_error (err, objname_dup, NULL, errstring_dup);
/* NOTREACHED */
}
@@ -150,7 +150,7 @@ do_sym (void *handle, const char *name, void *who,
if (match == NULL
|| caller < match->l_map_start
|| caller >= match->l_map_end)
- GLRO(dl_signal_error) (0, NULL, NULL, N_("\
+ _dl_signal_error (0, NULL, NULL, N_("\
RTLD_NEXT used in code not dynamically loaded"));
}
diff --git a/elf/dl-tsd.c b/elf/dl-tsd.c
deleted file mode 100644
index 7181e1c..0000000
--- a/elf/dl-tsd.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Thread-local data used by error handling for runtime dynamic linker.
- Copyright (C) 2002-2016 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
- <http://www.gnu.org/licenses/>. */
-
-#ifdef _LIBC_REENTRANT
-
-# include <ldsodefs.h>
-# include <tls.h>
-
-# ifndef SHARED
-
-/* _dl_error_catch_tsd points to this for the single-threaded case.
- It's reset by the thread library for multithreaded programs
- if we're not using __thread. */
-void ** __attribute__ ((const))
-_dl_initial_error_catch_tsd (void)
-{
- static __thread void *data;
- return &data;
-}
-void **(*_dl_error_catch_tsd) (void) __attribute__ ((const))
- = &_dl_initial_error_catch_tsd;
-
-# else
-
-/* libpthread sets _dl_error_catch_tsd to point to this function.
- We define it here instead of in libpthread so that it doesn't
- need to have a TLS segment of its own just for this one pointer. */
-
-void ** __attribute__ ((const))
-__libc_dl_error_tsd (void)
-{
- static __thread void *data attribute_tls_model_ie;
- return &data;
-}
-
-# endif /* SHARED */
-
-#endif /* _LIBC_REENTRANT */
diff --git a/elf/rtld.c b/elf/rtld.c
index 647661c..4ec25d7 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -167,8 +167,6 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
/* Function pointers. */
._dl_debug_printf = _dl_debug_printf,
- ._dl_catch_error = _dl_catch_error,
- ._dl_signal_error = _dl_signal_error,
._dl_mcount = _dl_mcount,
._dl_lookup_symbol_x = _dl_lookup_symbol_x,
._dl_check_caller = _dl_check_caller,
@@ -637,18 +635,6 @@ cannot allocate TLS data structures for initial thread");
return tcbp;
}
-#ifdef _LIBC_REENTRANT
-/* _dl_error_catch_tsd points to this for the single-threaded case.
- It's reset by the thread library for multithreaded programs. */
-void ** __attribute__ ((const))
-_dl_initial_error_catch_tsd (void)
-{
- static void *data;
- return &data;
-}
-#endif
-
-
static unsigned int
do_preload (const char *fname, struct link_map *main_map, const char *where)
{
@@ -752,11 +738,6 @@ dl_main (const ElfW(Phdr) *phdr,
#endif
void *tcbp = NULL;
-#ifdef _LIBC_REENTRANT
- /* Explicit initialization since the reloc would just be more work. */
- GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd;
-#endif
-
GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
#if defined SHARED && defined _LIBC_REENTRANT \
diff --git a/elf/tst-latepthread.c b/elf/tst-latepthread.c
new file mode 100644
index 0000000..9449ef6
--- /dev/null
+++ b/elf/tst-latepthread.c
@@ -0,0 +1,105 @@
+/* Test that loading libpthread does not break ld.so exceptions (bug 16628).
+ Copyright (C) 2016 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+ void *handle = dlopen ("tst-latepthreadmod.so", RTLD_LOCAL | RTLD_LAZY);
+ if (handle == NULL)
+ {
+ printf ("error: dlopen failed: %s\n", dlerror ());
+ return 1;
+ }
+ void *ptr = dlsym (handle, "trigger_dynlink_failure");
+ if (ptr == NULL)
+ {
+ printf ("error: dlsym failed: %s\n", dlerror ());
+ return 1;
+ }
+ int (*func) (void) = ptr;
+
+ /* Run the actual test in a subprocess, to capture the error. */
+ int fds[2];
+ if (pipe (fds) < 0)
+ {
+ printf ("error: pipe: %m\n");
+ return 1;
+ }
+ pid_t pid = fork ();
+ if (pid < 0)
+ {
+ printf ("error: fork: %m\n");
+ return 1;
+ }
+ else if (pid == 0)
+ {
+ if (dup2 (fds[1], STDERR_FILENO) < 0)
+ _exit (2);
+ /* Trigger an abort. */
+ func ();
+ _exit (3);
+ }
+ /* NB: This assumes that the abort message is so short that the pipe
+ does not block. */
+ int status;
+ if (waitpid (pid, &status, 0) < 0)
+ {
+ printf ("error: waitpid: %m\n");
+ return 1;
+ }
+
+ /* Check the printed error message. */
+ if (close (fds[1]) < 0)
+ {
+ printf ("error: close: %m\n");
+ return 1;
+ }
+ char buf[512];
+ /* Leave room for the NUL terminator. */
+ ssize_t ret = read (fds[0], buf, sizeof (buf) - 1);
+ if (ret < 0)
+ {
+ printf ("error: read: %m\n");
+ return 1;
+ }
+ if (ret > 0 && buf[ret - 1] == '\n')
+ --ret;
+ buf[ret] = '\0';
+ printf ("info: exit status: %d, message: %s\n", status, buf);
+ if (strstr (buf, "undefined symbol: this_function_is_not_defined") == NULL)
+ {
+ printf ("error: message does not contain expected string\n");
+ return 1;
+ }
+ if (!WIFEXITED (status) || WEXITSTATUS (status) != 127)
+ {
+ printf ("error: unexpected process exit status\n");
+ return 1;
+ }
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/elf/tst-latepthreadmod.c b/elf/tst-latepthreadmod.c
new file mode 100644
index 0000000..ce81206
--- /dev/null
+++ b/elf/tst-latepthreadmod.c
@@ -0,0 +1,33 @@
+/* DSO which links against libpthread and triggers a lazy binding.
+ Copyright (C) 2016 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
+ <http://www.gnu.org/licenses/>. */
+
+/* This file is compiled into a DSO which loads libpthread, but fails
+ the dynamic linker afterwards. */
+
+#include <pthread.h>
+
+/* Link in libpthread. */
+void *pthread_create_ptr = &pthread_create;
+
+int this_function_is_not_defined (void);
+
+int
+trigger_dynlink_failure (void)
+{
+ return this_function_is_not_defined ();
+}
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 48fab50..0fd54a0 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -456,10 +456,6 @@ __pthread_initialize_minimal_internal (void)
lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
#ifdef SHARED
- /* Transfer the old value from the dynamic linker's internal location. */
- *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
- GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
-
/* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
keep the lock count from the ld.so implementation. */
GL(dl_rtld_lock_recursive) = (void *) __pthread_mutex_lock;
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index f68fdf4..288f5fe 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -357,10 +357,6 @@ struct rtld_global
/* List of search directories. */
EXTERN struct r_search_path_elem *_dl_all_dirs;
-#ifdef _LIBC_REENTRANT
- EXTERN void **(*_dl_error_catch_tsd) (void) __attribute__ ((const));
-#endif
-
/* Structure describing the dynamic linker itself. We need to
reserve memory for the data the audit libraries need. */
EXTERN struct link_map _dl_rtld_map;
@@ -583,10 +579,6 @@ struct rtld_global_ro
PLT relocations in libc.so. */
void (*_dl_debug_printf) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
- int (internal_function *_dl_catch_error) (const char **, const char **,
- bool *, void (*) (void *), void *);
- void (internal_function *_dl_signal_error) (int, const char *, const char *,
- const char *);
void (*_dl_mcount) (ElfW(Addr) frompc, ElfW(Addr) selfpc);
lookup_t (internal_function *_dl_lookup_symbol_x) (const char *,
struct link_map *,
@@ -632,13 +624,6 @@ extern const ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
#endif
-#if IS_IN (rtld)
-/* This is the initial value of GL(dl_error_catch_tsd).
- A non-TLS libpthread will change it. */
-extern void **_dl_initial_error_catch_tsd (void) __attribute__ ((const))
- attribute_hidden;
-#endif
-
/* This is the initial value of GL(dl_make_stack_executable_hook).
A threads library can change it. */
extern int _dl_make_stack_executable (void **stack_endp) internal_function;
@@ -705,9 +690,20 @@ extern void _dl_debug_printf_c (const char *fmt, ...)
/* Write a message on the specified descriptor FD. The parameters are
interpreted as for a `printf' call. */
+#if IS_IN (rtld) || !defined (SHARED)
extern void _dl_dprintf (int fd, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)))
attribute_hidden;
+#else
+__attribute__ ((always_inline, __format__ (__printf__, 2, 3)))
+static inline void
+_dl_dprintf (int fd, const char *fmt, ...)
+{
+ /* Use local declaration to avoid includign <stdio.h>. */
+ extern int __dprintf(int fd, const char *format, ...) attribute_hidden;
+ __dprintf (fd, fmt, __builtin_va_arg_pack ());
+}
+#endif
/* Write a message on the specified descriptor standard output. The
parameters are interpreted as for a `printf' call. */
@@ -737,13 +733,26 @@ extern void _dl_dprintf (int fd, const char *fmt, ...)
problem. */
extern void _dl_signal_error (int errcode, const char *object,
const char *occurred, const char *errstring)
- internal_function __attribute__ ((__noreturn__)) attribute_hidden;
+ internal_function __attribute__ ((__noreturn__));
+libc_hidden_proto (_dl_signal_error)
/* Like _dl_signal_error, but may return when called in the context of
- _dl_receive_error. */
+ _dl_receive_error. This is only used during ld.so bootstrap. In
+ static and profiled builds, this is equivalent to
+ _dl_signal_error. */
+#if IS_IN (rtld)
extern void _dl_signal_cerror (int errcode, const char *object,
const char *occation, const char *errstring)
internal_function attribute_hidden;
+#else
+__attribute__ ((always_inline))
+static inline void
+_dl_signal_cerror (int errcode, const char *object,
+ const char *occation, const char *errstring)
+{
+ _dl_signal_error (errcode, object, occation, errstring);
+}
+#endif
/* Call OPERATE, receiving errors from `dl_signal_cerror'. Unlike
`_dl_catch_error' the operation is resumed after the OPERATE
@@ -764,7 +773,8 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
extern int _dl_catch_error (const char **objname, const char **errstring,
bool *mallocedp, void (*operate) (void *),
void *args)
- internal_function attribute_hidden;
+ internal_function;
+libc_hidden_proto (_dl_catch_error)
/* Open the shared object NAME and map in its segments.
LOADER's DT_RPATH is used in searching for NAME.
diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data
index 1a40cf9..5cf53a4 100644
--- a/sysdeps/generic/localplt.data
+++ b/sysdeps/generic/localplt.data
@@ -15,3 +15,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/aarch64/localplt.data b/sysdeps/unix/sysv/linux/aarch64/localplt.data
index d7d6734..e431f36 100644
--- a/sysdeps/unix/sysv/linux/aarch64/localplt.data
+++ b/sysdeps/unix/sysv/linux/aarch64/localplt.data
@@ -16,3 +16,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/alpha/localplt.data b/sysdeps/unix/sysv/linux/alpha/localplt.data
index 351596c..2984393 100644
--- a/sysdeps/unix/sysv/linux/alpha/localplt.data
+++ b/sysdeps/unix/sysv/linux/alpha/localplt.data
@@ -33,3 +33,6 @@ ld.so: malloc + RELA R_ALPHA_GLOB_DAT
ld.so: calloc + RELA R_ALPHA_GLOB_DAT
ld.so: realloc + RELA R_ALPHA_GLOB_DAT
ld.so: free + RELA R_ALPHA_GLOB_DAT
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error + RELA R_ALPHA_GLOB_DAT
+ld.so: _dl_catch_error + RELA R_ALPHA_GLOB_DAT
diff --git a/sysdeps/unix/sysv/linux/arm/localplt.data b/sysdeps/unix/sysv/linux/arm/localplt.data
index 4301703..a5ccd7f 100644
--- a/sysdeps/unix/sysv/linux/arm/localplt.data
+++ b/sysdeps/unix/sysv/linux/arm/localplt.data
@@ -16,3 +16,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data
index 2a25ebc..fea8c9c 100644
--- a/sysdeps/unix/sysv/linux/hppa/localplt.data
+++ b/sysdeps/unix/sysv/linux/hppa/localplt.data
@@ -21,3 +21,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data
index 4ce8447..48bcc42 100644
--- a/sysdeps/unix/sysv/linux/i386/localplt.data
+++ b/sysdeps/unix/sysv/linux/i386/localplt.data
@@ -15,3 +15,6 @@ ld.so: malloc + REL R_386_GLOB_DAT
ld.so: calloc + REL R_386_GLOB_DAT
ld.so: realloc + REL R_386_GLOB_DAT
ld.so: free + REL R_386_GLOB_DAT
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error + REL R_386_GLOB_DAT
+ld.so: _dl_catch_error + REL R_386_GLOB_DAT
diff --git a/sysdeps/unix/sysv/linux/ia64/localplt.data b/sysdeps/unix/sysv/linux/ia64/localplt.data
index b628ca4..df63530 100644
--- a/sysdeps/unix/sysv/linux/ia64/localplt.data
+++ b/sysdeps/unix/sysv/linux/ia64/localplt.data
@@ -14,3 +14,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/m68k/localplt.data b/sysdeps/unix/sysv/linux/m68k/localplt.data
index 88124c4..abfbd34 100644
--- a/sysdeps/unix/sysv/linux/m68k/localplt.data
+++ b/sysdeps/unix/sysv/linux/m68k/localplt.data
@@ -14,3 +14,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/microblaze/localplt.data b/sysdeps/unix/sysv/linux/microblaze/localplt.data
index 176d618..697fdd0 100644
--- a/sysdeps/unix/sysv/linux/microblaze/localplt.data
+++ b/sysdeps/unix/sysv/linux/microblaze/localplt.data
@@ -15,3 +15,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/nios2/localplt.data b/sysdeps/unix/sysv/linux/nios2/localplt.data
index 6cf93cc..a7d774d 100644
--- a/sysdeps/unix/sysv/linux/nios2/localplt.data
+++ b/sysdeps/unix/sysv/linux/nios2/localplt.data
@@ -35,3 +35,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
index b25abf8..4ef5bf4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
@@ -13,3 +13,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
index 8c4e65d..c919426 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
@@ -43,3 +43,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
index 49d5de6..2d43472 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
@@ -12,3 +12,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/s390/localplt.data b/sysdeps/unix/sysv/linux/s390/localplt.data
index 1226413..bd1addd 100644
--- a/sysdeps/unix/sysv/linux/s390/localplt.data
+++ b/sysdeps/unix/sysv/linux/s390/localplt.data
@@ -20,3 +20,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/sh/localplt.data b/sysdeps/unix/sysv/linux/sh/localplt.data
index 57f31c5..e6fb930 100644
--- a/sysdeps/unix/sysv/linux/sh/localplt.data
+++ b/sysdeps/unix/sysv/linux/sh/localplt.data
@@ -18,3 +18,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
index a208adf..d5b5895 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
@@ -24,3 +24,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
index 2323551..edceab5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
@@ -26,3 +26,6 @@ ld.so: malloc
ld.so: calloc
ld.so: realloc
ld.so: free
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error
+ld.so: _dl_catch_error
diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data
index f168b14..28096f8 100644
--- a/sysdeps/x86_64/localplt.data
+++ b/sysdeps/x86_64/localplt.data
@@ -17,3 +17,6 @@ ld.so: malloc + RELA R_X86_64_GLOB_DAT
ld.so: calloc + RELA R_X86_64_GLOB_DAT
ld.so: realloc + RELA R_X86_64_GLOB_DAT
ld.so: free + RELA R_X86_64_GLOB_DAT
+# The TLS-enabled version of these functions is interposed from libc.so.
+ld.so: _dl_signal_error + RELA R_X86_64_GLOB_DAT
+ld.so: _dl_catch_error + RELA R_X86_64_GLOB_DAT
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 78 +++++++
dlfcn/dlerror.c | 4 +-
dlfcn/dlinfo.c | 4 +-
dlfcn/dlmopen.c | 4 +-
dlfcn/dlopen.c | 2 +-
elf/Makefile | 21 ++-
elf/Versions | 6 +
elf/dl-close.c | 2 +-
elf/dl-error-minimal.c | 23 ++
elf/dl-error-skeleton.c | 230 ++++++++++++++++++++
elf/dl-error.c | 210 +-----------------
elf/dl-libc.c | 4 +-
elf/dl-sym.c | 8 +-
elf/dl-tsd.c | 53 -----
elf/rtld.c | 19 --
elf/tst-latepthread.c | 105 +++++++++
elf/tst-latepthreadmod.c | 33 +++
nptl/nptl-init.c | 4 -
sysdeps/generic/ldsodefs.h | 46 +++--
sysdeps/generic/localplt.data | 3 +
sysdeps/unix/sysv/linux/aarch64/localplt.data | 3 +
sysdeps/unix/sysv/linux/alpha/localplt.data | 3 +
sysdeps/unix/sysv/linux/arm/localplt.data | 3 +
sysdeps/unix/sysv/linux/hppa/localplt.data | 3 +
sysdeps/unix/sysv/linux/i386/localplt.data | 3 +
sysdeps/unix/sysv/linux/ia64/localplt.data | 3 +
sysdeps/unix/sysv/linux/m68k/localplt.data | 3 +
sysdeps/unix/sysv/linux/microblaze/localplt.data | 3 +
sysdeps/unix/sysv/linux/nios2/localplt.data | 3 +
.../sysv/linux/powerpc/powerpc32/fpu/localplt.data | 3 +
.../linux/powerpc/powerpc32/nofpu/localplt.data | 3 +
.../sysv/linux/powerpc/powerpc64/localplt.data | 3 +
sysdeps/unix/sysv/linux/s390/localplt.data | 3 +
sysdeps/unix/sysv/linux/sh/localplt.data | 3 +
.../unix/sysv/linux/sparc/sparc32/localplt.data | 3 +
.../unix/sysv/linux/sparc/sparc64/localplt.data | 3 +
sysdeps/x86_64/localplt.data | 3 +
37 files changed, 595 insertions(+), 315 deletions(-)
create mode 100644 elf/dl-error-minimal.c
create mode 100644 elf/dl-error-skeleton.c
delete mode 100644 elf/dl-tsd.c
create mode 100644 elf/tst-latepthread.c
create mode 100644 elf/tst-latepthreadmod.c
hooks/post-receive
--
GNU C Library master sources
More information about the Glibc-cvs
mailing list