]> sourceware.org Git - glibc.git/commitdiff
Implement _dl_catch_error, _dl_signal_error in libc.so [BZ #16628]
authorFlorian Weimer <fweimer@redhat.com>
Wed, 30 Nov 2016 14:59:57 +0000 (15:59 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Wed, 30 Nov 2016 14:59:57 +0000 (15:59 +0100)
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.

37 files changed:
ChangeLog
dlfcn/dlerror.c
dlfcn/dlinfo.c
dlfcn/dlmopen.c
dlfcn/dlopen.c
elf/Makefile
elf/Versions
elf/dl-close.c
elf/dl-error-minimal.c [new file with mode: 0644]
elf/dl-error-skeleton.c [new file with mode: 0644]
elf/dl-error.c
elf/dl-libc.c
elf/dl-sym.c
elf/dl-tsd.c [deleted file]
elf/rtld.c
elf/tst-latepthread.c [new file with mode: 0644]
elf/tst-latepthreadmod.c [new file with mode: 0644]
nptl/nptl-init.c
sysdeps/generic/ldsodefs.h
sysdeps/generic/localplt.data
sysdeps/unix/sysv/linux/aarch64/localplt.data
sysdeps/unix/sysv/linux/alpha/localplt.data
sysdeps/unix/sysv/linux/arm/localplt.data
sysdeps/unix/sysv/linux/hppa/localplt.data
sysdeps/unix/sysv/linux/i386/localplt.data
sysdeps/unix/sysv/linux/ia64/localplt.data
sysdeps/unix/sysv/linux/m68k/localplt.data
sysdeps/unix/sysv/linux/microblaze/localplt.data
sysdeps/unix/sysv/linux/nios2/localplt.data
sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
sysdeps/unix/sysv/linux/s390/localplt.data
sysdeps/unix/sysv/linux/sh/localplt.data
sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
sysdeps/x86_64/localplt.data

index c2cb6080650955bff7e2e68d0a9550980a16c385..d01747866e496ccf8b3828e09d499a793caf017a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,81 @@
+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]
index 41b2bd6bf29be5f61affc5e750775ab2f64ee4b0..e0e5648696965e8bc2d30f5c031dc801375285c0 100644 (file)
@@ -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;
index eeba8da40892aefc15823dfc8773c10e9ca7441d..794e354c233ab6df1e4dc2e6135d410349aebdf4 100644 (file)
@@ -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:
index 6da0d0d6913906b9ccf51fafd24a3a11ded341c2..4eed5136f55511e676ee14ed900d6f945b80f2c5 100644 (file)
@@ -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,
index 453efbd1c02fe1bf1e9a94e4e6aa7b261f2f2fd3..5263fed5f31de2e8b0d805e8cd26677c5e12d065 100644 (file)
@@ -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,
index 82c7e0559d8db6ffa4417c9d00c20f48f2db9ff8..33b003b170e1f42e82cc1a5c24438590919727ab 100644 (file)
@@ -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
index 23deda984ff1eda4b648495a321505dadd578e7d..05e5449f4d059715fa5b8c6a6f7e715c249611f5 100644 (file)
@@ -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;
   }
 }
index 687d7de874c57f1b39ddc56e16bd7b33942462de..648970332ea524fa974d1e9202dde46e52eb5f81 100644 (file)
@@ -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 (file)
index 0000000..d535d65
--- /dev/null
@@ -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-skeleton.c b/elf/dl-error-skeleton.c
new file mode 100644 (file)
index 0000000..beb31ae
--- /dev/null
@@ -0,0 +1,230 @@
+/* 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.
+
+   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/>.  */
+
+/* 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>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <stdio.h>
+
+/* 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.  */
+  };
+
+/* 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;
+#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'.
+
+   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 */
+
+void
+internal_function
+_dl_signal_error (int errcode, const char *objname, const char *occation,
+                 const char *errstring)
+{
+  struct catch *lcatch = catch_hook;
+
+  if (! errstring)
+    errstring = N_("DYNAMIC LINKER BUG!!!");
+
+  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)
+                        : ""));
+    }
+}
+libc_hidden_def (_dl_signal_error)
+
+
+#if DL_ERROR_BOOTSTRAP
+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);
+}
+#endif /* DL_ERROR_BOOTSTRAP */
+
+
+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 old = catch_hook;
+  catch_hook = &c;
+
+  /* Do not save the signal mask.  */
+  if (__builtin_expect (__sigsetjmp (c.env, 0), 0) == 0)
+    {
+      (*operate) (args);
+      catch_hook = 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.  */
+  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 *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;
+}
+#endif /* DL_ERROR_BOOTSTRAP */
index bd22ec6cf07e7338bc9cef4c9225913e9c0380df..7fe36b46318e58340aa2c36763008aa8e5736bbc 100644 (file)
@@ -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.
 
    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"
