Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -310,6 +310,9 @@ StringRef *MapSectionToMember(StringRef Name); + Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, + StringRef &Data); + public: DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr); Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -957,6 +957,26 @@ return MachObj->isRelocationScattered(RelocInfo); } +Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec, + StringRef Name, StringRef &Data) { + if (!Decompressor::isCompressed(Sec)) + return Error::success(); + + Expected Decompressor = + Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8); + if (!Decompressor) + return Decompressor.takeError(); + + SmallString<32> Out; + if (auto Err = Decompressor->decompress(Out)) + return Err; + + UncompressedSections.emplace_back(std::move(Out)); + Data = UncompressedSections.back(); + + return Error::success(); +} + DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L) : IsLittleEndian(Obj.isLittleEndian()), @@ -980,16 +1000,11 @@ if (!L || !L->getLoadedSectionContents(*RelocatedSection,data)) Section.getContents(data); - if (Decompressor::isCompressed(Section)) { - Expected Decompressor = - Decompressor::create(name, data, IsLittleEndian, AddressSize == 8); - if (!Decompressor) - continue; - SmallString<32> Out; - if (auto Err = Decompressor->decompress(Out)) - continue; - UncompressedSections.emplace_back(std::move(Out)); - data = UncompressedSections.back(); + if (auto Err = maybeDecompress(Section, name, data)) { + errs() << "error: failed to decompress '" + name + "', " + + toString(std::move(Err)) + << '\n'; + continue; } // Compressed sections names in GNU style starts from ".z", Index: llvm/trunk/test/DebugInfo/dwarfdump-decompression-error.test =================================================================== --- llvm/trunk/test/DebugInfo/dwarfdump-decompression-error.test +++ llvm/trunk/test/DebugInfo/dwarfdump-decompression-error.test @@ -0,0 +1,15 @@ +REQUIRES: zlib + +// dwarfdump-decompression-error.elf-x86-64 is prepared using following +// source code and invocation: +// test.cpp: +// int main() { return 0; } +// +// gcc test.cpp -o out -g -Wl,--compress-debug-sections,zlib +// +// After that result object was modified manually. One random byte in compressed +// content of .debug_info section was changed to 0xff. That breaks normal +// decompression flow in runtime. +RUN: llvm-dwarfdump %p/Inputs/dwarfdump-decompression-error.elf-x86-64 2>&1 | FileCheck %s + +CHECK: error: failed to decompress '.debug_info', zlib error: Z_DATA_ERROR