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>
This commit is contained in:
H.J. Lu
2025-10-29 09:49:57 +08:00
parent 603d5fa176
commit f685e3953f
2 changed files with 30 additions and 11 deletions

View 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);
}
}
}

View 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