diff --git a/llvm/include/llvm/Object/Decompressor.h b/llvm/include/llvm/Object/Decompressor.h --- a/llvm/include/llvm/Object/Decompressor.h +++ b/llvm/include/llvm/Object/Decompressor.h @@ -43,19 +43,9 @@ /// Return memory buffer size required for decompression. uint64_t getDecompressedSize() { return DecompressedSize; } - /// Return true if section is compressed, including gnu-styled case. - static bool isCompressed(const object::SectionRef &Section); - - /// Return true if section is a ELF compressed one. - static bool isCompressedELFSection(uint64_t Flags, StringRef Name); - - /// Return true if section name matches gnu style compressed one. - static bool isGnuStyle(StringRef Name); - private: Decompressor(StringRef Data); - Error consumeCompressedGnuHeader(); Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian); StringRef SectionData; diff --git a/llvm/lib/DWP/DWP.cpp b/llvm/lib/DWP/DWP.cpp --- a/llvm/lib/DWP/DWP.cpp +++ b/llvm/lib/DWP/DWP.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm/Object/Decompressor.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/MemoryBuffer.h" using namespace llvm; @@ -273,12 +274,16 @@ static Error handleCompressedSection(std::deque> &UncompressedSections, - StringRef &Name, StringRef &Contents) { - if (!Decompressor::isGnuStyle(Name)) + SectionRef Sec, StringRef Name, StringRef &Contents) { + auto *Obj = dyn_cast(Sec.getObject()); + if (!Obj || + !(static_cast(Sec).getFlags() & ELF::SHF_COMPRESSED)) return Error::success(); - - Expected Dec = - Decompressor::create(Name, Contents, false /*IsLE*/, false /*Is64Bit*/); + bool IsLE = isa(Obj) || + isa(Obj); + bool Is64 = isa(Obj) || + isa(Obj); + Expected Dec = Decompressor::create(Name, Contents, IsLE, Is64); if (!Dec) return createError(Name, Dec.takeError()); @@ -286,7 +291,6 @@ if (Error E = Dec->resizeAndDecompress(UncompressedSections.back())) return createError(Name, std::move(E)); - Name = Name.substr(2); // Drop ".z" Contents = UncompressedSections.back(); return Error::success(); } @@ -494,7 +498,8 @@ return ContentsOrErr.takeError(); StringRef Contents = *ContentsOrErr; - if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents)) + if (auto Err = handleCompressedSection(UncompressedSections, Section, Name, + Contents)) return Err; Name = Name.substr(Name.find_first_not_of("._")); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -1645,7 +1645,7 @@ /// provided by Data. Otherwise leaves it unchanged. Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, StringRef &Data) { - if (!Decompressor::isCompressed(Sec)) + if (!Sec.isCompressed()) return Error::success(); Expected Decompressor = diff --git a/llvm/lib/Object/Decompressor.cpp b/llvm/lib/Object/Decompressor.cpp --- a/llvm/lib/Object/Decompressor.cpp +++ b/llvm/lib/Object/Decompressor.cpp @@ -23,9 +23,7 @@ return createError("zlib is not available"); Decompressor D(Data); - Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader() - : D.consumeCompressedZLibHeader(Is64Bit, IsLE); - if (Err) + if (Error Err = D.consumeCompressedZLibHeader(Is64Bit, IsLE)) return std::move(Err); return D; } @@ -33,21 +31,6 @@ Decompressor::Decompressor(StringRef Data) : SectionData(Data), DecompressedSize(0) {} -Error Decompressor::consumeCompressedGnuHeader() { - if (!SectionData.startswith("ZLIB")) - return createError("corrupted compressed section header"); - - SectionData = SectionData.substr(4); - - // Consume uncompressed section size (big-endian 8 bytes). - if (SectionData.size() < 8) - return createError("corrupted uncompressed section size"); - DecompressedSize = read64be(SectionData.data()); - SectionData = SectionData.substr(8); - - return Error::success(); -} - Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian) { using namespace ELF; @@ -72,26 +55,6 @@ return Error::success(); } -bool Decompressor::isGnuStyle(StringRef Name) { - return Name.startswith(".zdebug"); -} - -bool Decompressor::isCompressed(const object::SectionRef &Section) { - if (Section.isCompressed()) - return true; - - Expected SecNameOrErr = Section.getName(); - if (SecNameOrErr) - return isGnuStyle(*SecNameOrErr); - - consumeError(SecNameOrErr.takeError()); - return false; -} - -bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) { - return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name); -} - Error Decompressor::decompress(MutableArrayRef Buffer) { size_t Size = Buffer.size(); return compression::zlib::uncompress(arrayRefFromStringRef(SectionData), diff --git a/llvm/test/tools/llvm-dwp/Inputs/compress/a.dwo b/llvm/test/tools/llvm-dwp/Inputs/compress/a.dwo deleted file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@&1 | FileCheck %s -RUN: not llvm-dwp %p/../Inputs/empty_compressed_section.dwo -o %t 2>&1 | FileCheck %s -RUN: not llvm-dwp %p/../Inputs/invalid_compressed.dwo -o %t 2>&1 | FileCheck %s +# REQUIRES: zlib +# RUN: yaml2obj --docnum=1 %s -o %t1.o +# RUN: not llvm-dwp %t1.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1 +# RUN: yaml2obj --docnum=2 %s -o %t2.o +# RUN: not llvm-dwp %t2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2 -CHECK: error: failure while decompressing compressed section: '.zdebug_{{.*}}.dwo' +# ERR1: error: failure while decompressing compressed section: '.debug_info.dwo', corrupted compressed section header +# ERR2: error: failure while decompressing compressed section: '.debug_info.dwo', zlib error: Z_DATA_ERROR + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_info.dwo + Type: SHT_PROGBITS + Flags: [ SHF_COMPRESSED ] + AddressAlign: 8 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_info.dwo + Type: SHT_PROGBITS + Flags: [ SHF_COMPRESSED ] + AddressAlign: 8 + Content: "010000000000000004000000000000000100000000000000ffff"