[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.