diff options
Diffstat (limited to 'lib/DebugInfo/DWARF/DWARFContext.cpp')
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFContext.cpp | 78 |
1 files changed, 12 insertions, 66 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 7df66c76e8b53..77f6f65ee131c 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/Object/Decompressor.h" #include "llvm/Object/MachO.h" #include "llvm/Object/RelocVisitor.h" #include "llvm/Support/Compression.h" @@ -577,66 +578,6 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; } -static bool consumeCompressedGnuHeader(StringRef &data, - uint64_t &OriginalSize) { - // Consume "ZLIB" prefix. - if (!data.startswith("ZLIB")) - return false; - data = data.substr(4); - // Consume uncompressed section size (big-endian 8 bytes). - DataExtractor extractor(data, false, 8); - uint32_t Offset = 0; - OriginalSize = extractor.getU64(&Offset); - if (Offset == 0) - return false; - data = data.substr(Offset); - return true; -} - -static bool consumeCompressedZLibHeader(StringRef &Data, uint64_t &OriginalSize, - bool IsLE, bool Is64Bit) { - using namespace ELF; - uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr); - if (Data.size() < HdrSize) - return false; - - DataExtractor Extractor(Data, IsLE, 0); - uint32_t Offset = 0; - if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word) - : sizeof(Elf32_Word)) != - ELFCOMPRESS_ZLIB) - return false; - - // Skip Elf64_Chdr::ch_reserved field. - if (Is64Bit) - Offset += sizeof(Elf64_Word); - - OriginalSize = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Xword) - : sizeof(Elf32_Word)); - Data = Data.substr(HdrSize); - return true; -} - -static bool tryDecompress(StringRef &Name, StringRef &Data, - SmallString<32> &Out, bool ZLibStyle, bool IsLE, - bool Is64Bit) { - if (!zlib::isAvailable()) - return false; - - uint64_t OriginalSize; - bool Result = - ZLibStyle ? consumeCompressedZLibHeader(Data, OriginalSize, IsLE, Is64Bit) - : consumeCompressedGnuHeader(Data, OriginalSize); - - if (!Result || zlib::uncompress(Data, Out, OriginalSize) != zlib::StatusOK) - return false; - - // gnu-style names are started from "z", consume that. - if (!ZLibStyle) - Name = Name.substr(1); - return true; -} - DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L) : IsLittleEndian(Obj.isLittleEndian()), @@ -660,18 +601,23 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, if (!L || !L->getLoadedSectionContents(*RelocatedSection,data)) Section.getContents(data); - name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. - - bool ZLibStyleCompressed = Section.isCompressed(); - if (ZLibStyleCompressed || name.startswith("zdebug_")) { + if (Decompressor::isCompressed(Section)) { + Expected<Decompressor> Decompressor = + Decompressor::create(name, data, IsLittleEndian, AddressSize == 8); + if (!Decompressor) + continue; SmallString<32> Out; - if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian, - AddressSize == 8)) + if (auto Err = Decompressor->decompress(Out)) continue; UncompressedSections.emplace_back(std::move(Out)); data = UncompressedSections.back(); } + // Compressed sections names in GNU style starts from ".z", + // at this point section is decompressed and we drop compression prefix. + name = name.substr( + name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes. + StringRef *SectionData = StringSwitch<StringRef *>(name) .Case("debug_info", &InfoSection.Data) |