about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2021-06-03 08:26:04 +0200
committerFlorian Weimer <fweimer@redhat.com>2021-06-03 09:12:05 +0200
commit466c1ea15f461edb8e3ffaf5d86d708876343bbf (patch)
tree43d42d322ff24bd12c4124a9edafc4e0e4232f0a /elf
parent9c76debc983e1a16e2e723b36526826713a671af (diff)
downloadglibc-466c1ea15f461edb8e3ffaf5d86d708876343bbf.tar.gz
glibc-466c1ea15f461edb8e3ffaf5d86d708876343bbf.tar.xz
glibc-466c1ea15f461edb8e3ffaf5d86d708876343bbf.zip
dlfcn: Rework static dlopen hooks
Consolidate all hooks structures into a single one.  There are
no static dlopen ABI concerns because glibc 2.34 already comes
with substantial ABI-incompatible changes in this area.  (Static
dlopen requires the exact same dynamic glibc version that was used
for static linking.)

The new approach uses a pointer to the hooks structure into
_rtld_global_ro and initalizes it in __rtld_static_init.  This avoids
a back-and-forth with various callback functions.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Diffstat (limited to 'elf')
-rw-r--r--elf/Versions1
-rw-r--r--elf/dl-libc.c73
-rw-r--r--elf/rtld_static_init.c18
3 files changed, 24 insertions, 68 deletions
diff --git a/elf/Versions b/elf/Versions
index be88c48e6d..a12d64e8db 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -23,7 +23,6 @@ libc {
   GLIBC_PRIVATE {
     # functions used in other libraries
     _dl_addr;
-    _dl_open_hook; _dl_open_hook2;
     _dl_sym; _dl_vsym;
     __libc_dlclose; __libc_dlopen_mode; __libc_dlsym; __libc_dlvsym;
     __libc_early_init;
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index ed551f6e56..8e0734f44c 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -126,32 +126,7 @@ do_dlclose (void *ptr)
   GLRO(dl_close) ((struct link_map *) ptr);
 }
 
-/* This code is to support __libc_dlopen from __libc_dlopen'ed shared
-   libraries.  We need to ensure the statically linked __libc_dlopen
-   etc. functions are used instead of the dynamically loaded.  */
-struct dl_open_hook
-{
-  void *(*dlopen_mode) (const char *name, int mode);
-  void *(*dlsym) (void *map, const char *name);
-  int (*dlclose) (void *map);
-  void *(*dlvsym) (void *map, const char *name, const char *version);
-};
-
-#ifdef SHARED
-extern struct dl_open_hook *_dl_open_hook;
-libc_hidden_proto (_dl_open_hook);
-struct dl_open_hook *_dl_open_hook __attribute__ ((nocommon));
-libc_hidden_data_def (_dl_open_hook);
-
-/* The dlvsym member was added retroactively to struct dl_open_hook.
-   Static applications which have it will set _dl_open_hook2 in
-   addition to _dl_open_hook.  */
-extern struct dl_open_hook *_dl_open_hook2;
-libc_hidden_proto (_dl_open_hook2);
-struct dl_open_hook *_dl_open_hook2 __attribute__ ((nocommon));
-libc_hidden_data_def (_dl_open_hook2);
-
-#else
+#ifndef SHARED
 static void
 do_dlsym_private (void *ptr)
 {
@@ -169,14 +144,6 @@ do_dlsym_private (void *ptr)
 				args->map->l_scope, &vers, 0, 0, NULL);
   args->loadbase = l;
 }
-
-static struct dl_open_hook _dl_open_hook =
-  {
-    .dlopen_mode = __libc_dlopen_mode,
-    .dlsym = __libc_dlsym,
-    .dlclose = __libc_dlclose,
-    .dlvsym = __libc_dlvsym,
-  };
 #endif
 
 /* ... and these functions call dlerror_run. */
@@ -191,16 +158,9 @@ __libc_dlopen_mode (const char *name, int mode)
 
 #ifdef SHARED
   if (!rtld_active ())
