--- ../elfref/do-lookup.h 2009-12-26 04:11:18.000000000 +0100 +++ elf/do-lookup.h 2009-12-26 23:32:08.000000000 +0100 @@ -36,12 +36,12 @@ protected by GSCOPE. A read barrier here might be to expensive. */ __asm volatile ("" : "+r" (n), "+m" (scope->r_list)); struct link_map **list = scope->r_list; + int strength= result->s ? 2 : 0; do { /* These variables are used in the nested function. */ Elf_Symndx symidx; - int num_versions = 0; const ElfW(Sym) *versioned_sym = NULL; const struct link_map *map = list[i]->l_real; @@ -113,10 +113,13 @@ It would also be a bug in the object since it means that the list of required versions is incomplete and so the tests in dl-version.c haven't found a problem.*/ - assert (version->filename == NULL - || ! _dl_name_match_p (version->filename, map)); +// assert (version->filename == NULL +// || ! _dl_name_match_p (version->filename, map)); /* Otherwise we accept the symbol. */ + if(!versioned_sym) + versioned_sym= sym; + return NULL; } else { @@ -158,7 +161,7 @@ { /* Don't accept hidden symbols. */ if ((verstab[symidx] & 0x8000) == 0 - && num_versions++ == 0) + && !versioned_sym) /* No version so far. */ versioned_sym = sym; @@ -224,25 +227,25 @@ } } - /* If we have seen exactly one versioned symbol while we are - looking for an unversioned symbol and the version is not the - default version we still accept this symbol since there are - no possible ambiguities. */ - sym = num_versions == 1 ? versioned_sym : NULL; + /* Take the first approximate match if no exact match is available */ + sym = versioned_sym; if (sym != NULL) { + int new_strength; found_it: + new_strength= sym == versioned_sym ? 1 : 2; switch (ELFW(ST_BIND) (sym->st_info)) { case STB_WEAK: /* Weak definition. Use this value if we don't find another. */ if (__builtin_expect (GLRO(dl_dynamic_weak), 0)) { - if (! result->s) + if (strength < new_strength) { result->s = sym; result->m = (struct link_map *) map; + strength= new_strength; } break; } @@ -256,8 +259,16 @@ #endif /* Global definition. Just what we need. */ + if(strength < new_strength + 2){ result->s = sym; result->m = (struct link_map *) map; + strength= new_strength + 2; +// _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu] scope=%u strength=%u\n", +// undef_name, +// map->l_name[0] ? map->l_name : rtld_progname, +// map->l_ns, (int)scope, strength); + } + if(strength == 4) return 1; default: /* Local symbols are ignored. */ @@ -267,12 +278,12 @@ /* If this current map is the one mentioned in the verneed entry and we have not found a weak entry, it is a bug. */ - if (symidx == STN_UNDEF && version != NULL && version->filename != NULL + if (symidx == STN_UNDEF && version != NULL && version->filename != NULL && strength<3 && __builtin_expect (_dl_name_match_p (version->filename, map), 0)) return -1; } while (++i < n); /* We have not found anything until now. */ - return 0; + return strength>=3; }