[PATCH v2 1/5] bfd: have objcopy retain unknown ELF section flags
Jan Beulich
jbeulich@suse.com
Fri Aug 1 13:21:49 GMT 2025
Silently zapping them is certainly wrong. When they're not replaced due
to user request, simply keeping them may not always be correct (we don't
know what such a flag means, after all), but is certainly at least
closer to having the output object still represent what the input object
had.
This introduces new binutils/ testsuite failures, but only for two
targets where most of the tests there fail anyway (amdgcn-elf and
nfp-elf), due to there not being an assembler available.
---
The heuristic comparing BFD section flags is fragile (here as much as in
the handling of section type): If with --set-section-flags the user ends
up specifying what was already there, we'd behave as if the option
wasn't specified.
The situation with unknown SHT_* is quite a bit worse. While there is a
FIXME comment in bfd_section_from_shdr(), the diagnostic recorded there
isn't ever emitted on e.g. a default x86_64-linux build, where the
default target isn't the last one in the list of targets. Instead the
user gets to see "Unable to recognise the format of the input file ...",
which is pretty misleading.
---
v2: Emit warning.
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8430,9 +8430,28 @@ _bfd_elf_copy_private_section_data (bfd
& ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
elf_section_type (osec) = elf_section_type (isec);
- /* FIXME: Is this correct for all OS/PROC specific flags? */
- elf_section_flags (osec) = (elf_section_flags (isec)
- & (SHF_MASKOS | SHF_MASKPROC));
+ elf_section_flags (osec) = elf_section_flags (isec);
+ /* Like for type, retain flags for objcopy (yet unlike for type, don't do so
+ for relocatable link). Same heuristic as there: If the BFD section flags
+ are different, assume --set-section-flags is in use for the section.
+
+ FIXME: Is this correct for all OS/PROC specific flags? */
+ if (link_info != NULL || osec->flags != isec->flags)
+ elf_section_flags (osec) &= (SHF_MASKOS | SHF_MASKPROC);
+ else
+ {
+ /* Clear only flags which are set below or elsewhere. */
+ elf_section_flags (osec) &= ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR
+ | SHF_MERGE | SHF_STRINGS | SHF_LINK_ORDER
+ | SHF_INFO_LINK | SHF_GROUP | SHF_TLS
+ | SHF_COMPRESSED);
+ if (elf_section_flags (osec) & ~(SHF_MASKOS | SHF_MASKPROC))
+ _bfd_error_handler
+ (_("%pB:%pA: warning: retaining unknown section flag(s) %#" PRIx64),
+ ibfd, isec,
+ (uint64_t) (elf_section_flags (osec)
+ & ~(SHF_MASKOS | SHF_MASKPROC)));
+ }
/* Copy sh_info from input for mbind section. */
if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
--- /dev/null
+++ b/binutils/testsuite/binutils-all/copy-7.d
@@ -0,0 +1,14 @@
+#PROG: objcopy
+#readelf: -tW
+#name: copy with unknown section flag
+#warning: .*/copy-7[.].*:[.]special: warning: retaining .* 0x10000
+
+There are .* section headers, starting at offset .*
+
+Section Headers:
+ \[Nr\].*
+#...
+ \[ [1-9]\] .special
+ PROGBITS .*
+ \[0+10000\]: UNKNOWN \(0+10000\)
+#...
--- /dev/null
+++ b/binutils/testsuite/binutils-all/copy-7.s
@@ -0,0 +1,7 @@
+ .globl text_symbol
+ .text
+text_symbol:
+ .nop
+
+ .section .special,"0x10000", %progbits
+ .long -1
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -1313,6 +1313,7 @@ if [is_elf_format] {
run_dump_test "group-7b"
run_dump_test "group-7c"
run_dump_test "copy-1"
+ run_dump_test "copy-7"
run_dump_test "note-1"
# Use copytest.o from the note-1 test to determine ELF32 or ELF64
if [is_elf64 tmpdir/copytest.o] {
More information about the Binutils
mailing list