diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-06-03 08:26:04 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-06-03 09:12:05 +0200 |
commit | 466c1ea15f461edb8e3ffaf5d86d708876343bbf (patch) | |
tree | 43d42d322ff24bd12c4124a9edafc4e0e4232f0a /elf | |
parent | 9c76debc983e1a16e2e723b36526826713a671af (diff) | |
download | glibc-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/Versions | 1 | ||||
-rw-r--r-- | elf/dl-libc.c | 73 | ||||
-rw-r--r-- | elf/rtld_static_init.c | 18 |
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; |