mirror of git://sourceware.org/git/glibc.git
* 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.
This commit is contained in:
parent
fb453d084d
commit
4e35ef2c71
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2007-01-15 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2007-01-13 Ulrich Drepper <drepper@redhat.com>
|
2007-01-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* inet/Makefile: Define CFLAGS-getsrvbynm_r.c and
|
* inet/Makefile: Define CFLAGS-getsrvbynm_r.c and
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Look up a symbol in the loaded objects.
|
/* Look up a symbol in the loaded objects.
|
||||||
Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc.
|
Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
#include <ldsodefs.h>
|
#include <ldsodefs.h>
|
||||||
#include <dl-hash.h>
|
#include <dl-hash.h>
|
||||||
#include <dl-machine.h>
|
#include <dl-machine.h>
|
||||||
|
#include <sysdep-cancel.h>
|
||||||
#include <bits/libc-lock.h>
|
#include <bits/libc-lock.h>
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ dl_new_hash (const char *s)
|
||||||
/* Add extra dependency on MAP to UNDEF_MAP. */
|
/* Add extra dependency on MAP to UNDEF_MAP. */
|
||||||
static int
|
static int
|
||||||
internal_function
|
internal_function
|
||||||
add_dependency (struct link_map *undef_map, struct link_map *map)
|
add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
|
||||||
{
|
{
|
||||||
struct link_map **list;
|
struct link_map **list;
|
||||||
struct link_map *runp;
|
struct link_map *runp;
|
||||||
|
@ -98,8 +99,18 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
|
||||||
if (undef_map == map)
|
if (undef_map == map)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Make sure nobody can unload the object while we are at it. */
|
/* Make sure nobody can unload the object while we are at it.
|
||||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
If we hold a scope lock drop it now to avoid ABBA locking problems. */
|
||||||
|
if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0 && !RTLD_SINGLE_THREAD_P)
|
||||||
|
{
|
||||||
|
__rtld_mrlock_unlock (undef_map->l_scope_lock);
|
||||||
|
|
||||||
|
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||||
|
|
||||||
|
__rtld_mrlock_lock (undef_map->l_scope_lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||||
|
|
||||||
/* Avoid references to objects which cannot be unloaded anyway. */
|
/* Avoid references to objects which cannot be unloaded anyway. */
|
||||||
if (map->l_type != lt_loaded
|
if (map->l_type != lt_loaded
|
||||||
|
@ -226,9 +237,10 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
|
||||||
|
|
||||||
bump_num_relocations ();
|
bump_num_relocations ();
|
||||||
|
|
||||||
/* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look
|
/* No other flag than DL_LOOKUP_ADD_DEPENDENCY and DL_LOOKUP_SCOPE_LOCK
|
||||||
up a versioned symbol. */
|
is allowed if we look up a versioned symbol. */
|
||||||
assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY);
|
assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY
|
||||||
|
| DL_LOOKUP_SCOPE_LOCK)) == 0);
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
if (__builtin_expect (skip_map != NULL, 0))
|
if (__builtin_expect (skip_map != NULL, 0))
|
||||||
|
@ -338,12 +350,13 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
|
||||||
runtime lookups. */
|
runtime lookups. */
|
||||||
&& (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
|
&& (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
|
||||||
/* Add UNDEF_MAP to the dependencies. */
|
/* Add UNDEF_MAP to the dependencies. */
|
||||||
&& add_dependency (undef_map, current_value.m) < 0)
|
&& add_dependency (undef_map, current_value.m, flags) < 0)
|
||||||
/* Something went wrong. Perhaps the object we tried to reference
|
/* Something went wrong. Perhaps the object we tried to reference
|
||||||
was just removed. Try finding another definition. */
|
was just removed. Try finding another definition. */
|
||||||
return _dl_lookup_symbol_x (undef_name, undef_map, ref,
|
return _dl_lookup_symbol_x (undef_name, undef_map, ref,
|
||||||
symbol_scope, version, type_class,
|
(flags & DL_LOOKUP_SCOPE_LOCK) == 0
|
||||||
flags, skip_map);
|
? symbol_scope : undef_map->l_scope, version,
|
||||||
|
type_class, flags, skip_map);
|
||||||
|
|
||||||
/* The object is used. */
|
/* The object is used. */
|
||||||
current_value.m->l_used = 1;
|
current_value.m->l_used = 1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* On-demand PLT fixup for shared objects.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -93,14 +93,20 @@ _dl_fixup (
|
||||||
version = NULL;
|
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)
|
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,
|
result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
|
||||||
l->l_scope, version, ELF_RTYPE_CLASS_PLT,
|
version, ELF_RTYPE_CLASS_PLT, flags, NULL);
|
||||||
DL_LOOKUP_ADD_DEPENDENCY, 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);
|
__rtld_mrlock_unlock (l->l_scope_lock);
|
||||||
|
|
||||||
/* Currently result contains the base load address (or link map)
|
/* Currently result contains the base load address (or link map)
|
||||||
|
@ -181,15 +187,21 @@ _dl_profile_fixup (
|
||||||
version = NULL;
|
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)
|
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,
|
result = _dl_lookup_symbol_x (strtab + refsym->st_name, l,
|
||||||
l->l_scope, version,
|
&defsym, l->l_scope, version,
|
||||||
ELF_RTYPE_CLASS_PLT,
|
ELF_RTYPE_CLASS_PLT, flags, NULL);
|
||||||
DL_LOOKUP_ADD_DEPENDENCY, 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);
|
__rtld_mrlock_unlock (l->l_scope_lock);
|
||||||
|
|
||||||
/* Currently result contains the base load address (or link map)
|
/* Currently result contains the base load address (or link map)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Look up a symbol in a shared object loaded by `dlopen'.
|
/* Look up a symbol in a shared object loaded by `dlopen'.
|
||||||
Copyright (C) 1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc.
|
Copyright (C) 1999-2002,2004,2006,2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -126,7 +126,7 @@ do_sym (void *handle, const char *name, void *who,
|
||||||
args.name = name;
|
args.name = name;
|
||||||
args.map = match;
|
args.map = match;
|
||||||
args.vers = vers;
|
args.vers = vers;
|
||||||
args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
|
args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_SCOPE_LOCK;
|
||||||
args.refp = &ref;
|
args.refp = &ref;
|
||||||
|
|
||||||
const char *objname;
|
const char *objname;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Run-time dynamic linker data structures for loaded ELF shared objects.
|
/* Run-time dynamic linker data structures for loaded ELF shared objects.
|
||||||
Copyright (C) 1995-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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -838,7 +838,9 @@ enum
|
||||||
DL_LOOKUP_ADD_DEPENDENCY = 1,
|
DL_LOOKUP_ADD_DEPENDENCY = 1,
|
||||||
/* Return most recent version instead of default version for
|
/* Return most recent version instead of default version for
|
||||||
unversioned lookup. */
|
unversioned lookup. */
|
||||||
DL_LOOKUP_RETURN_NEWEST = 2
|
DL_LOOKUP_RETURN_NEWEST = 2,
|
||||||
|
/* Set if the scopr lock in the UNDEF_MAP is taken. */
|
||||||
|
DL_LOOKUP_SCOPE_LOCK = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Lookup versioned symbol. */
|
/* Lookup versioned symbol. */
|
||||||
|
@ -847,7 +849,7 @@ extern lookup_t _dl_lookup_symbol_x (const char *undef,
|
||||||
const ElfW(Sym) **sym,
|
const ElfW(Sym) **sym,
|
||||||
struct r_scope_elem *symbol_scope[],
|
struct r_scope_elem *symbol_scope[],
|
||||||
const struct r_found_version *version,
|
const struct r_found_version *version,
|
||||||
int type_class, int explicit,
|
int type_class, int flags,
|
||||||
struct link_map *skip_map)
|
struct link_map *skip_map)
|
||||||
internal_function attribute_hidden;
|
internal_function attribute_hidden;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue