[binutils-gdb] ld/ELF: Fix small issue with orphan sections and NOLOAD output section

Eric Botcazou via Binutils-cvs <[email protected]>
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bd40fc073ae0c30f8ad40623e9f40da1be09b0e5

commit bd40fc073ae0c30f8ad40623e9f40da1be09b0e5
Author: Eric Botcazou <[email protected]>
Date:   Wed Mar 18 12:49:23 2026 +0100

    ld/ELF: Fix small issue with orphan sections and NOLOAD output section
    
    What happens is that the effect of the command:
    
      .foo (NOLOAD) : {}
    
    is not equivalent to that of:
    
      .foo (NOLOAD) : { *(.foo) }
    
    when there is more than 1 object file containing a .foo section: the former
    will output two .foo sections, the first with PROGBITS and the second with
    NOBITS, where the latter will output only one with NOBITS.
    
    Given that the commands are essentially equivalent, the linker ought to
    yield the same outcome, namely the single output section with NOBITS.

Diff:
---
 ld/ldelf.c                       | 15 +++++++++------
 ld/testsuite/ld-elf/orphan-13.d  | 12 ++++++++++++
 ld/testsuite/ld-elf/orphan-13.ld |  7 +++++++
 ld/testsuite/ld-elf/orphan-13a.s | 14 ++++++++++++++
 ld/testsuite/ld-elf/orphan-13b.s |  2 ++
 ld/testsuite/ld-elf/orphan-13c.s |  2 ++
 6 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/ld/ldelf.c b/ld/ldelf.c
index fbab75aeefb..15d4b576bc0 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -2242,14 +2242,17 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint)
 	   lang_insert_orphan to create a new output section.  */
 	constraint = SPECIAL;
 
-	/* Check to see if we already have an output section statement
-	   with this name, and its bfd section has compatible flags.
-	   If the section already exists but does not have any flags
-	   set, then it has been created by the linker, possibly as a
-	   result of a --section-start command line switch.  */
+	/* Check to see if we already have an output section statement with
+	   this name, and it was either present in the script with a special
+	   type (knowing that lang_insert_orphan only creates normal_section
+	   output sections) or its BFD section has compatible flags.  If the
+	   section already exists but does not have any flags set, then it has
+	   been created by the linker, possibly as a result of --section-start
+	   command line switch.  */
 	if (os->bfd_section != NULL
 	    && !bfd_is_abs_section (os->bfd_section)
-	    && (os->bfd_section->flags == 0
+	    && (os->sectype >= noload_section
+		|| os->bfd_section->flags == 0
 		|| (((s->flags ^ os->bfd_section->flags)
 		     & (SEC_LOAD | SEC_ALLOC)) == 0
 		    && (!elfinput
diff --git a/ld/testsuite/ld-elf/orphan-13.d b/ld/testsuite/ld-elf/orphan-13.d
new file mode 100644
index 00000000000..8f867dc8938
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-13.d
@@ -0,0 +1,12 @@
+#source: orphan-13a.s
+#source: orphan-13b.s
+#source: orphan-13c.s
+#ld: -T orphan-13.ld
+#readelf: -S --wide
+#xfail: [uses_genelf]
+#xfail: xstormy16-*-*
+
+#...
+  \[[ 0-9]+\] \.foo +NOBITS +[0-9a-f]+ +[0-9a-f]+ +0+30 +0+ +A +0 +0 +[0-9]+
+  \[[ 0-9]+\] [._][^f].*
+#pass
diff --git a/ld/testsuite/ld-elf/orphan-13.ld b/ld/testsuite/ld-elf/orphan-13.ld
new file mode 100644
index 00000000000..face613f8bd
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-13.ld
@@ -0,0 +1,7 @@
+SECTIONS
+{
+  . = SIZEOF_HEADERS;
+  .text : { *(.text) }
+  .data : { *(.data) }
+  .foo (NOLOAD) : {}
+}
diff --git a/ld/testsuite/ld-elf/orphan-13a.s b/ld/testsuite/ld-elf/orphan-13a.s
new file mode 100644
index 00000000000..a8a6f364455
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-13a.s
@@ -0,0 +1,14 @@
+ .globl main
+ .globl _main
+ .globl start
+ .globl _start
+ .globl __start
+ .text
+main:
+_main:
+start:
+_start:
+__start:
+
+ .section .foo,"a",%progbits
+ .long 1,1,1,1
diff --git a/ld/testsuite/ld-elf/orphan-13b.s b/ld/testsuite/ld-elf/orphan-13b.s
new file mode 100644
index 00000000000..c475eb11d1b
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-13b.s
@@ -0,0 +1,2 @@
+ .section .foo,"a",%progbits
+ .long 1,1,1,1
diff --git a/ld/testsuite/ld-elf/orphan-13c.s b/ld/testsuite/ld-elf/orphan-13c.s
new file mode 100644
index 00000000000..c475eb11d1b
--- /dev/null
+++ b/ld/testsuite/ld-elf/orphan-13c.s
@@ -0,0 +1,2 @@
+ .section .foo,"a",%progbits
+ .long 1,1,1,1
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.