include/
authorAlan Modra <amodra@gmail.com>
Wed, 26 Nov 2008 01:04:17 +0000 (01:04 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 26 Nov 2008 01:04:17 +0000 (01:04 +0000)
PR 7047
* bfdlink.h (struct bfd_elf_version_expr): Delete "symbol".
Add "literal".
bfd/
PR 7047
* configure.in: Bump version.
* configure: Regenerate.
* elflink.c (_bfd_elf_link_assign_sym_version): Continue matching
against version nodes when a global match is a wildcard.  Similarly
continue matching on local wildcard matches, rather than only
continuing for "*".  Have any global wildcard match override a
local wildcard match.  Correct logic hiding unversioned symbol.
(bfd_elf_size_dynamic_sections): Update for changes to struct
bfd_elf_version_expr.
ld/
PR 7047
* emultempl/ppc64elf.em (gld${EMULATION_NAME}_new_vers_pattern): Update
for changes to struct bfd_elf_version_expr.
* ldlang.c (lang_vers_match, version_expr_head_hash): Likewise.
(version_expr_head_eq, lang_finalize_version_expr_head): Likewise.
(lang_register_vers_node): Likewise.
(lang_new_vers_pattern): Likewise.  Ensure "literal" is set when
no glob chars found in "pattern".
(realsymbol): Correct backslash quote logic.
* ld.texinfo (VERSION): Warn about global wildcards.

bfd/ChangeLog
bfd/configure
bfd/configure.in
bfd/elflink.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/emultempl/ppc64elf.em
ld/ld.texinfo
ld/ldlang.c

index 9d4a323dd7f79182892daee19abbb8661a3b35cd..e0602882c9d960475a0fed4d2c91ecea9eb57f5e 100644 (file)
@@ -1,3 +1,16 @@
+2008-11-26  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 7047
+       * configure.in: Bump version.
+       * configure: Regenerate.
+       * elflink.c (_bfd_elf_link_assign_sym_version): Continue matching
+       against version nodes when a global match is a wildcard.  Similarly
+       continue matching on local wildcard matches, rather than only
+       continuing for "*".  Have any global wildcard match override a
+       local wildcard match.  Correct logic hiding unversioned symbol.
+       (bfd_elf_size_dynamic_sections): Update for changes to struct
+       bfd_elf_version_expr.
+
 2008-11-25  Joel Brobecker  <brobecker@adacore.com>
 
        * configure.in: Deactivate large-file support on native x86-solaris
index 042f5d1f74c7e478fa38fef52ac2db83c48807f6..8ff1234a1a7ad83ab06c1d55885c4bfbd790131f 100755 (executable)
@@ -3033,7 +3033,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=bfd
- VERSION=2.19.50
+ VERSION=2.19.51
 
 
 cat >>confdefs.h <<_ACEOF
index 7297ee0e7094c2a390c1735c7a152273063d714b..47ef10ccdfa65193c7c7fd57bac2ebb99f82bde9 100644 (file)
@@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([libbfd.c])
 AC_CANONICAL_TARGET
 AC_ISC_POSIX
 
-AM_INIT_AUTOMAKE(bfd, 2.19.50)
+AM_INIT_AUTOMAKE(bfd, 2.19.51)
 
 dnl These must be called before LT_INIT, because it may want
 dnl to call AC_CHECK_PROG.
index ce1dff7d012bc982ffb7d76d379dc2bffc5b2ed9..43379c71a6e6a1c7beb9676e0c15e28090b627d4 100644 (file)
@@ -2010,41 +2010,36 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
   if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL)
     {
       struct bfd_elf_version_tree *t;
-      struct bfd_elf_version_tree *local_ver;
+      struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
       struct bfd_elf_version_expr *d;
 
       /* See if can find what version this symbol is in.  If the
         symbol is supposed to be local, then don't actually register
         it.  */
       local_ver = NULL;
+      global_ver = NULL;
+      exist_ver = NULL;
       for (t = sinfo->verdefs; t != NULL; t = t->next)
        {
          if (t->globals.list != NULL)
            {
-             bfd_boolean matched;
-
-             matched = FALSE;
              d = NULL;
              while ((d = (*t->match) (&t->globals, d,
                                       h->root.root.string)) != NULL)
-               if (d->symver)
-                 matched = TRUE;
-               else
-                 {
-                   /* There is a version without definition.  Make
-                      the symbol the default definition for this
-                      version.  */
-                   h->verinfo.vertree = t;
-                   local_ver = NULL;
-                   d->script = 1;
+               {
+                 global_ver = t;
+                 local_ver = NULL;
+                 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;
-                 }
+               }
+
              if (d != NULL)
                break;
-             else if (matched)
-               /* There is no undefined version for this symbol. Hide the
-                  default one.  */
-               (*bed->elf_backend_hide_symbol) (info, h, TRUE);
            }
 
          if (t->locals.list != NULL)
@@ -2054,11 +2049,14 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
                                       h->root.root.string)) != NULL)
                {
                  local_ver = t;
-                 /* If the match is "*", keep looking for a more
-                    explicit, perhaps even global, match.
-                    XXX: Shouldn't this be !d->wildcard instead?  */
-                 if (d->pattern[0] != '*' || d->pattern[1] != '\0')
-                   break;
+                 /* 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;
+                     break;
+                   }
                }
 
              if (d != NULL)
@@ -2066,14 +2064,22 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
            }
        }
 
-      if (local_ver != NULL)
+      if (global_ver != NULL)
+       {
+         h->verinfo.vertree = global_ver;
+         /* If we already have a versioned symbol that matches the
+            node for this symbol, then we don't want to create a
+            duplicate from the unversioned symbol.  Instead hide the
+            unversioned symbol.  */
+         if (exist_ver == global_ver)
+           (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+       }
+      else if (local_ver != NULL)
        {
          h->verinfo.vertree = local_ver;
-         if (h->dynindx != -1
-             && ! info->export_dynamic)
-           {
-             (*bed->elf_backend_hide_symbol) (info, h, TRUE);
-           }
+         if (!info->export_dynamic
+             || exist_ver == local_ver)
+           (*bed->elf_backend_hide_symbol) (info, h, TRUE);
        }
     }
 
