[PATCH v2 5/5] ld: clarify comments on /DISCARD/ output section behavior
Matthieu Longo
matthieu.longo@arm.com
Tue Oct 14 10:46:11 GMT 2025
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, and the section is kept. In this case,
the linker must warn that the section may not be discarded.
---
ld/ldlang.c | 16 ++++++++++++----
.../non-contiguous-mem/non-contiguous-ok-5.warn | 4 ++--
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/ld/ldlang.c b/ld/ldlang.c
index c7c4ba8a019..818fa742d63 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2709,17 +2709,25 @@ 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 appears after previous ones which assigned the
+ input section to an output section. /DISCARD/ does not have the
+ precedence, so the section will be kept. */
+ 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\)
--
2.51.0
More information about the Binutils
mailing list