diff options
author | George Rimar <grimar@accesssoftek.com> | 2016-05-24 10:46:43 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2016-05-24 10:46:43 +0000 |
commit | e9b2e19109d97d8951018d7647631ac7fe20b51c (patch) | |
tree | 9ec3e827ff5beb8d149444c0f367975c229ff107 /llvm/lib | |
parent | 672c710de4aaa64a99c8bc08a67f351c1fa932d6 (diff) | |
download | llvm-e9b2e19109d97d8951018d7647631ac7fe20b51c.zip llvm-e9b2e19109d97d8951018d7647631ac7fe20b51c.tar.gz llvm-e9b2e19109d97d8951018d7647631ac7fe20b51c.tar.bz2 |
Recommit r270540
fix: forgot to commit the updated dwarfdump-test-zlib.elf-x86-64
Original commit message:
[llvm-dwarfdump] - Teach dwarfdump to decompress debug sections in zlib style.
Before this llvm-dwarfdump only recognized zlib-gnu compression style of headers,
this patch adds support for zlib style.
It looks reasonable to support both styles for dumping,
even if we are not going to suport generating of deprecated gnu one.
Differential revision: http://reviews.llvm.org/D20470
llvm-svn: 270543
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 68 | ||||
-rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 4 |
3 files changed, 61 insertions, 15 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index d3b5e73..27b8c56 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -15,6 +15,7 @@ #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/ELF.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -590,8 +591,8 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; } -static bool consumeCompressedDebugSectionHeader(StringRef &data, - uint64_t &OriginalSize) { +static bool consumeCompressedGnuHeader(StringRef &data, + uint64_t &OriginalSize) { // Consume "ZLIB" prefix. if (!data.startswith("ZLIB")) return false; @@ -606,6 +607,50 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data, 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()), @@ -631,20 +676,13 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. - // Check if debug info section is compressed with zlib. - if (name.startswith("zdebug_")) { - uint64_t OriginalSize; - if (!zlib::isAvailable() || - !consumeCompressedDebugSectionHeader(data, OriginalSize)) + bool ZLibStyleCompressed = Section.isCompressed(); + if (ZLibStyleCompressed || name.startswith("zdebug_")) { + SmallString<32> Out; + if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian, + AddressSize == 8)) continue; - UncompressedSections.resize(UncompressedSections.size() + 1); - if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) != - zlib::StatusOK) { - UncompressedSections.pop_back(); - continue; - } - // Make data point to uncompressed section contents and save its contents. - name = name.substr(1); + UncompressedSections.emplace_back(std::move(Out)); data = UncompressedSections.back(); } diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 4b6ab23..489c69c 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -292,6 +292,10 @@ uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const { return Sec->getAlignment(); } +bool COFFObjectFile::isSectionCompressed(DataRefImpl Sec) const { + return false; +} + bool COFFObjectFile::isSectionText(DataRefImpl Ref) const { const coff_section *Sec = toSec(Ref); return Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 760249f..d7ec3e5 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -653,6 +653,10 @@ uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const { return uint64_t(1) << Align; } +bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const { + return false; +} + bool MachOObjectFile::isSectionText(DataRefImpl Sec) const { uint32_t Flags = getSectionFlags(this, Sec); return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; |