[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