2010-03-23 Jakub Jelinek * 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)