index d56de1a57a0b66c62ba6555eea5760e044b83975..dde44c8799dee6b37fe9575012e7a531e9cdbc62 100644 (file)
@@ -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)
index 6431c226149ea7be19a824ae2cfacc47a86ae022..e00b286991bfeeed2f0436bf660f3aab8184f34d 100644 (file)
@@ -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 (file)
index 7181e1c..0000000
+++ /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 */
index 647661ca45901d6e42c3c52475030d8dd06b61ab..4ec25d7c30d91dd2d1d61ef4952898899a260a1e 100644 (file)
@@ -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 (file)
index 0000000..9449ef6
--- /dev/null
@@ -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 (file)
index 0000000..ce81206
--- /dev/null
@@ -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 ();
+}
index 48fab50c4ead43479cb0541170a839052257e52d..0fd54a0a932195365daae40f705bb1ea23a88ef7 100644 (file)
@@ -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;
index f68fdf4501821dfcaf0c814afecb9bcb3aaf7c87..288f5fe32e7a75530777499a4ea55aeaa75e4023 100644 (file)
@@ -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.
index 1a40cf984112918d0bac3dc272dca5832da3c07b..5cf53a4c21443521460c72539fef3f0b58232a6c 100644 (file)
@@ -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
index d7d673454fa561f6f34c45711062a54f9dc82b66..e431f368e31e8d00399081a4815c3d27b0043677 100644 (file)
@@ -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
index 351596cf575270d72bc0028743d322e35e334853..298439365f6f76d1578d858651b5a2f2aacdf475 100644 (file)
@@ -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
index 43017035539de3be1bb4adcdda1b0d8537718a4b..a5ccd7fa587a1584b1d23be6a64ceb828a3f89e8 100644 (file)
@@ -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
index 2a25ebce46657c3d4d6c13b72ab3e9524ea6e7d4..fea8c9cbf61581b81e69455acced8be548a4d3e5 100644 (file)
@@ -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
index 4ce8447673be80d5229f345e4b9b4dc048a77366..48bcc42a6722d49902d98b68cfe6d59e40c24fcd 100644 (file)
@@ -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
index b628ca4dfc5046b05dbed206edda73374a1bfe32..df63530b6ca56c38dd792fb97dd6dd817a9f98e2 100644 (file)
@@ -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
index 88124c4460950fe4b2fbcff9e78417445dfa9f5b..abfbd34f419ff17ce2ef648d32a55a6a082eddbf 100644 (file)
@@ -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
index 176d61818e82652c0706c398fb6f972c3fdfb2f2..697fdd018683b30026cd2c327cbb99bef5f516b5 100644 (file)
@@ -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
index 6cf93cc2afb832610d273c462b6d32be76da8c38..a7d774dcf81a1e0788b328d999258d35261c3247 100644 (file)
@@ -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
index b25abf800650c8aba280b48a606b243e664c67a3..4ef5bf4a7fd7a822107e4829dd9974c3a2bd0d49 100644 (file)
@@ -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
index 8c4e65d123be80afc350849cbffb21297751746e..c9194264dd5b40210284a545580891fc1093aede 100644 (file)
@@ -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
index 49d5de6019ea4e944c07778b602051ce7120c0f5..2d434726cc186ca2d72c91af4bbcd8d0ddd4d03a 100644 (file)
@@ -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
index 122641312c09fec4167ba3092b8fbff13819e8b3..bd1adddb1f1f075ad0e16509701621ff0f7fbbce 100644 (file)
@@ -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
index 57f31c579a9d3e7271357346b31555cb3dcec1cd..e6fb930cf73ae1174ebd8969b562b5bad80c2f3e 100644 (file)
@@ -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
index a208adff31017a5529a96d366752869d133feef6..d5b5895a5c00a0668d4256ef6758643744bb97d8 100644 (file)
@@ -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
index 2323551f631efbadc70cd108193ed987684afb76..edceab57c3ff6cf67420d02143da0ed4b2c4e12a 100644 (file)
@@ -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
index f168b143ff264668fab402a1c872ab3369b08412..28096f893e3099671b4fb9773c729bbadf9bd1d6 100644 (file)
@@ -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
This page took 0.198761 seconds and 5 git commands to generate.