[binutils-gdb] ld: clarify comments on /DISCARD/ output section behavior

Matthieu Longo 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=fe4a952931334dee80378c9f0606745976d8b30f

commit fe4a952931334dee80378c9f0606745976d8b30f
Author: Matthieu Longo <[email protected]>
Date:   Fri Sep 12 17:26:38 2025 +0100

    ld: clarify comments on /DISCARD/ output section behavior
    
    The previous comments made it difficult to understand how the /DISCARD/
    output section interacts with non-contiguous regions.
    
    In summary, the general rule is that the first (top-most) clause takes
    precedence over subsequent ones:
    - If /DISCARD/ appears first, the section is dropped. There is no need
      to warn about potential behavior changes with non-contiguous regions
      when the section is already discarded.
    - If /DISCARD/ follows clauses that assign the input section to an output
      section, /DISCARD/ is ignored. If the input section can't be assigned
      to the output section for a later reason, an error will be raised.
      Otherwise the input section will be assigned as intended to an output
      section specified by one of the matching clauses previous to /DISCARD/.

Diff:
---
 ld/ldlang.c                                        | 27 ++++++++++++++++++----
 .../non-contiguous-mem/non-contiguous-ok-5.warn    |  4 ++--
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index bc008c59df1..656edeb4981 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2743,17 +2743,36 @@ wont_add_section_p (asection *section,
 
   if (discard)
     {
+      /* /DISCARD/ is seen first and the top-most clause has precedence on the
+	 next ones, thus the section will be dropped.  No need to warn about
+	 potential change in behavior with non-contiguous regions when the
+	 section is already dropped.  */
       if (section->output_section == NULL)
 	{
 	  /* This prevents future calls from assigning this section or
 	     warning about it again.  */
 	  section->output_section = bfd_abs_section_ptr;
 	}
-      else if (bfd_is_abs_section (section->output_section))
-	;
-      else if (link_info.non_contiguous_regions_warnings)
+      /* The /DISCARD/ clause follows clauses that assign the input section to
+	 an output section. Since /DISCARD/ does not have the precedence,
+	 /DISCARD/ is ignored.
+	 1. If the input section can be assigned to an output section,
+	    the link will succeed. The warning below is emitted with
+	    --enable-non-contiguous-regions-warnings so that the user can
+	    notice that /DISCARD/ did not do what he might have expected,
+	    i.e. discarding the input section.
+	 2. If the input section cannot be assigned, the link will fail
+	    with an error. The warning below is emitted with
+	    --enable-non-contiguous-regions-warnings so that the user can
+	    notice that /DISCARD/ was ignored for this input section, then
+	    leading to a link failure caused by not enough space in the output
+	    section for the input section.  */
+      else if (! bfd_is_abs_section (section->output_section)
+	       && link_info.non_contiguous_regions_warnings)
 	einfo (_("%P:%pS: warning: --enable-non-contiguous-regions makes "
-		 "section `%pA' from `%pB' match /DISCARD/ clause.\n"),
+		 "section `%pA' from `%pB' match /DISCARD/ clause.  If the "
+		 "section can be assigned to an output section, it won't be "
+		 "discarded.\n"),
 	       NULL, section, section->owner);
 
       return true;
diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn
index 730599ef289..7cf8af73a56 100644
--- a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn
+++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn
@@ -2,8 +2,8 @@
 .*: warning: .* may change behaviour for section .\.code\.2. from .* \(assigned to \.raml, but additional match: \.ramu\)
 .*: warning: .* may change behaviour for section .\.code\.3. from .* \(assigned to \.raml, but additional match: \.ramu\)
 .*: warning: .* may change behaviour for section .\.code\.4. from .* \(assigned to \.raml, but additional match: \.ramu\)
-.*: warning: .* makes section .\.code\.2. from .* match /DISCARD/ clause\.
-.*: warning: .* makes section .\.code\.4. from .* match /DISCARD/ clause\.
+.*: warning: .* makes section .\.code\.2. from .* match /DISCARD/ clause\.  If the section can be assigned to an output section, it won't be discarded\.
+.*: warning: .* makes section .\.code\.4. from .* match /DISCARD/ clause\.  If the section can be assigned to an output section, it won't be discarded\.
 .*: warning: .* may change behaviour for section .\.code\.1. from .* \(assigned to \.ramu, but additional match: \.ramz\)
 .*: warning: .* may change behaviour for section .\.code\.2. from .* \(assigned to \.ramu, but additional match: \.ramz\)
 .*: warning: .* may change behaviour for section .\.code\.3. from .* \(assigned to \.ramu, but additional match: \.ramz\)
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.