[binutils-gdb] ld: fix segfault on discarded input sections not fitting in memory regions

Matthieu Longo mlongo@sourceware.org
Fri Mar 6 10:36:26 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=29174966e11fbace469eba0a6e1610865afd66a6

commit 29174966e11fbace469eba0a6e1610865afd66a6
Author: Matthieu Longo <matthieu.longo@arm.com>
Date:   Tue Sep 9 11:32:41 2025 +0100

    ld: fix segfault on discarded input sections not fitting in memory regions
    
    In the case of non-contiguous memory regions, if an input section did not
    fit in any of the designated memory regions, the linker marked it as
    discarded, and warn_non_contiguous_discards() would only issue warning on
    it, relying on later unresolved symbol errors to terminate the process
    before a crash occur. This approach was insufficient, and crashes did occur
    on AArch64.
    
    This patch renames warn_non_contiguous_discards () to a name that does not
    contain "discard" as it created some confusion with the /DISCARD/ output
    section. It also promotes the warnings to errors, and ensures that the
    link process terminates cleanly if any input section is not allocated to
    an output section.
    
    It also updates an AArch32 test's expectations to match the corrected
    behavior. Tests for the crash cases are added in a subsequent patch.
    
    Finally, it adds some patterns to /DISCARD/ in ld-elf/non-contiguous.ld.
    Before this patch, a section which was not assigned to an output section
    because no pattern matched, did not raise any error.
    
    Approved-By: Jan Beulich <jbeulich@suse.com>
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31412

Diff:
---
 ld/ldlang.c                                 | 30 +++++++++++++++++++----------
 ld/testsuite/ld-arm/non-contiguous-arm7.err |  9 ++++-----
 ld/testsuite/ld-elf/non-contiguous.ld       | 24 ++++++++++++-----------
 3 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 05ea97517ff..bc008c59df1 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -5696,7 +5696,7 @@ size_input_section
   lang_input_section_type *is = &((*this_ptr)->input_section);
   asection *i = is->section;
   asection *o = output_section_statement->bfd_section;
-  *removed = 0;
+  *removed = false;
 
   if (link_info.non_contiguous_regions)
     {
@@ -5707,7 +5707,7 @@ size_input_section
 	 have reinitialized its size.  */
       if (i->already_assigned && i->already_assigned != o)
 	{
-	  *removed = 1;
+	  *removed = true;
 	  return dot;
 	}
     }
@@ -5770,7 +5770,7 @@ size_input_section
 			     "would overflow `%pA' after it changed size).\n"),
 			   i, i->output_section);
 
-		  *removed = 1;
+		  *removed = true;
 		  dot = end;
 		  i->output_section = NULL;
 		  return dot;
@@ -8440,9 +8440,14 @@ lang_propagate_lma_regions (void)
     }
 }
 
+/* Checks whether any input section was not allocated to an output section.
+   If such a case is found, emits an error for the corresponding input section
+   and stops the link process.  */
+
 static void
-warn_non_contiguous_discards (void)
+error_non_contiguous_unallocated_sections (void)
 {
+  bool removed_section = false;
   LANG_FOR_EACH_INPUT_STATEMENT (file)
     {
       if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0
@@ -8451,10 +8456,16 @@ warn_non_contiguous_discards (void)
 
       for (asection *s = file->the_bfd->sections; s != NULL; s = s->next)
 	if (s->output_section == NULL && !s->veneer)
-	  einfo (_("%P: warning: --enable-non-contiguous-regions "
-		   "discards section `%pA' from `%pB'\n"),
-		 s, file->the_bfd);
+	  {
+	    einfo (_("%P: error: --enable-non-contiguous-regions was not able "
+		     "to allocate the input section `%pA' (%pB) to an output "
+		     "section\n"),
+		   s, file->the_bfd);
+	    removed_section = true;
+	  }
     }
+  if (removed_section)
+    fatal (_("%P: final link failed\n"));
 }
 
 static void
@@ -8876,9 +8887,8 @@ lang_process (void)
   if (command_line.check_section_addresses)
     lang_check_section_addresses ();
 
-  if (link_info.non_contiguous_regions
-      && link_info.non_contiguous_regions_warnings)
-    warn_non_contiguous_discards ();
+  if (link_info.non_contiguous_regions)
+    error_non_contiguous_unallocated_sections ();
 
   /* Check any required symbols are known.  */
   ldlang_check_require_defined_symbols ();
diff --git a/ld/testsuite/ld-arm/non-contiguous-arm7.err b/ld/testsuite/ld-arm/non-contiguous-arm7.err
index 7b3a3d8c3c9..21f71898eb1 100644
--- a/ld/testsuite/ld-arm/non-contiguous-arm7.err
+++ b/ld/testsuite/ld-arm/non-contiguous-arm7.err
@@ -1,5 +1,4 @@
-.* may change behaviour for section .?\.bss.? from .*
-.* may change behaviour for section .?\.bss\.MY_BUF.? from .*
-.* discards section .?\.bss\.MY_BUF.? from .*
-.* unresolvable R_ARM_ABS32 relocation against symbol .?MY_BUF.?
-.* final link failed
+.*: warning: --enable-non-contiguous-regions may change behaviour for section `\.bss' from `.*non-contiguous-arm7\.o' \(assigned to \.bss, but additional match: \.bss_ram2\)
+.*: warning: --enable-non-contiguous-regions may change behaviour for section `\.bss\.MY_BUF' from `.*non-contiguous-arm7\.o' \(assigned to \.bss, but additional match: \.bss_ram2\)
+.*: error: --enable-non-contiguous-regions was not able to allocate the input section `\.bss\.MY_BUF' \(.*non-contiguous-arm7\.o\) to an output section
+.*: final link failed
diff --git a/ld/testsuite/ld-elf/non-contiguous.ld b/ld/testsuite/ld-elf/non-contiguous.ld
index cfd3f248476..7b933844fc7 100644
--- a/ld/testsuite/ld-elf/non-contiguous.ld
+++ b/ld/testsuite/ld-elf/non-contiguous.ld
@@ -14,17 +14,19 @@ SECTIONS
 {
    /* Ignore this target specific info in output comparison.  */
    /DISCARD/ : {
-             *(.ARM.attributes)
-	     *(.ARC.attributes)
-	     *(.riscv.attributes)
-	     *(.c6xabi.attributes)
-	     *(.trampolines)
-	     *(.reginfo)
-	     *(.note.renesas)
-	     *(.MIPS.abiflags)
-	     *(.MSP430.attributes)
-	     *(.csky.attributes)
-	     *(.gnu.attributes)
+     *(.ARM.attributes)
+     *(.ARC.attributes)
+     *(.riscv.attributes)
+     *(.c6xabi.attributes)
+     *(.trampolines)
+     *(.reginfo)
+     *(.note.renesas)
+     *(.note.spu_name)
+     *(.MIPS.abiflags)
+     *(.MIPS.options)
+     *(.MSP430.attributes)
+     *(.csky.attributes)
+     *(.gnu.attributes)
    }
 
    .raml : /*AT ( ADDR (.text) + SIZEOF (.text) )*/


More information about the Binutils-cvs mailing list