[PATCH RFC] bfd: have objcopy retain unknown ELF section flags
Alan Modra
amodra@gmail.com
Sun Jul 6 03:27:54 GMT 2025
On Fri, Jun 13, 2025 at 03:27:28PM +0200, Jan Beulich wrote:
> 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 patch looks reasonable to me.
> Should we warn about any flags (outside of MASKOS/MASKPROC) being
> retained this way?
Probably. At least that way people will be alerted to the fact they
should update their binutils.
> (For context: The original observation was years ago
> with old enough binutils losing SHF_COMPRESSED on debug info, obviously
> causing issues when later those objects were handed to the linker. The
> errors raised by the linker weren't really straightforward to connect
> back to the root cause. Hence my main requirement going forward is: Any
> loss of information should not go silently.)
>
> 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 on in the list of targets. Instead the
> user gets to see "Unable to recognise the format of the input file ...",
> which is pretty misleading.
Yes, I'm not completely happy about the handling of errors in object_p
functions. What we have at the moment is the result of trying to
eliminate irrelevant and duplicate messages from targets other than
the one that matches.
>
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -8414,9 +8414,19 @@ _bfd_elf_init_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);
>
> /* 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,13 @@
> +#PROG: objcopy
> +#readelf: -tW
> +#name: copy with unknown section flag
> +
> +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
> @@ -1232,6 +1232,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] {
--
Alan Modra
More information about the Binutils
mailing list