[PATCH] elf: Verify that there is only one default version
"H.J. Lu" <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <CAMe9rOoSGbK-g6tymr_Q2TtH_39i1aS6p2zLCFyJyMeuEDoY1A@mail.gmail.com> |
When assigning the symbol version, verify that there is only one default version. bfd/ PR ld/34550 * elflink.c (_bfd_elf_link_assign_sym_version): Verify that there is only one default version. ld/ PR ld/34550 * testsuite/ld-elf/pr34550.d: New test. * testsuite/ld-elf/pr34550.s: Likewise. * testsuite/ld-elf/pr34550.t: Likewise. -- H.J.
0001-elf-Verify-that-there-is-only-one-default-version.patch
(text/x-patch, 4.2 KB)
From 294ca43bc99d0c8a6d0d0ce3e3cea486f9823b3b Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <[email protected]> Date: Wed, 26 Aug 2026 11:29:39 +0800 Subject: [PATCH] elf: Verify that there is only one default version When assigning the symbol version, verify that there is only one default version. bfd/ PR ld/34550 * elflink.c (_bfd_elf_link_assign_sym_version): Verify that there is only one default version. ld/ PR ld/34550 * testsuite/ld-elf/pr34550.d: New test. * testsuite/ld-elf/pr34550.s: Likewise. * testsuite/ld-elf/pr34550.t: Likewise. Signed-off-by: H.J. Lu <[email protected]> --- bfd/elflink.c | 50 ++++++++++++++++++++++++++++++++++- ld/testsuite/ld-elf/pr34550.d | 4 +++ ld/testsuite/ld-elf/pr34550.s | 10 +++++++ ld/testsuite/ld-elf/pr34550.t | 13 +++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-elf/pr34550.d create mode 100644 ld/testsuite/ld-elf/pr34550.s create mode 100644 ld/testsuite/ld-elf/pr34550.t diff --git a/bfd/elflink.c b/bfd/elflink.c index cc29b99ba56..1245bf425b9 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2693,10 +2693,14 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) if (p != NULL && h->verinfo.vertree == NULL) { struct bfd_elf_version_tree *t; + bool default_version = false; ++p; if (*p == ELF_VER_CHR) - ++p; + { + default_version = true; + ++p; + } /* If there is no version string, we can just return out. */ if (*p == '\0') @@ -2710,6 +2714,50 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) if (hide) obed->elf_backend_hide_symbol (info, h, true); + else if (default_version) + { + /* Get the unversioned symbol for the default version. */ + struct elf_link_hash_entry *h_u; + size_t size = p - h->root.root.string - 1; + char *unversioned_name = bfd_malloc (size); + if (unversioned_name == NULL) + { + sinfo->failed = true; + return false; + } + memcpy (unversioned_name, h->root.root.string, size - 1); + unversioned_name[size - 1] = 0; + h_u = elf_link_hash_lookup (elf_hash_table (info), + unversioned_name, false, + false, false); + + /* There must be an unversioned symbol. */ + if (h_u == NULL) + abort (); + + while (h_u->root.type == bfd_link_hash_indirect + || h_u->root.type == bfd_link_hash_warning) + h_u = (struct elf_link_hash_entry *) h_u->root.u.i.link; + + /* Verify that there is only one default version. */ + if (h_u->versioned != versioned_hidden + && h_u->verinfo.vertree != h->verinfo.vertree) + { + /* xgettext:c-format */ + info->callbacks->einfo + (_("%X%P: %pB: symbol `%s' has 2 default versions: " + "`%s', `%s'.\n"), + info->output_bfd, unversioned_name, + h_u->verinfo.vertree->name, + h->verinfo.vertree->name); + bfd_set_error (bfd_error_bad_value); + sinfo->failed = true; + free (unversioned_name); + return false; + } + + free (unversioned_name); + } /* If we are building an application, we need to create a version node for this version. */ diff --git a/ld/testsuite/ld-elf/pr34550.d b/ld/testsuite/ld-elf/pr34550.d new file mode 100644 index 00000000000..def41a1d1ec --- /dev/null +++ b/ld/testsuite/ld-elf/pr34550.d @@ -0,0 +1,4 @@ +#target: [check_shared_lib_support] +#as: +#ld: -shared --version-script=pr34550.t +#error: symbol `fmod' has 2 default versions: `GLIBC_2.0', `GLIBC_2.43'. diff --git a/ld/testsuite/ld-elf/pr34550.s b/ld/testsuite/ld-elf/pr34550.s new file mode 100644 index 00000000000..652aa35f31f --- /dev/null +++ b/ld/testsuite/ld-elf/pr34550.s @@ -0,0 +1,10 @@ + .text + .type fmod,%function + .globl fmod +fmod: + .dc.a 0 + .type fmod_new,%function + .globl fmod_new +fmod_new: + .dc.a 0 + .symver fmod_new, fmod@@GLIBC_2.43 diff --git a/ld/testsuite/ld-elf/pr34550.t b/ld/testsuite/ld-elf/pr34550.t new file mode 100644 index 00000000000..37dff255cdc --- /dev/null +++ b/ld/testsuite/ld-elf/pr34550.t @@ -0,0 +1,13 @@ +GLIBC_2.0 { + global: + fmod; + local: + *; +}; + +GLIBC_2.43 { + global: + fmod; + local: + *; +} GLIBC_2.0; -- 2.55.0