glibc/ld-prelink-unique.diff

58 lines
2.1 KiB
Diff

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].
--- libc/elf/dl-lookup.c.jj 2009-12-16 00:10:37.000000000 +0100
+++ libc/elf/dl-lookup.c 2010-03-23 11:03:45.850560036 +0100
@@ -1,5 +1,6 @@
/* 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.
The GNU C Library is free software; you can redistribute it and/or
@@ -414,6 +415,20 @@ do_lookup_x (const char *undef_name, uin
assert (!RTLD_CHECK_FOREIGN_CALL);
#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
size = INITIAL_NUNIQUE_SYM_TABLE;
entries = calloc (sizeof (struct unique_sym), size);
@@ -917,13 +932,17 @@ _dl_debug_bindings (const char *undef_na
{
const uint_fast32_t new_hash = dl_new_hash (undef_name);
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,
undef_map->l_local_scope[0], 0, version, 0, NULL,
type_class, undef_map);
if (val.s != value->s || val.m != value->m)
conflict = 1;
+ GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries;
}
if (value->s)