diff --git a/bfd/elf.c b/bfd/elf.c index 4f6bcde2365..596c1ec3de2 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -8434,9 +8434,28 @@ _bfd_elf_copy_private_section_data (bfd *ibfd, & ~(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 diff --git a/binutils/testsuite/binutils-all/copy-7.d b/binutils/testsuite/binutils-all/copy-7.d new file mode 100644 index 00000000000..ac8e7560969 --- /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\) +#... diff --git a/binutils/testsuite/binutils-all/copy-7.s b/binutils/testsuite/binutils-all/copy-7.s new file mode 100644 index 00000000000..0861c3c602f --- /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 diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index 89370bc893a..ac8978fef2b 100644 --- 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] {