@@ -5566,14 +5572,14 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
       /* Make all global versions with definition.  */
       for (t = verdefs; t != NULL; t = t->next)
        for (d = t->globals.list; d != NULL; d = d->next)
-         if (!d->symver && d->symbol)
+         if (!d->symver && d->literal)
            {
              const char *verstr, *name;
              size_t namelen, verlen, newlen;
              char *newname, *p;
              struct elf_link_hash_entry *newh;
 
-             name = d->symbol;
+             name = d->pattern;
              namelen = strlen (name);
              verstr = t->name;
              verlen = strlen (verstr);
@@ -5631,7 +5637,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
          all_defined = TRUE;
          for (t = verdefs; t != NULL; t = t->next)
            for (d = t->globals.list; d != NULL; d = d->next)
-             if (!d->symver && !d->script)
+             if (d->literal && !d->symver && !d->script)
                {
                  (*_bfd_error_handler)
                    (_("%s: undefined version: %s"),
index c6a6caef48155184940f619a3e3878a8305bf06b..96c84746e20f3a0eb50c19b320ace1464b08c265 100644 (file)
@@ -1,3 +1,9 @@
+2008-11-26  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 7047
+       * bfdlink.h (struct bfd_elf_version_expr): Delete "symbol".
+       Add "literal".
+
 2008-11-21  Sterling Augustine  <sterling@tensilica.com>
 
        * xtensa-isa-internal.h (XTENSA_STATE_IS_SHARED_OR): New flag.
index d27b5388d3b61c9c2c7ed432902d1e96bf6431fd..51c5b15cd68187a497c1b182c6b36b75c657aaba 100644 (file)
@@ -707,8 +707,8 @@ struct bfd_elf_version_expr
   struct bfd_elf_version_expr *next;
   /* Glob pattern.  */
   const char *pattern;
-  /* NULL for a glob pattern, otherwise a straight symbol.  */
-  const char *symbol;
+  /* Set if pattern is not a glob.  */
+  unsigned int literal : 1;
   /* Defined by ".symver".  */
   unsigned int symver : 1;
   /* Defined by version script.  */
index 4e93eb233b52569a5a8bf5a7a8cdfa698a28d6c4..e9cf92dd1991e3767d708a28f6dc29e1abbc4d38 100644 (file)
@@ -1,3 +1,16 @@
+2008-11-26  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 7047
+       * emultempl/ppc64elf.em (gld${EMULATION_NAME}_new_vers_pattern): Update
+       for changes to struct bfd_elf_version_expr.
+       * ldlang.c (lang_vers_match, version_expr_head_hash): Likewise.
+       (version_expr_head_eq, lang_finalize_version_expr_head): Likewise.
+       (lang_register_vers_node): Likewise.
+       (lang_new_vers_pattern): Likewise.  Ensure "literal" is set when
+       no glob chars found in "pattern".
+       (realsymbol): Correct backslash quote logic.
+       * ld.texinfo (VERSION): Warn about global wildcards.
+
 2008-11-24  Alan Modra  <amodra@bigpond.net.au>
 
        * ldlang.c (lang_record_phdrs): Don't add orphans to PT_INTERP header.
index 9a49fa5a34174cc1f92babbdc832e2da303c3bdf..eff8dff4a5635586551a556ee2d438db9911942b 100644 (file)
@@ -416,29 +416,18 @@ gld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
   char *dot_pat;
 
   if (!dotsyms
-      || (entry->pattern != NULL
-         && (entry->pattern[0] == '*' || entry->pattern[0] == '.')))
+      || entry->pattern[0] == '.'
+      || (!entry->literal && entry->pattern[0] == '*'))
     return entry;
 
   dot_entry = xmalloc (sizeof *dot_entry);
   *dot_entry = *entry;
   dot_entry->next = entry;
-  if (entry->pattern != NULL)
-    {
-      len = strlen (entry->pattern) + 2;
-      dot_pat = xmalloc (len);
-      dot_pat[0] = '.';
-      memcpy (dot_pat + 1, entry->pattern, len - 1);
-      dot_entry->pattern = dot_pat;
-    }
-  if (entry->symbol != NULL)
-    {
-      len = strlen (entry->symbol) + 2;
-      dot_pat = xmalloc (len);
-      dot_pat[0] = '.';
-      memcpy (dot_pat + 1, entry->symbol, len - 1);
-      dot_entry->symbol = dot_pat;
-    }
+  len = strlen (entry->pattern) + 2;
+  dot_pat = xmalloc (len);
+  dot_pat[0] = '.';
+  memcpy (dot_pat + 1, entry->pattern, len - 1);
+  dot_entry->pattern = dot_pat;
   return dot_entry;
 }
 
index 83c8ac4f0e793e8b4bad0533e009c8c0b76458ee..4e8cf8a6f82636013cb405b13ea50bca6a393f30 100644 (file)
@@ -4561,7 +4561,11 @@ When the linker finds a symbol defined in a library which is not
 specifically bound to a version node, it will effectively bind it to an
 unspecified base version of the library.  You can bind all otherwise
 unspecified symbols to a given version node by using @samp{global: *;}
-somewhere in the version script.
+somewhere in the version script.  Note that it's slightly crazy to use
+wildcards in a global spec except on the last version node.  Global
+wildcards elsewhere run the risk of accidentally adding symbols to the
+set exported for an old version.  That's wrong since older versions
+ought to have a fixed set of symbols.
 
 The names of the version nodes have no specific meaning other than what
 they might suggest to the person reading them.  The @samp{2.0} version
index 6668c59e523a7bd75e554acb0ffc4196492219f1..855e7951f4d86ed03445e3d692a05b0378619846 100644 (file)
@@ -6989,7 +6989,7 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
        java_sym = sym;
     }
 
