mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Fix handling of STB_GNU_UNIQUE in LD_TRACE_PRELINKING
This commit is contained in:
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2010-03-23 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-lookup.c (do_lookup_x): If tab->entries is NULL,
|
||||||
|
but tab->size != 0, just unlock and goto success, without
|
||||||
|
allocating anything or entering anything into the hash table.
|
||||||
|
(_dl_debug_bindings): Temporarily set tab->entries to NULL
|
||||||
|
around do_lookup_x in undef_map->l_local_scope[0]. If
|
||||||
|
undef_map->l_symbolic_in_local_scope, lookup also in
|
||||||
|
symbolic_searchlist of following libraries in l_local_scope
|
||||||
|
that have DT_SYMBOLIC set.
|
||||||
|
* elf/dl-deps.c (_dl_map_object_deps): Compute
|
||||||
|
l_symbolic_in_local_scope.
|
||||||
|
* include/link.h (struct link_map): Add l_symbolic_in_local_scope
|
||||||
|
bitfield.
|
||||||
|
|
||||||
2010-03-24 Ulrich Drepper <drepper@redhat.com>
|
2010-03-24 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
[BZ #11410]
|
[BZ #11410]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Load the dependencies of a mapped object.
|
/* Load the dependencies of a mapped object.
|
||||||
Copyright (C) 1996-2003, 2004, 2005, 2006, 2007
|
Copyright (C) 1996-2003, 2004, 2005, 2006, 2007, 2010
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -554,7 +554,12 @@ Filters not supported with LD_TRACE_PRELINKING"));
|
|||||||
cnt = _dl_build_local_scope (l_initfini, l);
|
cnt = _dl_build_local_scope (l_initfini, l);
|
||||||
assert (cnt <= nlist);
|
assert (cnt <= nlist);
|
||||||
for (j = 0; j < cnt; j++)
|
for (j = 0; j < cnt; j++)
|
||||||
l_initfini[j]->l_reserved = 0;
|
{
|
||||||
|
l_initfini[j]->l_reserved = 0;
|
||||||
|
if (j && __builtin_expect (l_initfini[j]->l_info[DT_SYMBOLIC]
|
||||||
|
!= NULL, 0))
|
||||||
|
l->l_symbolic_in_local_scope = true;
|
||||||
|
}
|
||||||
|
|
||||||
l->l_local_scope[0] =
|
l->l_local_scope[0] =
|
||||||
(struct r_scope_elem *) malloc (sizeof (struct r_scope_elem)
|
(struct r_scope_elem *) malloc (sizeof (struct r_scope_elem)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* Look up a symbol in the loaded objects.
|
/* Look up a symbol in the loaded objects.
|
||||||
Copyright (C) 1995-2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
Copyright (C) 1995-2005, 2006, 2007, 2009, 2010
|
||||||
|
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
|
||||||
@ -414,6 +415,20 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
|
|||||||
assert (!RTLD_CHECK_FOREIGN_CALL);
|
assert (!RTLD_CHECK_FOREIGN_CALL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* If tab->entries is NULL, but tab->size is not, it means
|
||||||
|
this is the second, conflict finding, lookup for
|
||||||
|
LD_TRACE_PRELINKING in _dl_debug_bindings. Don't
|
||||||
|
allocate anything and don't enter anything into the
|
||||||
|
hash table. */
|
||||||
|
if (__builtin_expect (tab->size, 0))
|
||||||
|
{
|
||||||
|
assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
|
||||||
|
__rtld_lock_unlock_recursive (tab->lock);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INITIAL_NUNIQUE_SYM_TABLE 31
|
#define INITIAL_NUNIQUE_SYM_TABLE 31
|
||||||
size = INITIAL_NUNIQUE_SYM_TABLE;
|
size = INITIAL_NUNIQUE_SYM_TABLE;
|
||||||
entries = calloc (sizeof (struct unique_sym), size);
|
entries = calloc (sizeof (struct unique_sym), size);
|
||||||
@ -917,13 +932,48 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
|||||||
{
|
{
|
||||||
const uint_fast32_t new_hash = dl_new_hash (undef_name);
|
const uint_fast32_t new_hash = dl_new_hash (undef_name);
|
||||||
unsigned long int old_hash = 0xffffffff;
|
unsigned long int old_hash = 0xffffffff;
|
||||||
|
struct unique_sym *saved_entries
|
||||||
|
= GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries;
|
||||||
|
|
||||||
|
GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = NULL;
|
||||||
do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
|
do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
|
||||||
undef_map->l_local_scope[0], 0, version, 0, NULL,
|
undef_map->l_local_scope[0], 0, version, 0, NULL,
|
||||||
type_class, undef_map);
|
type_class, undef_map);
|
||||||
|
|
||||||
if (val.s != value->s || val.m != value->m)
|
if (val.s != value->s || val.m != value->m)
|
||||||
conflict = 1;
|
conflict = 1;
|
||||||
|
else if (__builtin_expect (undef_map->l_symbolic_in_local_scope, 0)
|
||||||
|
&& val.s
|
||||||
|
&& __builtin_expect (ELFW(ST_BIND) (val.s->st_info),
|
||||||
|
STB_GLOBAL) == STB_GNU_UNIQUE)
|
||||||
|
{
|
||||||
|
/* If it is STB_GNU_UNIQUE and undef_map's l_local_scope
|
||||||
|
contains any DT_SYMBOLIC libraries, unfortunately there
|
||||||
|
can be conflicts even if the above is equal. As symbol
|
||||||
|
resolution goes from the last library to the first and
|
||||||
|
if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC
|
||||||
|
library, it would be the one that is looked up. */
|
||||||
|
struct sym_val val2 = { NULL, NULL };
|
||||||
|
size_t n;
|
||||||
|
struct r_scope_elem *scope = undef_map->l_local_scope[0];
|
||||||
|
|
||||||
|
for (n = 0; n < scope->r_nlist; n++)
|
||||||
|
if (scope->r_list[n] == val.m)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (n++; n < scope->r_nlist; n++)
|
||||||
|
if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL
|
||||||
|
&& do_lookup_x (undef_name, new_hash, &old_hash, *ref,
|
||||||
|
&val2,
|
||||||
|
&scope->r_list[n]->l_symbolic_searchlist,
|
||||||
|
0, version, 0, NULL, type_class,
|
||||||
|
undef_map) > 0)
|
||||||
|
{
|
||||||
|
conflict = 1;
|
||||||
|
val = val2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value->s)
|
if (value->s)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Data structure for communication from the run-time dynamic linker for
|
/* Data structure for communication from the run-time dynamic linker for
|
||||||
loaded ELF shared objects.
|
loaded ELF shared objects.
|
||||||
Copyright (C) 1995-2006, 2007, 2009 Free Software Foundation, Inc.
|
Copyright (C) 1995-2006, 2007, 2009, 2010 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
|
||||||
@ -188,6 +188,10 @@ struct link_map
|
|||||||
unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
|
unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
|
||||||
mprotected or if no holes are present at
|
mprotected or if no holes are present at
|
||||||
all. */
|
all. */
|
||||||
|
unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope
|
||||||
|
during LD_TRACE_PRELINKING=1
|
||||||
|
contains any DT_SYMBOLIC
|
||||||
|
libraries. */
|
||||||
|
|
||||||
/* Collected information about own RPATH directories. */
|
/* Collected information about own RPATH directories. */
|
||||||
struct r_search_path_struct l_rpath_dirs;
|
struct r_search_path_struct l_rpath_dirs;
|
||||||
|
Reference in New Issue
Block a user