This is an archive of the discontinued LLVM Phabricator instance.

[llvm-objcopy] -O binary: skip empty sections
ClosedPublic

Authored by MaskRay on Apr 30 2020, 11:55 PM.

Details

Summary

After SHF_ALLOC sections are ordered by LMA:

  • If initial sections are empty, GNU objcopy skips their contents while we emit leading zeros. (binary-paddr.test %t4)
  • If trailing sections are empty, GNU objcopy skips their contents while we emit trailing zeros. (binary-paddr.test %t5)

This patch matches GNU objcopy's behavior. Linkers don't keep p_memsz
PT_LOAD segments. Such empty sections would not have a containing
PT_LOAD and Section::ParentSegment might be null if linkers fail to
optimize the file offsets (lld D79254).

In particular, without D79254, the arm Linux kernel's multi_v5_defconfig
depends on this behavior: in vmlinux, an empty .text_itcm is mapped at
a very high address (0xfffe0000) but the kernel does not expect `objcopy
-O binary` to create a very large arch/arm/boot/Image
(0xfffe0000-0xc0000000 ~= 1GiB). See
https://bugs.llvm.org/show_bug.cgi?id=45632

Diff Detail

Event Timeline

MaskRay created this revision.Apr 30 2020, 11:55 PM

Thanks for the fix! I can confirm that a multi_v5_defconfig kernel looks normal size wise and boots in QEMU. I will do a set of kernel builds overnight to make sure that nothing else regresses.

jhenderson accepted this revision.May 1 2020, 2:23 AM

LGTM, with a couple of nits.

llvm/test/tools/llvm-objcopy/ELF/binary-paddr.test
138

Nit: I'd find it clearer if there was a blank line after the RUN lines before the SKIP-EMPTY lines.

Aside: I'm slightly surprised this works, given that -EMPTY is also a FileCheck suffix!

177

Nit: blank line before this line.

This revision is now accepted and ready to land.May 1 2020, 2:23 AM
MaskRay updated this revision to Diff 261547.May 1 2020, 2:21 PM
MaskRay marked 3 inline comments as done.
MaskRay edited the summary of this revision. (Show Details)

Address comments

llvm/test/tools/llvm-objcopy/ELF/binary-paddr.test
138

Switched to SKIPEMPTY.

The -EMPTY -DAG` arguments may suggest that we probably should prefer FOO_BAR to FOO-BAR...

MaskRay updated this revision to Diff 261548.May 1 2020, 2:24 PM

Simplify tests

This revision was automatically updated to reflect the committed changes.
vitalybuka reopened this revision.May 3 2020, 7:46 PM
vitalybuka added a subscriber: vitalybuka.

http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/41020/steps/check-llvm%20ubsan/logs/stdio

--
/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:147:51: runtime error: addition of unsigned offset to 0x7f7a7b973000 overflowed to 0x7f7a7b972000
    #0 0x48e24c in llvm::objcopy::elf::SectionWriter::visit(llvm::objcopy::elf::Section const&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:147:51
    #1 0x495b37 in llvm::objcopy::elf::BinaryWriter::write() /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:2214:9
    #2 0x459738 in llvm::objcopy::elf::writeOutput(llvm::objcopy::CopyConfig const&, llvm::objcopy::elf::Object&, llvm::objcopy::Buffer&, llvm::objcopy::elf::ElfType) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp:757:18
    #3 0x459d09 in llvm::objcopy::elf::executeObjcopyOnBinary(llvm::objcopy::CopyConfig const&, llvm::object::ELFObjectFileBase&, llvm::objcopy::Buffer&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp:819:17
    #4 0x43f1cb in executeObjcopyOnBinary(llvm::objcopy::CopyConfig&, llvm::object::Binary&, llvm::objcopy::Buffer&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:173:12
    #5 0x43cd75 in executeObjcopy /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:301:21
    #6 0x43cd75 in main /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:374:19
    #7 0x7f7a7b26109a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)
    #8 0x40ab79 in _start (/b/sanitizer-x86_64-linux-fast/build/llvm_build_ubsan/bin/llvm-objcopy+0x40ab79)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:147:51 in 

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
********************
Failing Tests (1):
  LLVM :: tools/llvm-objcopy/ELF/binary-paddr.test
This revision is now accepted and ready to land.May 3 2020, 7:46 PM

http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/41020/steps/check-llvm%20ubsan/logs/stdio

--
/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:147:51: runtime error: addition of unsigned offset to 0x7f7a7b973000 overflowed to 0x7f7a7b972000
    #0 0x48e24c in llvm::objcopy::elf::SectionWriter::visit(llvm::objcopy::elf::Section const&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:147:51
    #1 0x495b37 in llvm::objcopy::elf::BinaryWriter::write() /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:2214:9
    #2 0x459738 in llvm::objcopy::elf::writeOutput(llvm::objcopy::CopyConfig const&, llvm::objcopy::elf::Object&, llvm::objcopy::Buffer&, llvm::objcopy::elf::ElfType) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp:757:18
    #3 0x459d09 in llvm::objcopy::elf::executeObjcopyOnBinary(llvm::objcopy::CopyConfig const&, llvm::object::ELFObjectFileBase&, llvm::objcopy::Buffer&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp:819:17
    #4 0x43f1cb in executeObjcopyOnBinary(llvm::objcopy::CopyConfig&, llvm::object::Binary&, llvm::objcopy::Buffer&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:173:12
    #5 0x43cd75 in executeObjcopy /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:301:21
    #6 0x43cd75 in main /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/llvm-objcopy.cpp:374:19
    #7 0x7f7a7b26109a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)
    #8 0x40ab79 in _start (/b/sanitizer-x86_64-linux-fast/build/llvm_build_ubsan/bin/llvm-objcopy+0x40ab79)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/tools/llvm-objcopy/ELF/Object.cpp:147:51 in 

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
********************
Failing Tests (1):
  LLVM :: tools/llvm-objcopy/ELF/binary-paddr.test

Thanks! Fixed by 762fb1c40eea6878c2d6a1f0f1fc7915c8747981

MaskRay closed this revision.May 3 2020, 9:59 PM