aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2025-08-26 10:42:03 +0200
committerJan Beulich <jbeulich@suse.com>2025-08-26 10:42:03 +0200
commit74f045d47ab9060bc4e8b82e62bdf2d0ef730cb5 (patch)
tree423637cc79b9ca83357b9006399c5a16b4b7768f
parent5319c8dec64aa5e37c56da2b0cfe77a1886231ca (diff)
downloadbinutils-74f045d47ab9060bc4e8b82e62bdf2d0ef730cb5.zip
binutils-74f045d47ab9060bc4e8b82e62bdf2d0ef730cb5.tar.gz
binutils-74f045d47ab9060bc4e8b82e62bdf2d0ef730cb5.tar.bz2
ld: entry size and merge/strings attributes propagation
While commit 9c0adb10c7fc ("elf: Clear entsize when clearing SEC_MERGE|SEC_STRINGS") addressed the particular issue reported in PR ld/33291, it didn't go quite far enough to deal with related aspects as well: As indicated in other recent commits, the three properties can be largely independent (ELF generally being the target here): Entry size doesn't require either of merge/strings, and strings also doesn't require merge. Commit 98e6d3f5bd4e ("gas/ELF: allow specifying entity size for arbitrary sections") uncovered issues with ld's handling. Zap entry size when it doesn't match between input sections. In that case SEC_MERGE and SEC_STRINGS also need to be removed, as their underlying granularity is lost. Then deal with SEC_MERGE and SEC_STRINGS separately. Otoh record entry size from the first input independent of SEC_MERGE.
-rw-r--r--ld/ldlang.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 0bb4a17..54292a8 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2854,15 +2854,24 @@ lang_add_section (lang_statement_list_type *ptr,
/* Only set SEC_READONLY flag on the first input section. */
flags &= ~ SEC_READONLY;
- /* Keep SEC_MERGE and SEC_STRINGS only if they are the same. */
- if ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS))
- != (flags & (SEC_MERGE | SEC_STRINGS))
- || ((flags & SEC_MERGE) != 0
- && output->bfd_section->entsize != section->entsize))
+ /* Keep entry size, SEC_MERGE, and SEC_STRINGS only if entry sizes are
+ the same. */
+ if (output->bfd_section->entsize != section->entsize)
{
- output->bfd_section->flags &= ~ (SEC_MERGE | SEC_STRINGS);
output->bfd_section->entsize = 0;
- flags &= ~ (SEC_MERGE | SEC_STRINGS);
+ flags &= ~(SEC_MERGE | SEC_STRINGS);
+ }
+
+ /* Keep SEC_MERGE and SEC_STRINGS (each) only if they are the same. */
+ if ((output->bfd_section->flags ^ flags) & SEC_MERGE)
+ {
+ output->bfd_section->flags &= ~SEC_MERGE;
+ flags &= ~SEC_MERGE;
+ }
+ if ((output->bfd_section->flags ^ flags) & SEC_STRINGS)
+ {
+ output->bfd_section->flags &= ~SEC_STRINGS;
+ flags &= ~SEC_STRINGS;
}
}
output->bfd_section->flags |= flags;
@@ -2877,8 +2886,7 @@ lang_add_section (lang_statement_list_type *ptr,
link_info.output_bfd,
output->bfd_section,
&link_info);
- if ((flags & SEC_MERGE) != 0)
- output->bfd_section->entsize = section->entsize;
+ output->bfd_section->entsize = section->entsize;
}
if ((flags & SEC_TIC54X_BLOCK) != 0