[binutils-gdb] elf: Don't set its DT_VERSYM entry for unversioned symbol

H.J. Lu hjl@sourceware.org
Mon Nov 3 07:09:12 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f685e3953f9a38a41bbd0a597f9882870cee13d5

commit f685e3953f9a38a41bbd0a597f9882870cee13d5
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Oct 29 09:49:57 2025 +0800

    elf: Don't set its DT_VERSYM entry for unversioned symbol
    
    1. Referenced symbol without '@' has no version.
    2. Defined symbol without the .symver directive has no version if there
    is no linker version script.
    
    Symbol without version shouldn't have the base version in its DT_VERSYM
    entry.  Instead, its DT_VERSYM entry should be all zero to indicate that
    the symbol doesn't have a version.
    
    NB: Symbol with the base version has a '@' suffix, like "foo@", defined
    with
    
    .symver hide_original_foo, foo@
    
    bfd/
    
            PR ld/33577
            * elflink.c (elf_link_output_extsym): Don't set its DT_VERSYM
            entry for the symbol without version.
    
    ld/
    
            PR ld/33577
            * ld-elfvers/vers16.dsym: Remove the "Base" version on symbols
            without version.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>

Diff:
---
 bfd/elflink.c                       | 37 ++++++++++++++++++++++++++++---------
 ld/testsuite/ld-elfvers/vers16.dsym |  4 ++--
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 0ea974d45ce..f73ceb23c8b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11139,34 +11139,53 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
 	{
 	  Elf_Internal_Versym iversym;
 	  Elf_External_Versym *eversym;
+	  bool noversion = false;
 
 	  if (!h->def_regular && !ELF_COMMON_DEF_P (h))
 	    {
 	      if (h->verinfo.verdef == NULL
 		  || (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd)
 		      & (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED)))
-		iversym.vs_vers = 1;
+		{
+		  iversym.vs_vers = 1;
+		  if (strchr (h->root.root.string, ELF_VER_CHR) == NULL)
+		    /* Referenced symbol without ELF_VER_CHR has no
+		       version.  */
+		    noversion = true;
+		}
 	      else
 		iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1;
 	    }
 	  else
 	    {
 	      if (h->verinfo.vertree == NULL)
-		iversym.vs_vers = 1;
+		{
+		  iversym.vs_vers = 1;
+		  if (elf_tdata (flinfo->output_bfd)->cverdefs == 0)
+		    /* Defined symbol has no version if there is no
+		       linker version script.  */
+		    noversion = true;
+		}
 	      else
 		iversym.vs_vers = h->verinfo.vertree->vernum + 1;
 	      if (flinfo->info->create_default_symver)
 		iversym.vs_vers++;
 	    }
 
-	  /* Turn on VERSYM_HIDDEN only if the hidden versioned symbol is
-	     defined locally.  */
-	  if (h->versioned == versioned_hidden && h->def_regular)
-	    iversym.vs_vers |= VERSYM_HIDDEN;
+	  /* Don't set its DT_VERSYM entry for unversioned symbol.  */
+	  if (!noversion)
+	    {
+	      /* Turn on VERSYM_HIDDEN only if the hidden versioned
+		 symbol is defined locally.  */
+	      if (h->versioned == versioned_hidden && h->def_regular)
+		iversym.vs_vers |= VERSYM_HIDDEN;
 
-	  eversym = (Elf_External_Versym *) flinfo->symver_sec->contents;
-	  eversym += h->dynindx;
-	  _bfd_elf_swap_versym_out (flinfo->output_bfd, &iversym, eversym);
+	      eversym
+		= (Elf_External_Versym *) flinfo->symver_sec->contents;
+	      eversym += h->dynindx;
+	      _bfd_elf_swap_versym_out (flinfo->output_bfd, &iversym,
+					eversym);
+	    }
 	}
     }
 
diff --git a/ld/testsuite/ld-elfvers/vers16.dsym b/ld/testsuite/ld-elfvers/vers16.dsym
index cc0c4e11d93..076d0eb07ed 100644
--- a/ld/testsuite/ld-elfvers/vers16.dsym
+++ b/ld/testsuite/ld-elfvers/vers16.dsym
@@ -1,2 +1,2 @@
-[0-9a-f]+ g +DF (\.text|\.opd|\*ABS\*)	[0-9a-f]+( +Base +)? (0x[0-9a-f]+ )?_?show_bar
-[0-9a-f]+ +DF \*UND\*	[0-9a-f]+ +Base +(0x[0-9a-f]+ )?_?show_foo
+[0-9a-f]+ g +DF (\.text|\.opd|\*ABS\*)	[0-9a-f]+ +(0x[0-9a-f]+ )?_?show_bar
+[0-9a-f]+ +DF \*UND\*	[0-9a-f]+ +(0x[0-9a-f]+ )?_?show_foo


More information about the Binutils-cvs mailing list