This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Update MIPS dl-lookup.c


I've updated the MIPS dl-lookup.c for a recent change to the generic 
version.

diff --git a/ChangeLog.mips b/ChangeLog.mips
index 2edc425..272b2f3 100644
--- a/ChangeLog.mips
+++ b/ChangeLog.mips
@@ -1,3 +1,7 @@
+2010-03-24  Joseph Myers  <joseph@codesourcery.com>
+
+	* sysdeps/mips/dl-lookup.c: Update from generic version.
+
 2010-03-23  Mischa Jonker  <mischa.jonker@viragelogic.com>
 
 	[BZ #11291]
diff --git a/sysdeps/mips/dl-lookup.c b/sysdeps/mips/dl-lookup.c
index a9fff59..4090efe 100644
--- a/sysdeps/mips/dl-lookup.c
+++ b/sysdeps/mips/dl-lookup.c
@@ -1,6 +1,7 @@
 /* Look up a symbol in the loaded objects.
    MIPS/Linux version - special handling of non-PIC undefined symbol rules.
-   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
@@ -431,6 +432,20 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
 		  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);
@@ -934,13 +949,48 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 	{
 	  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;
+	  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)

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]