aboutsummaryrefslogtreecommitdiff
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
glibc-466c1ea15f461edb8e3ffaf5d86d708876343bbf.tar.gz
glibc-466c1ea15f461edb8e3ffaf5d86d708876343bbf.tar.bz2
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;