[PATCH] bfd/ld: handle ABI prefixes in version scripts

Mike Frysinger vapier@gentoo.org
Thu Dec 9 20:56:00 GMT 2010


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.

I was holding off on this once binutils-2.21 was done, and we've
hit that point now.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>

bfd/:
2010-12-09  Mike Frysinger  <vapier@gentoo.org>

	* elflink.c (bfd_elf_size_dynamic_sections): Add
	bfd_get_symbol_leading_char to the start of newname.

ld/:
2010-12-09  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.
---
 bfd/elflink.c |    8 +++++---
 ld/ldlang.c   |   22 +++++++++++++++++-----
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 32575d9..52b2afe 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5713,11 +5713,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;
@@ -5725,7 +5726,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;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index e804a53..28d2756 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -7299,19 +7299,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;
     }
@@ -7325,10 +7335,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
@@ -7386,12 +7396,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)
-- 
1.7.3.1



More information about the Binutils mailing list