]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
elf: Don't set its DT_VERSYM entry for unversioned symbol
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 29 Oct 2025 01:49:57 +0000 (09:49 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 3 Nov 2025 07:09:07 +0000 (15:09 +0800)
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>
bfd/elflink.c
ld/testsuite/ld-elfvers/vers16.dsym

index 0ea974d45ce5e62b4eb41570b2b6611e25b8195f..f73ceb23c8b3b022cad85e5882bfa9b16bd298a9 100644 (file)
@@ -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);
+           }
        }
     }
 
index cc0c4e11d930af91adb0f91075ba4cf3c13f612e..076d0eb07ed636e7ff0cc505cb3cc34880fdbba3 100644 (file)
@@ -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