-    return _dl_open_hook->dlopen_mode (name, mode);
-  return (dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map);
-#else
-  if (dlerror_run (do_dlopen, &args))
-    return NULL;
-
-  __libc_register_dl_open_hook (args.map);
-  __libc_register_dlfcn_hook (args.map);
-  return (void *) args.map;
+    return GLRO (dl_dlfcn_hook)->libc_dlopen_mode (name, mode);
 #endif
+  return dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map;
 }
 libc_hidden_def (__libc_dlopen_mode)
 
@@ -216,21 +176,6 @@ __libc_dlsym_private (struct link_map *map, const char *name)
     return DL_SYMBOL_ADDRESS (sargs.loadbase, sargs.ref);
   return NULL;
 }
-
-void
-__libc_register_dl_open_hook (struct link_map *map)
-{
-  struct dl_open_hook **hook;
-
-  hook = (struct dl_open_hook **) __libc_dlsym_private (map, "_dl_open_hook");
-  if (hook != NULL)
-    *hook = &_dl_open_hook;
-
-  /* For dlvsym support.  */
-  hook = (struct dl_open_hook **) __libc_dlsym_private (map, "_dl_open_hook2");
-  if (hook != NULL)
-    *hook = &_dl_open_hook;
-}
 #endif
 
 void *
@@ -242,7 +187,7 @@ __libc_dlsym (void *map, const char *name)
 
 #ifdef SHARED
   if (!rtld_active ())
-    return _dl_open_hook->dlsym (map, name);
+    return GLRO (dl_dlfcn_hook)->libc_dlsym (map, name);
 #endif
   return (dlerror_run (do_dlsym, &args) ? NULL
 	  : (void *) (DL_SYMBOL_ADDRESS (args.loadbase, args.ref)));
@@ -257,13 +202,7 @@ __libc_dlvsym (void *map, const char *name, const char *version)
 {
 #ifdef SHARED
   if (!rtld_active ())
-    {
-      /* The static application is too old and does not provide the
-	 dlvsym hook.  */
-      if (_dl_open_hook2 == NULL)
-	return NULL;
-      return _dl_open_hook2->dlvsym (map, name, version);
-    }
+    return GLRO (dl_dlfcn_hook)->libc_dlvsym (map, name, version);
 #endif
 
   struct do_dlvsym_args args;
@@ -287,7 +226,7 @@ __libc_dlclose (void *map)
 {
 #ifdef SHARED
   if (!rtld_active ())
-    return _dl_open_hook->dlclose (map);
+    return GLRO (dl_dlfcn_hook)->libc_dlclose (map);
 #endif
   return dlerror_run (do_dlclose, map);
 }
diff --git a/elf/rtld_static_init.c b/elf/rtld_static_init.c
index 42efecfbff..3f8abb6800 100644
--- a/elf/rtld_static_init.c
+++ b/elf/rtld_static_init.c
@@ -25,6 +25,23 @@
 
 #include <rtld_static_init.h>
 
+static const struct dlfcn_hook _dlfcn_hook =
+  {
+    .dlopen = __dlopen,
+    .dlclose = __dlclose,
+    .dlsym = __dlsym,
+    .dlvsym = __dlvsym,
+    .dlerror = __dlerror,
+    .dladdr = __dladdr,
+    .dladdr1 = __dladdr1,
+    .dlinfo = __dlinfo,
+    .dlmopen = __dlmopen,
+    .libc_dlopen_mode = __libc_dlopen_mode,
+    .libc_dlsym = __libc_dlsym,
+    .libc_dlvsym = __libc_dlvsym,
+    .libc_dlclose = __libc_dlclose,
+  };
+
 void
 __rtld_static_init (struct link_map *map)
 {
@@ -45,6 +62,7 @@ __rtld_static_init (struct link_map *map)
   extern __typeof (dl->_dl_clktck) _dl_clktck attribute_hidden;
   dl->_dl_clktck = _dl_clktck;
 #endif
+  dl->_dl_dlfcn_hook = &_dlfcn_hook;
   extern __typeof (dl->_dl_hwcap) _dl_hwcap attribute_hidden;
   dl->_dl_hwcap = _dl_hwcap;
   extern __typeof (dl->_dl_hwcap2) _dl_hwcap2 attribute_hidden;