aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-runtime.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-01-15 20:48:56 +0000
committerUlrich Drepper <drepper@redhat.com>2007-01-15 20:48:56 +0000
commit4e35ef2c710dfefe96a491d133b5a53414e9a5c2 (patch)
treed9219ecd731de733953c1224356ecbe068b35e7f /elf/dl-runtime.c
parentfb453d084d86f22718b60422a135f7c70e47f0ac (diff)
downloadglibc-4e35ef2c710dfefe96a491d133b5a53414e9a5c2.tar
glibc-4e35ef2c710dfefe96a491d133b5a53414e9a5c2.tar.gz
glibc-4e35ef2c710dfefe96a491d133b5a53414e9a5c2.tar.bz2
glibc-4e35ef2c710dfefe96a491d133b5a53414e9a5c2.zip
* sysdeps/generic/ldsodefs.h: Define DL_LOOKUP_SCOPE_LOCK.
* elf/dl-lookup.c (add_dependency): If scope map is locked, unlock it before getting dl_load_lock and then relock. (_dl_lookup_symbol_x): Pass flags to add_dependency. When rerunning _dl_lookup_symbol_x, compute symbol_scope again in case we unlocked the scope. * elf/dl-runtime.c (_dl_fixup): Pass DL_LOOKUP_SCOPE_LOCK to _dl_lookup_symbol_x in case we locked the scope. (_dl_profile_fixup): Likewise. * elf/dl-sym.c (do_sym): In flags passed to call_dl_lookup, also set DL_LOOKUP_SCOPE_LOCK.
Diffstat (limited to 'elf/dl-runtime.c')
-rw-r--r--elf/dl-runtime.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index afc99f6150..9ecf62b436 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -1,5 +1,5 @@
/* On-demand PLT fixup for shared objects.
- Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -93,14 +93,20 @@ _dl_fixup (
version = NULL;
}
+ /* We need to keep the scope around so do some locking. This is
+ not necessary for objects which cannot be unloaded or when
+ we are not using any threads (yet). */
+ int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
- __rtld_mrlock_lock (l->l_scope_lock);
+ {
+ __rtld_mrlock_lock (l->l_scope_lock);
+ flags |= DL_LOOKUP_SCOPE_LOCK;
+ }
- result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
- l->l_scope, version, ELF_RTYPE_CLASS_PLT,
- DL_LOOKUP_ADD_DEPENDENCY, NULL);
+ result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
+ version, ELF_RTYPE_CLASS_PLT, flags, NULL);
- if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
+ if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0)
__rtld_mrlock_unlock (l->l_scope_lock);
/* Currently result contains the base load address (or link map)
@@ -181,15 +187,21 @@ _dl_profile_fixup (
version = NULL;
}
+ /* We need to keep the scope around so do some locking. This is
+ not necessary for objects which cannot be unloaded or when
+ we are not using any threads (yet). */
+ int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
- __rtld_mrlock_lock (l->l_scope_lock);
+ {
+ __rtld_mrlock_lock (l->l_scope_lock);
+ flags |= DL_LOOKUP_SCOPE_LOCK;
+ }
- result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym,
- l->l_scope, version,
- ELF_RTYPE_CLASS_PLT,
- DL_LOOKUP_ADD_DEPENDENCY, NULL);
+ result = _dl_lookup_symbol_x (strtab + refsym->st_name, l,
+ &defsym, l->l_scope, version,
+ ELF_RTYPE_CLASS_PLT, flags, NULL);
- if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
+ if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0)
__rtld_mrlock_unlock (l->l_scope_lock);
/* Currently result contains the base load address (or link map)