From 78a0329753c9a5597fbb269122ed394e421b1d0e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 26 Aug 2009 01:21:56 +0000 Subject: [PATCH] PR ld/10515 * linker.c (bfd_find_version_for_sym): Override a "*" match by any other wildcard match. Warn on multiple wildcard matches. --- bfd/ChangeLog | 6 ++++++ bfd/linker.c | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 149cf63ac1..8cb822af70 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2009-08-26 Alan Modra + + PR ld/10515 + * linker.c (bfd_find_version_for_sym): Override a "*" match by any + other wildcard match. Warn on multiple wildcard matches. + 2009-08-22 Ralf Wildenhues * Makefile.am (libbfd_la_LDFLAGS): Initialize early, to allow diff --git a/bfd/linker.c b/bfd/linker.c index 1c22beb990..8fe64e62c6 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -3271,14 +3271,18 @@ DESCRIPTION struct bfd_elf_version_tree * bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, - const char *sym_name, - bfd_boolean *hide) + const char *sym_name, + bfd_boolean *hide) { struct bfd_elf_version_tree *t; struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver; + struct bfd_elf_version_tree *star_local_ver, *star_global_ver; + unsigned int match_count = 0; local_ver = NULL; global_ver = NULL; + star_local_ver = NULL; + star_global_ver = NULL; exist_ver = NULL; for (t = verdefs; t != NULL; t = t->next) { @@ -3288,14 +3292,21 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL) { - global_ver = t; + ++match_count; + if (d->literal || strcmp (d->pattern, "*") != 0) + global_ver = t; + else + star_global_ver = t; if (d->symver) exist_ver = t; d->script = 1; /* If the match is a wildcard pattern, keep looking for a more explicit, perhaps even local, match. */ if (d->literal) - break; + { + match_count = 0; + break; + } } if (d != NULL) @@ -3308,13 +3319,19 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL) { - local_ver = t; + ++match_count; + if (d->literal || strcmp (d->pattern, "*") != 0) + local_ver = t; + else + star_local_ver = t; /* If the match is a wildcard pattern, keep looking for a more explicit, perhaps even global, match. */ if (d->literal) { /* An exact match overrides a global wildcard. */ global_ver = NULL; + star_global_ver = NULL; + match_count = 0; break; } } @@ -3324,6 +3341,14 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, } } + if (match_count > 1) + (*_bfd_error_handler) + (_("warning: multiple wildcard version script matches for %s\n"), + sym_name); + + if (global_ver == NULL && local_ver == NULL) + global_ver = star_global_ver; + if (global_ver != NULL) { /* If we already have a versioned symbol that matches the @@ -3334,6 +3359,9 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, return global_ver; } + if (local_ver == NULL) + local_ver = star_local_ver; + if (local_ver != NULL) { *hide = TRUE; @@ -3342,4 +3370,3 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, return NULL; } -