[PATCH] elf: Check multiple definition when defining hidden version

H.J. Lu hjl.tools@gmail.com
Wed Dec 2 14:51:38 GMT 2020


When defining a hidden version from the nondefault version of the symbol,
check if there is already a definition to avoid multiple definitions:

[hjl@gnu-cfl-2 pr26978]$ gcc -o y main.o libbar.so -Wl,-R,.
/usr/local/bin/ld: libbar.so:(*IND*+0x0): multiple definition of `foo@v1'; libbar.so:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
[hjl@gnu-cfl-2 pr26978]$ readelf --dyn-syms libbar.so

Symbol table '.dynsym' contains 5 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000001000     0 OBJECT  GLOBAL DEFAULT    7 foo@v1
     2: 0000000000001001     0 OBJECT  WEAK   DEFAULT    7 foo@@v1
     3: 0000000000001000     0 OBJECT  GLOBAL DEFAULT    7 foo_v1
     4: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS v1
[hjl@gnu-cfl-2 pr26978]$

bfd/

	PR ld/26978
	* elflink.c (_bfd_elf_add_default_symbol): Check if there is
	already a definition before defining an indirection.

ld/

	PR ld/26978
	* testsuite/ld-elf/pr26978.ver: New file.
	* testsuite/ld-elf/pr26978a.d: Likewise.
	* testsuite/ld-elf/pr26978a.s: Likewise.
	* testsuite/ld-elf/pr26978b.d: Likewise.
	* testsuite/ld-elf/pr26978b.s: Likewise.
---
 bfd/elflink.c                   | 13 +++++++++++++
 ld/testsuite/ld-elf/pr26978.ver |  1 +
 ld/testsuite/ld-elf/pr26978a.d  |  6 ++++++
 ld/testsuite/ld-elf/pr26978a.s  |  7 +++++++
 ld/testsuite/ld-elf/pr26978b.d  |  6 ++++++
 ld/testsuite/ld-elf/pr26978b.s  |  6 ++++++
 6 files changed, 39 insertions(+)
 create mode 100644 ld/testsuite/ld-elf/pr26978.ver
 create mode 100644 ld/testsuite/ld-elf/pr26978a.d
 create mode 100644 ld/testsuite/ld-elf/pr26978a.s
 create mode 100644 ld/testsuite/ld-elf/pr26978b.d
 create mode 100644 ld/testsuite/ld-elf/pr26978b.s

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 512c5044b3..65dc106656 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2077,6 +2077,19 @@ _bfd_elf_add_default_symbol (bfd *abfd,
 			      &type_change_ok, &size_change_ok, &matched))
     return FALSE;
 
+  /* Check if there is already a definition before defining an
+     indirection.  */
+  if ((hi->root.type == bfd_link_hash_defined
+       || hi->root.type == bfd_link_hash_defweak)
+      && (hi->def_regular || ELF_COMMON_DEF_P (hi)))
+    {
+      /* Handle a multiple definition.  */
+      (*info->callbacks->multiple_definition) (info, &hi->root,
+					       abfd, sec,
+					       hi->root.u.def.value);
+      return TRUE;
+    }
+
   if (skip)
     return TRUE;
 
diff --git a/ld/testsuite/ld-elf/pr26978.ver b/ld/testsuite/ld-elf/pr26978.ver
new file mode 100644
index 0000000000..46ddd300d7
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26978.ver
@@ -0,0 +1 @@
+v1 {};
diff --git a/ld/testsuite/ld-elf/pr26978a.d b/ld/testsuite/ld-elf/pr26978a.d
new file mode 100644
index 0000000000..d00991a3f1
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26978a.d
@@ -0,0 +1,6 @@
+#source: pr26978a.s
+#source: pr26978b.s
+#target: [check_shared_lib_support]
+#as:
+#ld: -shared --version-script=pr26978.ver
+#error: multiple definition of `foo@v1'
diff --git a/ld/testsuite/ld-elf/pr26978a.s b/ld/testsuite/ld-elf/pr26978a.s
new file mode 100644
index 0000000000..5c8da332c3
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26978a.s
@@ -0,0 +1,7 @@
+	.text
+	.weak foo
+	.globl foo
+	.symver foo, foo@@@v1
+	.type	foo, %object
+foo:
+	.nop
diff --git a/ld/testsuite/ld-elf/pr26978b.d b/ld/testsuite/ld-elf/pr26978b.d
new file mode 100644
index 0000000000..382242b65f
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26978b.d
@@ -0,0 +1,6 @@
+#source: pr26978b.s
+#source: pr26978a.s
+#target: [check_shared_lib_support]
+#as:
+#ld: -shared --version-script=pr26978.ver
+#error: multiple definition of `foo@v1'
diff --git a/ld/testsuite/ld-elf/pr26978b.s b/ld/testsuite/ld-elf/pr26978b.s
new file mode 100644
index 0000000000..5873672e08
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr26978b.s
@@ -0,0 +1,6 @@
+	.text
+	.globl foo_v1
+	.symver foo_v1, foo@v1
+	.type	foo_v1, %object
+foo_v1:
+	.nop
-- 
2.28.0



More information about the Binutils mailing list