-  if (head->htab && (prev == NULL || prev->symbol))
+  if (head->htab && (prev == NULL || prev->literal))
     {
       struct bfd_elf_version_expr e;
 
@@ -6998,9 +6998,9 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
        case 0:
          if (head->mask & BFD_ELF_VERSION_C_TYPE)
            {
-             e.symbol = sym;
+             e.pattern = sym;
              expr = htab_find (head->htab, &e);
-             while (expr && strcmp (expr->symbol, sym) == 0)
+             while (expr && strcmp (expr->pattern, sym) == 0)
                if (expr->mask == BFD_ELF_VERSION_C_TYPE)
                  goto out_ret;
                else
@@ -7010,9 +7010,9 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
        case BFD_ELF_VERSION_C_TYPE:
          if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
            {
-             e.symbol = cxx_sym;
+             e.pattern = cxx_sym;
              expr = htab_find (head->htab, &e);
-             while (expr && strcmp (expr->symbol, cxx_sym) == 0)
+             while (expr && strcmp (expr->pattern, cxx_sym) == 0)
                if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
                  goto out_ret;
                else
@@ -7022,9 +7022,9 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
        case BFD_ELF_VERSION_CXX_TYPE:
          if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
            {
-             e.symbol = java_sym;
+             e.pattern = java_sym;
              expr = htab_find (head->htab, &e);
-             while (expr && strcmp (expr->symbol, java_sym) == 0)
+             while (expr && strcmp (expr->pattern, java_sym) == 0)
                if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
                  goto out_ret;
                else
@@ -7037,7 +7037,7 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
     }
 
   /* Finally, try the wildcards.  */
-  if (prev == NULL || prev->symbol)
+  if (prev == NULL || prev->literal)
     expr = head->remaining;
   else
     expr = prev->next;
@@ -7070,7 +7070,7 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
 }
 
 /* Return NULL if the PATTERN argument is a glob pattern, otherwise,
-   return a string pointing to the symbol name.  */
+   return a pointer to the symbol name with any backslash quotes removed.  */
 
 static const char *
 realsymbol (const char *pattern)
@@ -7083,22 +7083,24 @@ realsymbol (const char *pattern)
     {
       /* It is a glob pattern only if there is no preceding
         backslash.  */
-      if (! backslash && (*p == '?' || *p == '*' || *p == '['))
-       {
-         free (symbol);
-         return NULL;
-       }
-
       if (backslash)
        {
          /* Remove the preceding backslash.  */
          *(s - 1) = *p;
+         backslash = FALSE;
          changed = TRUE;
        }
       else
-       *s++ = *p;
+       {
+         if (*p == '?' || *p == '*' || *p == '[')
+           {
+             free (symbol);
+             return NULL;
+           }
 
-      backslash = *p == '\\';
+         *s++ = *p;
+         backslash = *p == '\\';
+       }
     }
 
   if (changed)
@@ -7127,10 +7129,15 @@ lang_new_vers_pattern (struct bfd_elf_version_expr *orig,
 
   ret = xmalloc (sizeof *ret);
   ret->next = orig;
-  ret->pattern = literal_p ? NULL : new;
   ret->symver = 0;
   ret->script = 0;
-  ret->symbol = literal_p ? new : realsymbol (new);
+  ret->literal = TRUE;
+  ret->pattern = literal_p ? new : realsymbol (new);
+  if (ret->pattern == NULL)
+    {
+      ret->pattern = new;
+      ret->literal = FALSE;
+    }
 
   if (lang == NULL || strcasecmp (lang, "C") == 0)
     ret->mask = BFD_ELF_VERSION_C_TYPE;
@@ -7174,7 +7181,7 @@ version_expr_head_hash (const void *p)
 {
   const struct bfd_elf_version_expr *e = p;
 
-  return htab_hash_string (e->symbol);
+  return htab_hash_string (e->pattern);
 }
 
 static int
@@ -7183,7 +7190,7 @@ version_expr_head_eq (const void *p1, const void *p2)
   const struct bfd_elf_version_expr *e1 = p1;
   const struct bfd_elf_version_expr *e2 = p2;
 
-  return strcmp (e1->symbol, e2->symbol) == 0;
+  return strcmp (e1->pattern, e2->pattern) == 0;
 }
 
 static void
@@ -7195,7 +7202,7 @@ lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
 
   for (e = head->list; e; e = e->next)
     {
-      if (e->symbol)
+      if (e->literal)
        count++;
       head->mask |= e->mask;
     }
@@ -7209,7 +7216,7 @@ lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
       for (e = head->list; e; e = next)
        {
          next = e->next;
-         if (!e->symbol)
+         if (!e->literal)
            {
              *remaining_loc = e;
              remaining_loc = &e->next;
@@ -7234,14 +7241,14 @@ lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
                      last = e1;
                      e1 = e1->next;
                    }
-                 while (e1 && strcmp (e1->symbol, e->symbol) == 0);
+                 while (e1 && strcmp (e1->pattern, e->pattern) == 0);
 
                  if (last == NULL)
                    {
                      /* This is a duplicate.  */
                      /* FIXME: Memory leak.  Sometimes pattern is not
                         xmalloced alone, but in larger chunk of memory.  */
-                     /* free (e->symbol); */
+                     /* free (e->pattern); */
                      free (e);
                    }
                  else
@@ -7305,18 +7312,18 @@ lang_register_vers_node (const char *name,
        {
          struct bfd_elf_version_expr *e2;
 
-         if (t->locals.htab && e1->symbol)
+         if (t->locals.htab && e1->literal)
            {
              e2 = htab_find (t->locals.htab, e1);
-             while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
+             while (e2 && strcmp (e1->pattern, e2->pattern) == 0)
                {
                  if (e1->mask == e2->mask)
                    einfo (_("%X%P: duplicate expression `%s'"
-                            " in version information\n"), e1->symbol);
+                            " in version information\n"), e1->pattern);
                  e2 = e2->next;
                }
            }
-         else if (!e1->symbol)
+         else if (!e1->literal)
            for (e2 = t->locals.remaining; e2 != NULL; e2 = e2->next)
              if (strcmp (e1->pattern, e2->pattern) == 0
                  && e1->mask == e2->mask)
@@ -7331,19 +7338,19 @@ lang_register_vers_node (const char *name,
        {
          struct bfd_elf_version_expr *e2;
 
-         if (t->globals.htab && e1->symbol)
+         if (t->globals.htab && e1->literal)
            {
              e2 = htab_find (t->globals.htab, e1);
-             while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
+             while (e2 && strcmp (e1->pattern, e2->pattern) == 0)
                {
                  if (e1->mask == e2->mask)
                    einfo (_("%X%P: duplicate expression `%s'"
                             " in version information\n"),
-                          e1->symbol);
+                          e1->pattern);
                  e2 = e2->next;
                }
            }
-         else if (!e1->symbol)
+         else if (!e1->literal)
            for (e2 = t->globals.remaining; e2 != NULL; e2 = e2->next)
              if (strcmp (e1->pattern, e2->pattern) == 0
                  && e1->mask == e2->mask)