PATCH: A symbol version bug

H. J. Lu hjl@lucon.org
Wed May 14 07:15:00 GMT 2003


On Tue, May 13, 2003 at 05:20:26PM -0700, H. J. Lu wrote:
> Michael found a bug between binutils and glibc. ld.so assumes the
> first symbol from the hash table is the oldest (default) version.
> Unfortunately, it is not always true. The question is if glibc
> should depend on it or ld should guarantee it.
> 
> 

I believe it is a glibc bug. The problem is we didn't handle hidden
base version right. This patch should fix it.


H.J.
-------------- next part --------------
2003-05-14  <hongjiu.lu@intel.com>

	* elf/do-lookup.h (FCT): Try the base version, the first
	version and then the default version, in that order, for
	the old unversioned reference.

--- elf/do-lookup.h.base	2003-05-13 14:37:50.000000000 -0700
+++ elf/do-lookup.h	2003-05-14 00:00:09.000000000 -0700
@@ -53,6 +53,8 @@ FCT (const char *undef_name, unsigned lo
 #if ! VERSIONED
       int num_versions = 0;
       const ElfW(Sym) *versioned_sym = NULL;
+      const ElfW(Sym) *first_version = NULL;
+      const ElfW(Sym) *base_version = NULL;
 #endif
 
       map = list[i];
@@ -155,13 +157,22 @@ FCT (const char *undef_name, unsigned lo
 	     public interface should be returned.  */
 	  if (verstab != NULL)
 	    {
-	      if ((verstab[symidx] & 0x7fff)
-		  >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
+	      ElfW(Half) ndx = verstab[symidx] & 0x7fff;
+	      if (ndx >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
 		{
 		  /* Don't accept hidden symbols.  */
 		  if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0)
 		    /* No version so far.  */
 		    versioned_sym = sym;
+		  
+		  continue;
+		}
+	      if ((flags & DL_LOOKUP_RETURN_NEWEST) == 0)
+		{
+		  if (ndx == 1)
+		    base_version = sym;
+		  else if (ndx == 2)
+		    first_version = sym;
 
 		  continue;
 		}
@@ -179,7 +190,8 @@ FCT (const char *undef_name, unsigned lo
 #if VERSIONED
       sym = NULL;
 #else
-      sym = num_versions == 1 ? versioned_sym : NULL;
+      sym = base_version ?: (first_version ?: (num_versions == 1
+					       ? versioned_sym : NULL));
 #endif
 
       if (sym != NULL)


More information about the Libc-alpha mailing list