summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-04-23 10:17:34 +0000
committerAlexey Samsonov <samsonov@google.com>2013-04-23 10:17:34 +0000
commit005159e92420a102516ee6e29ef2178c818da5d0 (patch)
tree12692c0e8cf95807e5645786b7bc751f8bf71692 /lib
parentab4d569f2841beaf6152179b1f4da6b7e0f3530e (diff)
downloadllvm-005159e92420a102516ee6e29ef2178c818da5d0.tar.gz
llvm-005159e92420a102516ee6e29ef2178c818da5d0.tar.bz2
llvm-005159e92420a102516ee6e29ef2178c818da5d0.tar.xz
Use zlib to uncompress debug sections in DWARF parser.
This makes llvm-dwarfdump and llvm-symbolizer understand debug info sections compressed by ld.gold linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180088 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/DebugInfo/DWARFContext.cpp38
-rw-r--r--lib/DebugInfo/DWARFContext.h3
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 74a8c36d7a..1e13731361 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -10,6 +10,8 @@
#include "DWARFContext.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
@@ -483,6 +485,22 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
return InliningInfo;
}
+static bool consumeCompressedDebugSectionHeader(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;
+}
+
DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
IsLittleEndian(Obj->isLittleEndian()),
AddressSize(Obj->getBytesInAddress()) {
@@ -497,6 +515,22 @@ DWARFContextInMemory::DWARFContextInMemory(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))
+ continue;
+ OwningPtr<MemoryBuffer> UncompressedSection;
+ if (zlib::uncompress(data, UncompressedSection, OriginalSize) !=
+ zlib::StatusOK)
+ continue;
+ // Make data point to uncompressed section contents and save its contents.
+ name = name.substr(1);
+ data = UncompressedSection->getBuffer();
+ UncompressedSections.push_back(UncompressedSection.take());
+ }
+
StringRef *Section = StringSwitch<StringRef*>(name)
.Case("debug_info", &InfoSection)
.Case("debug_abbrev", &AbbrevSection)
@@ -584,4 +618,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
}
}
+DWARFContextInMemory::~DWARFContextInMemory() {
+ DeleteContainerPointers(UncompressedSections);
+}
+
void DWARFContextInMemory::anchor() { }
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index 37b272993f..78c18e6168 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -161,8 +161,11 @@ class DWARFContextInMemory : public DWARFContext {
StringRef RangeDWOSection;
StringRef AddrSection;
+ SmallVector<MemoryBuffer*, 4> UncompressedSections;
+
public:
DWARFContextInMemory(object::ObjectFile *);
+ ~DWARFContextInMemory();
virtual bool isLittleEndian() const { return IsLittleEndian; }
virtual uint8_t getAddressSize() const { return AddressSize; }
virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }