summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-05-24 09:28:36 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-05-24 09:28:36 +0000
commit6bcbf4c572c25b066bd4dd1592ddbe2268b43406 (patch)
treeba69b074a2f480ad23372beae89a48bcf7c23c8d /llvm/lib
parent13a49374048c0d9e1600cda96f181d07ce732042 (diff)
downloadbcm5719-llvm-6bcbf4c572c25b066bd4dd1592ddbe2268b43406.tar.gz
bcm5719-llvm-6bcbf4c572c25b066bd4dd1592ddbe2268b43406.zip
[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: 270540
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp68
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp4
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp4
3 files changed, 61 insertions, 15 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index d3b5e736c48..27b8c564d91 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 4b6ab23f5ff..489c69cc4bc 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 760249f56a8..d7ec3e57a58 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;
OpenPOWER on IntegriCloud