[PATCH] gas: Avoid section symbols as group signatures

"Kirill A. Korinsky" <[email protected]> Mon, 27 Jul 2026 13:04:47 +0200
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
When a COMDAT group signature matches its section name,
symbol_find_exact finds the existing section symbol. GAS then reuses
this unnamed STT_SECTION symbol as the group signature, although the
signature requires a distinct named symbol.

Reject section symbols when selecting an existing signature; GAS then
creates the usual named local STT_NOTYPE symbol.

This issue was discovered during the OpenBSD/sparc64 LLVM toolchain port
and the attempt to upstream its LLVM changes:
https://github.com/llvm/llvm-project/pull/207609

An LLD workaround for these objects was rejected upstream:
https://github.com/llvm/llvm-project/pull/209841

The LLD workaround was tested while building GCC 15.2.0 and GCC 16.1.0
on OpenBSD/sparc64 with the LLVM toolchain.
---
 gas/config/obj-elf.c           | 1 +
 gas/testsuite/gas/elf/elf.exp  | 1 +
 gas/testsuite/gas/elf/group2.d | 8 ++++++++
 gas/testsuite/gas/elf/group2.s | 2 ++
 4 files changed, 12 insertions(+)
 create mode 100644 gas/testsuite/gas/elf/group2.d
 create mode 100644 gas/testsuite/gas/elf/group2.s

diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 337726191..ca0ce0039 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -2286,6 +2286,7 @@ elf_adjust_symtab (void)
 	 name of the group.  */
       sy = symbol_find_exact (group_name);
       if (!sy
+	  || symbol_section_p (sy)
 	  || (sy != symbol_lastP
 	      && (sy->sy_next == NULL
 		  || sy->sy_next->sy_previous != sy)))
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 4196fd7da..93929c982 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -116,6 +116,7 @@ if { [is_elf_format] } then {
     run_dump_test "group0c"
     run_dump_test "group1a"
     run_dump_test "group1b"
+    run_dump_test "group2"
     case $target_triplet in {
 	{ hppa64*-*-hpux* } { }
 	default {
diff --git a/gas/testsuite/gas/elf/group2.d b/gas/testsuite/gas/elf/group2.d
new file mode 100644
index 000000000..37dec8c7e
--- /dev/null
+++ b/gas/testsuite/gas/elf/group2.d
@@ -0,0 +1,8 @@
+#readelf: -sW
+#name: section group signature matching section name
+#source: group2.s
+#not-target: *-*-solaris*
+
+#...
+.*NOTYPE[ 	]+LOCAL[ 	]+DEFAULT[ 	]+[0-9]+[ 	]+\.foo
+#pass
diff --git a/gas/testsuite/gas/elf/group2.s b/gas/testsuite/gas/elf/group2.s
new file mode 100644
index 000000000..58dc83acb
--- /dev/null
+++ b/gas/testsuite/gas/elf/group2.s
@@ -0,0 +1,2 @@
+	.section       .foo,"axG",%progbits,.foo,comdat
+	.byte	1
-- 
2.55.0