[binutils-gdb] bfd: have objcopy retain unknown ELF section flags

Jan Beulich jbeulich@sourceware.org
Fri Aug 15 10:20:54 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b3743a2c05d153deb5ad0ffdbee6ed5487d6e229

commit b3743a2c05d153deb5ad0ffdbee6ed5487d6e229
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Aug 15 12:16:22 2025 +0200

    bfd: have objcopy retain unknown ELF section flags
    
    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.

Diff:
---
 bfd/elf.c                                   | 25 ++++++++++++++++++++++---
 binutils/testsuite/binutils-all/copy-7.d    | 14 ++++++++++++++
 binutils/testsuite/binutils-all/copy-7.s    |  7 +++++++
 binutils/testsuite/binutils-all/objcopy.exp |  1 +
 4 files changed, 44 insertions(+), 3 deletions(-)

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] {


More information about the Binutils-cvs mailing list