PR ld/10515
authorAlan Modra <amodra@gmail.com>
Wed, 26 Aug 2009 01:21:56 +0000 (01:21 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 26 Aug 2009 01:21:56 +0000 (01:21 +0000)
* linker.c (bfd_find_version_for_sym): Override a "*" match by any
other wildcard match.  Warn on multiple wildcard matches.

bfd/ChangeLog
bfd/linker.c

index 149cf63ac12a5f1685292195ccca197ba9b5a4b5..8cb822af70d895fb5bcb86bc4bfc97f533ba6040 100644 (file)
@@ -1,3 +1,9 @@
+2009-08-26  Alan Modra  <amodra@bigpond.net.au>
+
+       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  <Ralf.Wildenhues@gmx.de>
 
        * Makefile.am (libbfd_la_LDFLAGS): Initialize early, to allow
index 1c22beb99057214e549862557af83ac7c3f249a6..8fe64e62c6b7eeac912cbd0d1408bcda028a542f 100644 (file)
@@ -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;
 }
-