[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\)