From c997fe658655b42237f556c11c7f5bc8ec60658b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 22 Sep 2022 10:26:47 -0700 Subject: [PATCH] [llvm-objcopy] --compress-debug-sections: remove tail padding for ELFCLASS32 For an ELFCLASS32 object, a compressed section due to --compress-debug-sections={zlib,zstd} has a tail padding of 12 zero bytes. zlib happily allows this while zstd is rigid and reports `error: '{{.*}}': failed to decompress section '.debug_foo': Src size is incorrect`. Cole Kissane reported the problem. Reviewed By: jhenderson, phosek Differential Revision: https://reviews.llvm.org/D134385 --- llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp | 2 +- llvm/lib/ObjCopy/ELF/ELFObject.cpp | 11 +++++------ llvm/lib/ObjCopy/ELF/ELFObject.h | 3 ++- .../llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml | 2 +- .../tools/llvm-objcopy/ELF/compress-debug-sections-zstd.test | 6 ++++++ 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp index 781be3d..2f6581b 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp @@ -510,7 +510,7 @@ static Error replaceAndRemoveSections(const CommonConfig &Config, Obj, isCompressable, [&Config, &Obj](const SectionBase *S) -> Expected { return &Obj.addSection( - CompressedSection(*S, Config.CompressionType)); + CompressedSection(*S, Config.CompressionType, Obj.Is64Bits)); })) return Err; } else if (Config.DecompressDebugSections) { diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp index a2edad8..abbced6 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp @@ -527,18 +527,16 @@ Error ELFSectionWriter::visit(const CompressedSection &Sec) { } CompressedSection::CompressedSection(const SectionBase &Sec, - DebugCompressionType CompressionType) + DebugCompressionType CompressionType, + bool Is64Bits) : SectionBase(Sec), CompressionType(CompressionType), DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) { compression::compress(compression::Params(CompressionType), OriginalData, CompressedData); Flags |= ELF::SHF_COMPRESSED; - size_t ChdrSize = - std::max(std::max(sizeof(object::Elf_Chdr_Impl), - sizeof(object::Elf_Chdr_Impl)), - std::max(sizeof(object::Elf_Chdr_Impl), - sizeof(object::Elf_Chdr_Impl))); + size_t ChdrSize = Is64Bits ? sizeof(object::Elf_Chdr_Impl) + : sizeof(object::Elf_Chdr_Impl); Size = ChdrSize + CompressedData.size(); Align = 8; } @@ -1873,6 +1871,7 @@ template Error ELFBuilder::build(bool EnsureSymtab) { return HeadersFile.takeError(); const typename ELFFile::Elf_Ehdr &Ehdr = HeadersFile->getHeader(); + Obj.Is64Bits = Ehdr.e_ident[EI_CLASS] == ELFCLASS64; Obj.OSABI = Ehdr.e_ident[EI_OSABI]; Obj.ABIVersion = Ehdr.e_ident[EI_ABIVERSION]; Obj.Type = Ehdr.e_type; diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.h b/llvm/lib/ObjCopy/ELF/ELFObject.h index 7fb4e05..d20afa3 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObject.h +++ b/llvm/lib/ObjCopy/ELF/ELFObject.h @@ -544,7 +544,7 @@ class CompressedSection : public SectionBase { public: CompressedSection(const SectionBase &Sec, - DebugCompressionType CompressionType); + DebugCompressionType CompressionType, bool Is64Bits); CompressedSection(ArrayRef CompressedData, uint32_t ChType, uint64_t DecompressedSize, uint64_t DecompressedAlign); @@ -1045,6 +1045,7 @@ public: Segment ElfHdrSegment; Segment ProgramHdrSegment; + bool Is64Bits; uint8_t OSABI; uint8_t ABIVersion; uint64_t Entry; diff --git a/llvm/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml b/llvm/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml index 888e5a5..67d8435 100644 --- a/llvm/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml +++ b/llvm/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml @@ -1,6 +1,6 @@ --- !ELF FileHeader: - Class: ELFCLASS64 + Class: ELFCLASS[[BITS=64]] Data: ELFDATA2LSB Type: ET_REL Machine: EM_X86_64 diff --git a/llvm/test/tools/llvm-objcopy/ELF/compress-debug-sections-zstd.test b/llvm/test/tools/llvm-objcopy/ELF/compress-debug-sections-zstd.test index f71450c..d763131 100644 --- a/llvm/test/tools/llvm-objcopy/ELF/compress-debug-sections-zstd.test +++ b/llvm/test/tools/llvm-objcopy/ELF/compress-debug-sections-zstd.test @@ -32,6 +32,12 @@ # RUN: cmp %t-zstd %t-zstd-zstd # RUN: %if zlib %{ llvm-objcopy --compress-debug-sections=zlib %t-zstd %t-zstd-zlib && cmp %t-zstd %t-zstd-zlib %} +## Test roundtrip for ELFCLASS32. +# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t32 && llvm-objcopy %t32 +# RUN: llvm-objcopy --compress-debug-sections=zstd %t32 %t32-zstd +# RUN: llvm-objcopy --decompress-debug-sections %t32-zstd %t32-de +# RUN: cmp %t32 %t32-de + # RUN: yaml2obj %s -o %t-corrupted # RUN: not llvm-objcopy --decompress-debug-sections %t-corrupted /dev/null 2>&1 | FileCheck %s -DFILE=%t-corrupted --check-prefix=ERR -- 2.7.4