]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: clarify comments on /DISCARD/ output section behavior
authorMatthieu Longo <matthieu.longo@arm.com>
Fri, 12 Sep 2025 16:26:38 +0000 (17:26 +0100)
committerMatthieu Longo <matthieu.longo@arm.com>
Fri, 6 Mar 2026 10:33:21 +0000 (10:33 +0000)
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/.

ld/ldlang.c
ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn

index bc008c59df1fc703643635f627a0d0f0e6b01c5a..656edeb4981442cf3eb7f93bdbfaff323dbbecc7 100644 (file)
@@ -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;
index 730599ef289d4bfa2911498515a4671cb20fb6f4..7cf8af73a567c7d447687f072acdb743848e2eae 100644 (file)
@@ -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\)