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