diff options
author | Fangrui Song <maskray@google.com> | 2019-05-01 00:39:31 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-05-01 00:39:31 +0000 |
commit | aa1f2c50a8f8bf95e80e573a6917b1eb5ae2a979 (patch) | |
tree | 5277bf1bd3d7f19f359cb5ae99958d929006eee5 | |
parent | c0806e0d24add3895768ac1638a75b898433a03e (diff) | |
download | bcm5719-llvm-aa1f2c50a8f8bf95e80e573a6917b1eb5ae2a979.tar.gz bcm5719-llvm-aa1f2c50a8f8bf95e80e573a6917b1eb5ae2a979.zip |
[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
llvm-svn: 359639
-rw-r--r-- | llvm/test/tools/llvm-objcopy/ELF/rename-section-flag.test | 10 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objcopy/ELF/set-section-flags.test | 10 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 13 |
3 files changed, 16 insertions, 17 deletions
diff --git a/llvm/test/tools/llvm-objcopy/ELF/rename-section-flag.test b/llvm/test/tools/llvm-objcopy/ELF/rename-section-flag.test index e990539784c..206e8b43bbd 100644 --- a/llvm/test/tools/llvm-objcopy/ELF/rename-section-flag.test +++ b/llvm/test/tools/llvm-objcopy/ELF/rename-section-flag.test @@ -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 diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-section-flags.test b/llvm/test/tools/llvm-objcopy/ELF/set-section-flags.test index 1c8d00bf18e..b312d3181f4 100644 --- a/llvm/test/tools/llvm-objcopy/ELF/set-section-flags.test +++ b/llvm/test/tools/llvm-objcopy/ELF/set-section-flags.test @@ -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 diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp index 7e991169124..9b21190000e 100644 --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -99,13 +99,12 @@ static uint64_t getSectionFlagsPreserveMask(uint64_t OldFlags, 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; } |