[llvm] r359639 - [llvm-objcopy] Simplify SHT_NOBITS -> SHT_PROGBITS promotion

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 30 17:39:31 PDT 2019


Author: maskray
Date: Tue Apr 30 17:39:31 2019
New Revision: 359639

URL: http://llvm.org/viewvc/llvm-project?rev=359639&view=rev
Log:
[llvm-objcopy] Simplify SHT_NOBITS -> SHT_PROGBITS promotion

GNU objcopy uses bfd_elf_get_default_section_type to decide the candidate section type,
which roughly translates to our [a] (I assume SEC_COMMON implies SHF_ALLOC):

  (!(Sec.Flags & ELF::SHF_ALLOC) || Flags & (SectionFlag::SecContents | SectionFlag::SecLoad)))

Then, it updates the section type in bfd/elf.c:elf_fake_sections if:

  if (this_hdr->sh_type == SHT_NULL)
    this_hdr->sh_type = sh_type; // common case
  else if (this_hdr->sh_type == SHT_NOBITS
           && sh_type == SHT_PROGBITS
           && (asect->flags & SEC_ALLOC) != 0)  // uncommon case
    ...
    this_hdr->sh_type = sh_type;

If the following condition is met the uncommon branch is executed:

  if (elf_section_type (osec) == SHT_NULL
      && (osec->flags == isec->flags
	  || (final_link
	      && ((osec->flags ^ isec->flags)
		  & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))

I suggest we just ignore this clause and follow the common case
behavior, which is done in this patch. Rationales to do so:

If --set-section-flags is a no-op (osec->flags == isec->flags)
(corresponds to the "readonly" test in set-section-flags.test), GNU
objcopy will require (Sec.Flags & ELF::SHF_ALLOC). [a] is essentially:

  Flags & (SectionFlag::SecContents | SectionFlag::SecLoad)

This special case is not really useful. Non-SHF_ALLOC SHT_NOBITS
sections do not make much sense and it doesn't matter if they are
SHT_NOBITS or SHT_PROGBITS.

For all other RUN lines in set-section-flags.test, the new behavior
matches GNU objcopy, i.e. this patch improves compatibility.

Differential Revision: https://reviews.llvm.org/D60189

Modified:
    llvm/trunk/test/tools/llvm-objcopy/ELF/rename-section-flag.test
    llvm/trunk/test/tools/llvm-objcopy/ELF/set-section-flags.test
    llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp

Modified: llvm/trunk/test/tools/llvm-objcopy/ELF/rename-section-flag.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/rename-section-flag.test?rev=359639&r1=359638&r2=359639&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/rename-section-flag.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/rename-section-flag.test Tue Apr 30 17:39:31 2019
@@ -12,7 +12,7 @@
 # RUN: llvm-readobj --sections %t.noload | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
 # RUN: llvm-objcopy --rename-section=.foo=.bar,readonly  \
 # RUN:   --rename-section=.baz=.blah,readonly %t %t.readonly
-# RUN: llvm-readobj --sections %t.readonly | FileCheck %s --check-prefixes=CHECK,NOBITS
+# RUN: llvm-readobj --sections %t.readonly | FileCheck %s --check-prefixes=CHECK,PROGBITS
 # RUN: llvm-objcopy --rename-section=.foo=.bar,debug  \
 # RUN:   --rename-section=.baz=.blah,debug %t %t.debug
 # RUN: llvm-readobj --sections %t.debug | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
@@ -30,13 +30,13 @@
 # RUN: llvm-readobj --sections %t.contents | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
 # RUN: llvm-objcopy --rename-section=.foo=.bar,merge  \
 # RUN:   --rename-section=.baz=.blah,merge %t %t.merge
-# RUN: llvm-readobj --sections %t.merge | FileCheck %s --check-prefixes=CHECK,NOBITS,MERGE,WRITE
+# RUN: llvm-readobj --sections %t.merge | FileCheck %s --check-prefixes=CHECK,PROGBITS,MERGE,WRITE
 # RUN: llvm-objcopy --rename-section=.foo=.bar,strings  \
 # RUN:   --rename-section=.baz=.blah,strings %t %t.strings
-# RUN: llvm-readobj --sections %t.strings | FileCheck %s --check-prefixes=CHECK,NOBITS,STRINGS,WRITE
+# RUN: llvm-readobj --sections %t.strings | FileCheck %s --check-prefixes=CHECK,PROGBITS,STRINGS,WRITE
 # RUN: llvm-objcopy --rename-section=.foo=.bar,share  \
 # RUN:   --rename-section=.baz=.blah,share %t %t.share
-# RUN: llvm-readobj --sections %t.share | FileCheck %s --check-prefixes=CHECK,NOBITS,WRITE
+# RUN: llvm-readobj --sections %t.share | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
 
 # Multiple flags:
 # RUN: llvm-objcopy --rename-section=.foo=.bar,alloc,readonly,strings  \
@@ -44,7 +44,7 @@
 # RUN: llvm-readobj --sections %t.alloc_ro_strings | FileCheck %s --check-prefixes=CHECK,NOBITS,ALLOC,STRINGS
 # RUN: llvm-objcopy --rename-section=.foo=.bar,alloc,code  \
 # RUN:   --rename-section=.baz=.blah,alloc,code %t %t.alloc_code
-# RUN: llvm-readobj --sections %t.alloc_code | FileCheck %s --check-prefixes=CHECK,PROGBITS,ALLOC,EXEC,WRITE
+# RUN: llvm-readobj --sections %t.alloc_code | FileCheck %s --check-prefixes=CHECK,NOBITS,ALLOC,EXEC,WRITE
 
 # Invalid flags:
 # RUN: not llvm-objcopy --rename-section=.foo=.bar,xyzzy %t %t.xyzzy 2>&1 | FileCheck %s --check-prefix=BAD-FLAG

Modified: llvm/trunk/test/tools/llvm-objcopy/ELF/set-section-flags.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/set-section-flags.test?rev=359639&r1=359638&r2=359639&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/set-section-flags.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/set-section-flags.test Tue Apr 30 17:39:31 2019
@@ -12,7 +12,7 @@
 # RUN: llvm-readobj --sections %t.noload | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
 # RUN: llvm-objcopy --set-section-flags=.foo=readonly \
 # RUN:   --set-section-flags=.baz=readonly --set-section-flags=.rela.baz=readonly %t %t.readonly
-# RUN: llvm-readobj --sections %t.readonly | FileCheck %s --check-prefixes=CHECK,NOBITS
+# RUN: llvm-readobj --sections %t.readonly | FileCheck %s --check-prefixes=CHECK,PROGBITS
 # RUN: llvm-objcopy --set-section-flags=.foo=debug \
 # RUN:   --set-section-flags=.baz=debug --set-section-flags=.rela.baz=debug %t %t.debug
 # RUN: llvm-readobj --sections %t.debug | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
@@ -30,13 +30,13 @@
 # RUN: llvm-readobj --sections %t.contents | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
 # RUN: llvm-objcopy --set-section-flags=.foo=merge \
 # RUN:   --set-section-flags=.baz=merge --set-section-flags=.rela.baz=merge %t %t.merge
-# RUN: llvm-readobj --sections %t.merge | FileCheck %s --check-prefixes=CHECK,MERGE,NOBITS,WRITE
+# RUN: llvm-readobj --sections %t.merge | FileCheck %s --check-prefixes=CHECK,MERGE,PROGBITS,WRITE
 # RUN: llvm-objcopy --set-section-flags=.foo=strings \
 # RUN:   --set-section-flags=.baz=strings --set-section-flags=.rela.baz=strings %t %t.strings
-# RUN: llvm-readobj --sections %t.strings | FileCheck %s --check-prefixes=CHECK,STRINGS,NOBITS,WRITE
+# RUN: llvm-readobj --sections %t.strings | FileCheck %s --check-prefixes=CHECK,STRINGS,PROGBITS,WRITE
 # RUN: llvm-objcopy --set-section-flags=.foo=share \
 # RUN:   --set-section-flags=.baz=share --set-section-flags=.rela.baz=share %t %t.share
-# RUN: llvm-readobj --sections %t.share | FileCheck %s --check-prefixes=CHECK,NOBITS,WRITE
+# RUN: llvm-readobj --sections %t.share | FileCheck %s --check-prefixes=CHECK,PROGBITS,WRITE
 
 # Multiple flags:
 # RUN: llvm-objcopy --set-section-flags=.foo=alloc,readonly,strings \
@@ -46,7 +46,7 @@
 # RUN: llvm-objcopy --set-section-flags=.foo=alloc,code \
 # RUN:   --set-section-flags=.baz=alloc,code \
 # RUN:   --set-section-flags=.rela.baz=alloc,code %t %t.alloc_code
-# RUN: llvm-readobj --sections %t.alloc_code | FileCheck %s --check-prefixes=CHECK,PROGBITS,ALLOC,EXEC,WRITE
+# RUN: llvm-readobj --sections %t.alloc_code | FileCheck %s --check-prefixes=CHECK,NOBITS,ALLOC,EXEC,WRITE
 
 # Invalid flags:
 # RUN: not llvm-objcopy --set-section-flags=.foo=xyzzy %t %t.xyzzy 2>&1 | FileCheck %s --check-prefix=BAD-FLAG

Modified: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp?rev=359639&r1=359638&r2=359639&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp Tue Apr 30 17:39:31 2019
@@ -99,13 +99,12 @@ static uint64_t getSectionFlagsPreserveM
 static void setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags) {
   Sec.Flags = getSectionFlagsPreserveMask(Sec.Flags, getNewShfFlags(Flags));
 
-  // Certain flags also promote SHT_NOBITS to SHT_PROGBITS. Don't change other
-  // section types (RELA, SYMTAB, etc.).
-  const SectionFlag NoBitsToProgBitsMask =
-      SectionFlag::SecContents | SectionFlag::SecLoad | SectionFlag::SecNoload |
-      SectionFlag::SecCode | SectionFlag::SecData | SectionFlag::SecRom |
-      SectionFlag::SecDebug;
-  if (Sec.Type == SHT_NOBITS && (Flags & NoBitsToProgBitsMask))
+  // In GNU objcopy, certain flags promote SHT_NOBITS to SHT_PROGBITS. This rule
+  // may promote more non-ALLOC sections than GNU objcopy, but it is fine as
+  // non-ALLOC SHT_NOBITS sections do not make much sense.
+  if (Sec.Type == SHT_NOBITS &&
+      (!(Sec.Flags & ELF::SHF_ALLOC) ||
+       Flags & (SectionFlag::SecContents | SectionFlag::SecLoad)))
     Sec.Type = SHT_PROGBITS;
 }
 




More information about the llvm-commits mailing list