about summary refs log tree commit diff
path: root/dlfcn
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 /dlfcn
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 'dlfcn')
-rw-r--r--dlfcn/dladdr.c2
-rw-r--r--dlfcn/dladdr1.c2
-rw-r--r--dlfcn/dlclose.c2
-rw-r--r--dlfcn/dlerror.c32
-rw-r--r--dlfcn/dlinfo.c2
-rw-r--r--dlfcn/dlmopen.c10
-rw-r--r--dlfcn/dlopen.c10
-rw-r--r--dlfcn/dlopenold.c2
-rw-r--r--dlfcn/dlsym.c2
-rw-r--r--dlfcn/dlvsym.c3
10 files changed, 13 insertions, 54 deletions
diff --git a/dlfcn/dladdr.c b/dlfcn/dladdr.c
index 3ef1b7f0b6..1cc305f0c4 100644
--- a/dlfcn/dladdr.c
+++ b/dlfcn/dladdr.c
@@ -25,7 +25,7 @@ __dladdr (const void *address, Dl_info *info)
 {
 #ifdef SHARED
   if (!rtld_active ())
-    return _dlfcn_hook->dladdr (address, info);
+    return GLRO (dl_dlfcn_hook)->dladdr (address, info);
 #endif
   return _dl_addr (address, info, NULL, NULL);
 }
diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c
index 203d6398e4..78560dbac2 100644
--- a/dlfcn/dladdr1.c
+++ b/dlfcn/dladdr1.c
@@ -25,7 +25,7 @@ __dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
 {
 #ifdef SHARED
   if (!rtld_active ())
-    return _dlfcn_hook->dladdr1 (address, info, extra, flags);
+    return GLRO (dl_dlfcn_hook)->dladdr1 (address, info, extra, flags);
 #endif
 
   switch (flags)
diff --git a/dlfcn/dlclose.c b/dlfcn/dlclose.c
index 4d5d307ab1..6a013a81bb 100644
--- a/dlfcn/dlclose.c
+++ b/dlfcn/dlclose.c
@@ -25,7 +25,7 @@ __dlclose (void *handle)
 {
 #ifdef SHARED
   if (!rtld_active ())
-    return _dlfcn_hook->dlclose (handle);
+    return GLRO (dl_dlfcn_hook)->dlclose (handle);
 #endif
 
   return _dlerror_run (GLRO (dl_close), handle) ? -1 : 0;
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 3df8602f4d..d0194a7cef 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -33,7 +33,7 @@ __dlerror (void)
 {
 # ifdef SHARED
   if (!rtld_active ())
-    return _dlfcn_hook->dlerror ();
+    return GLRO (dl_dlfcn_hook)->dlerror ();
 # endif
 
   struct dl_action_result *result = __libc_dlerror_result;
@@ -197,33 +197,3 @@ _dlerror_run (void (*operate) (void *), void *args)
     }
 }
 libc_hidden_def (_dlerror_run)
-
-#ifdef SHARED
-struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));
-libc_hidden_data_def (_dlfcn_hook)
-
-#else /* !SHARED */
-
-static struct dlfcn_hook _dlfcn_hooks =
-  {
-    .dlopen = __dlopen,
-    .dlclose = __dlclose,
-    .dlsym = __dlsym,
-    .dlvsym = __dlvsym,
-    .dlerror = __dlerror,
-    .dladdr = __dladdr,
-    .dladdr1 = __dladdr1,
-    .dlinfo = __dlinfo,
-    .dlmopen = __dlmopen
-  };
-
-void
-__libc_register_dlfcn_hook (struct link_map *map)
-{
-  struct dlfcn_hook **hook;
-
-  hook = (struct dlfcn_hook **) __libc_dlsym_private (map, "_dlfcn_hook");
-  if (hook != NULL)
-    *hook = &_dlfcn_hooks;
-}
-#endif /* !SHARED */
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
index 15fcbc5dc1..c6f9a1da09 100644
--- a/dlfcn/dlinfo.c
+++ b/dlfcn/dlinfo.c
@@ -90,7 +90,7 @@ int
 ___dlinfo (void *handle, int request, void *arg)
 {
   if (!rtld_active ())
-    return _dlfcn_hook->dlinfo (handle, request, arg);
+    return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg);
   else
     return dlinfo_implementation (handle, request, arg);
 }
diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c
index ae42814bbf..c171c8953d 100644
--- a/dlfcn/dlmopen.c
+++ b/dlfcn/dlmopen.c
@@ -81,7 +81,7 @@ void *
 ___dlmopen (Lmid_t nsid, const char *file, int mode)
 {
   if (!rtld_active ())
-    return _dlfcn_hook->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
+    return GLRO (dl_dlfcn_hook)->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
   else
     return dlmopen_implementation (nsid, file, mode, RETURN_ADDRESS (0));
 }
@@ -101,13 +101,7 @@ __dlmopen (Lmid_t nsid, const char *file, int mode, void *dl_caller)
 void *
 ___dlmopen (Lmid_t nsid, const char *file, int mode)
 {
-  struct link_map *l = __dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
-  if (l != NULL)
-    {
-      __libc_register_dl_open_hook (l);
-      __libc_register_dlfcn_hook (l);
-    }
-  return l;
+  return __dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
 }
 weak_alias (___dlmopen, dlmopen)
 static_link_warning (dlmopen)
diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
index afdc113efb..e04b374b82 100644
--- a/dlfcn/dlopen.c
+++ b/dlfcn/dlopen.c
@@ -76,7 +76,7 @@ void *
 ___dlopen (const char *file, int mode)
 {
   if (!rtld_active ())
-    return _dlfcn_hook->dlopen (file, mode, RETURN_ADDRESS (0));
+    return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
   else
     return dlopen_implementation (file, mode, RETURN_ADDRESS (0));
 }
@@ -96,13 +96,7 @@ __dlopen (const char *file, int mode, void *dl_caller)
 void *
 ___dlopen (const char *file, int mode)
 {
-  struct link_map *l = __dlopen (file, mode, RETURN_ADDRESS (0));
-  if (l != NULL)
-    {
-      __libc_register_dl_open_hook (l);
-      __libc_register_dlfcn_hook (l);
-    }
-  return l;
+  return __dlopen (file, mode, RETURN_ADDRESS (0));
 }
 weak_alias (___dlopen, dlopen)
 static_link_warning (dlopen)
diff --git a/dlfcn/dlopenold.c b/dlfcn/dlopenold.c
index 0fe5f24cc5..9115501ac1 100644
--- a/dlfcn/dlopenold.c
+++ b/dlfcn/dlopenold.c
@@ -71,7 +71,7 @@ __dlopen_nocheck (const char *file, int mode)
   args.mode = mode;
 
   if (!rtld_active ())
-    return _dlfcn_hook->dlopen (file, mode, RETURN_ADDRESS (0));
+    return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
 
   return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
 }
diff --git a/dlfcn/dlsym.c b/dlfcn/dlsym.c
index 6b03b7b7ab..43044cf7bb 100644
--- a/dlfcn/dlsym.c
+++ b/dlfcn/dlsym.c
@@ -63,7 +63,7 @@ void *
 ___dlsym (void *handle, const char *name)
 {
   if (!rtld_active ())
-    return _dlfcn_hook->dlsym (handle, name, RETURN_ADDRESS (0));
+    return GLRO (dl_dlfcn_hook)->dlsym (handle, name, RETURN_ADDRESS (0));
   else
     return dlsym_implementation (handle, name, RETURN_ADDRESS (0));
 }
diff --git a/dlfcn/dlvsym.c b/dlfcn/dlvsym.c
index de6b340647..9b76f9afa5 100644
--- a/dlfcn/dlvsym.c
+++ b/dlfcn/dlvsym.c
@@ -66,7 +66,8 @@ void *
 ___dlvsym (void *handle, const char *name, const char *version)
 {
   if (!rtld_active ())
-    return _dlfcn_hook->dlvsym (handle, name, version, RETURN_ADDRESS (0));
+    return GLRO (dl_dlfcn_hook)->dlvsym (handle, name, version,
+					 RETURN_ADDRESS (0));
   else
     return dlvsym_implementation (handle, name, version, RETURN_ADDRESS (0));
 }