mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
elf: Use RTLD_NODELETE is more places
* On dlopen dependencies for objects opened with RTLD_NODELETE (since it does not make sense to unload a dependency of a RTLD_NODELETE object); * For the main map executable. * For the main map DT_NEEDED dependencies. * On __libc_unwind_link_get for libgcc_s.so (used for backtrace and unwind). Checked on x86_64-linux-gnu.
This commit is contained in:
parent
e3b0b3484c
commit
4d2825a355
@ -636,7 +636,8 @@ dl_open_worker_begin (void *a)
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
_dl_map_object_deps (new, NULL, 0, 0,
|
||||
mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT));
|
||||
mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT
|
||||
| RTLD_NODELETE));
|
||||
|
||||
/* So far, so good. Now check the versions. */
|
||||
for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
|
@ -811,7 +811,7 @@ do_preload (const char *fname, struct link_map *main_map, const char *where)
|
||||
|
||||
args.str = fname;
|
||||
args.loader = main_map;
|
||||
args.mode = __RTLD_SECURE;
|
||||
args.mode = __RTLD_SECURE | RTLD_NODELETE;
|
||||
|
||||
unsigned int old_nloaded = GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
|
||||
|
||||
@ -1638,7 +1638,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
/* Create a link_map for the executable itself.
|
||||
This will be what dlopen on "" returns. */
|
||||
main_map = _dl_new_object ((char *) "", "", lt_executable, NULL,
|
||||
__RTLD_OPENEXEC, LM_ID_BASE);
|
||||
__RTLD_OPENEXEC | RTLD_NODELETE, LM_ID_BASE);
|
||||
assert (main_map != NULL);
|
||||
main_map->l_phdr = phdr;
|
||||
main_map->l_phnum = phnum;
|
||||
@ -1966,7 +1966,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
RTLD_TIMING_VAR (start);
|
||||
rtld_timer_start (&start);
|
||||
_dl_map_object_deps (main_map, preloads, npreloads,
|
||||
state.mode == rtld_mode_trace, 0);
|
||||
state.mode == rtld_mode_trace, RTLD_NODELETE);
|
||||
rtld_timer_accum (&load_time, start);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,8 @@ extern char **__libc_argv attribute_hidden;
|
||||
better error handling semantics for the library. */
|
||||
#define __libc_dlopen(name) \
|
||||
__libc_dlopen_mode (name, RTLD_NOW | __RTLD_DLOPEN)
|
||||
#define __libc_dlopen_nodelete(name) \
|
||||
__libc_dlopen_mode (name, RTLD_NODELETE | RTLD_NOW | __RTLD_DLOPEN)
|
||||
extern void *__libc_dlopen_mode (const char *__name, int __mode)
|
||||
attribute_hidden;
|
||||
extern void *__libc_dlsym (void *__map, const char *__name)
|
||||
|
@ -48,7 +48,7 @@ __libc_unwind_link_get (void)
|
||||
/* Initialize a copy of the data, so that we do not need about
|
||||
unlocking in case the dynamic loader somehow triggers
|
||||
unwinding. */
|
||||
void *local_libgcc_handle = __libc_dlopen (LIBGCC_S_SO);
|
||||
void *local_libgcc_handle = __libc_dlopen_nodelete (LIBGCC_S_SO);
|
||||
if (local_libgcc_handle == NULL)
|
||||
{
|
||||
__libc_lock_unlock (lock);
|
||||
@ -100,7 +100,8 @@ __libc_unwind_link_get (void)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
if (atomic_load_relaxed (&global_libgcc_handle) != NULL)
|
||||
/* This thread lost the race. Clean up. */
|
||||
/* This thread lost the race. Drop the l_direct_opencount and issue
|
||||
the debug log. */
|
||||
__libc_dlclose (local_libgcc_handle);
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user