bfd/ld: handle ABI prefixes in version scripts
authorMike Frysinger <vapier@gentoo.org>
Mon, 14 Feb 2011 17:03:45 +0000 (17:03 +0000)
committerMike Frysinger <vapier@gentoo.org>
Mon, 14 Feb 2011 17:03:45 +0000 (17:03 +0000)
The default language in version scripts is supposed to be C, but no
symbol demangling is performed on the symbols by default.  This makes
targets with a symbol prefix to fail with most version scripts out
there.  So strip away this prefix by default.

This fixes many tests (real world and ld's testsuite) for Blackfin
targets and doesn't seem to cause regressions for x86_64.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
bfd/ChangeLog
bfd/elflink.c
ld/ChangeLog
ld/ldlang.c

index 72b3c321d1b5461c6f4bb89ffea49ae74d0cd2ce..2f54729bf4386890af4e9f5055abb7bb65dde57a 100644 (file)
@@ -1,3 +1,8 @@
+2011-02-14  Mike Frysinger  <vapier@gentoo.org>
+
+       * elflink.c (bfd_elf_size_dynamic_sections): Add
+       bfd_get_symbol_leading_char to the start of newname.
+
 2011-02-13  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * configure: Regenerate.
index 79256bf6f6e177d5b1501e8234fee19dc7ecdcde..dffe0ae37b5ba4ea7d43f9c2bce9aa9acfa4a458 100644 (file)
@@ -5710,11 +5710,12 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
            {
              const char *verstr, *name;
              size_t namelen, verlen, newlen;
-             char *newname, *p;
+             char *newname, *p, leading_char;
              struct elf_link_hash_entry *newh;
 
+             leading_char = bfd_get_symbol_leading_char (output_bfd);
              name = d->pattern;
-             namelen = strlen (name);
+             namelen = strlen (name) + (leading_char != '\0');
              verstr = t->name;
              verlen = strlen (verstr);
              newlen = namelen + verlen + 3;
@@ -5722,7 +5723,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
              newname = (char *) bfd_malloc (newlen);
              if (newname == NULL)
                return FALSE;
-             memcpy (newname, name, namelen);
+             newname[0] = leading_char;
+             memcpy (newname + (leading_char != '\0'), name, namelen);
 
              /* Check the hidden versioned definition.  */
              p = newname + namelen;
index a57210e89f406b73aeb73df301ee62b3811a7ab3..1a0dd35cbd4bdcd3a511b72aa9adffa748ce712c 100644 (file)
@@ -1,3 +1,10 @@
+2011-02-14  Mike Frysinger  <vapier@gentoo.org>
+
+       * ldlang.c (lang_vers_match): Declare a new c_sym, assign it to
+       the bfd_demangle of sym, change users of sym to c_sym when not
+       already demangling, and free when done.  Change callers of
+       cplus_demangle to bfd_demangle.
+
 2011-02-14  Alan Modra  <amodra@gmail.com>
 
        * ldmain.c (remove_output): Rename to..
index 7ffe760371d11078ca77319a2a4667601521d4c3..7ffbf451e4e0fd5b7579a8a27b9ae08baef8136d 100644 (file)
@@ -7296,19 +7296,29 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
                 struct bfd_elf_version_expr *prev,
                 const char *sym)
 {
+  const char *c_sym;
   const char *cxx_sym = sym;
   const char *java_sym = sym;
   struct bfd_elf_version_expr *expr = NULL;
+  enum demangling_styles curr_style;
+
+  curr_style = CURRENT_DEMANGLING_STYLE;
+  cplus_demangle_set_style (no_demangling);
+  c_sym = bfd_demangle (link_info.output_bfd, sym, DMGL_NO_OPTS);
+  if (!c_sym)
+    c_sym = sym;
+  cplus_demangle_set_style (curr_style);
 
   if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
     {
-      cxx_sym = cplus_demangle (sym, DMGL_PARAMS | DMGL_ANSI);
+      cxx_sym = bfd_demangle (link_info.output_bfd, sym,
+                             DMGL_PARAMS | DMGL_ANSI);
       if (!cxx_sym)
        cxx_sym = sym;
     }
   if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
     {
-      java_sym = cplus_demangle (sym, DMGL_JAVA);
+      java_sym = bfd_demangle (link_info.output_bfd, sym, DMGL_JAVA);
       if (!java_sym)
        java_sym = sym;
     }
@@ -7322,10 +7332,10 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
        case 0:
          if (head->mask & BFD_ELF_VERSION_C_TYPE)
            {
-             e.pattern = sym;
+             e.pattern = c_sym;
              expr = (struct bfd_elf_version_expr *)
                   htab_find ((htab_t) head->htab, &e);
-             while (expr && strcmp (expr->pattern, sym) == 0)
+             while (expr && strcmp (expr->pattern, c_sym) == 0)
                if (expr->mask == BFD_ELF_VERSION_C_TYPE)
                  goto out_ret;
                else
@@ -7383,12 +7393,14 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
       else if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
        s = cxx_sym;
       else
-       s = sym;
+       s = c_sym;
       if (fnmatch (expr->pattern, s, 0) == 0)
        break;
     }
 
  out_ret:
+  if (c_sym != sym)
+    free ((char *) c_sym);
   if (cxx_sym != sym)
     free ((char *) cxx_sym);
   if (java_sym != sym)