From 005159e92420a102516ee6e29ef2178c818da5d0 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 23 Apr 2013 10:17:34 +0000 Subject: [PATCH] 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 --- cmake/config-ix.cmake | 6 ++- lib/DebugInfo/DWARFContext.cpp | 38 ++++++++++++++++++ lib/DebugInfo/DWARFContext.h | 3 ++ test/DebugInfo/Inputs/dwarfdump-test-zlib.cc | 24 +++++++++++ .../Inputs/dwarfdump-test-zlib.elf-x86-64 | Bin 0 -> 9589 bytes test/DebugInfo/dwarfdump-zlib.test | 12 ++++++ test/Makefile | 1 + test/lit.cfg | 3 ++ test/lit.site.cfg.in | 1 + 9 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 test/DebugInfo/Inputs/dwarfdump-test-zlib.cc create mode 100755 test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 create mode 100644 test/DebugInfo/dwarfdump-zlib.test diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index c426f41f5c9..7c4285a299b 100755 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -105,7 +105,11 @@ if( NOT PURE_WINDOWS ) endif() check_library_exists(dl dlopen "" HAVE_LIBDL) check_library_exists(rt clock_gettime "" HAVE_LIBRT) - check_library_exists(z compress2 "" HAVE_LIBZ) + if (LLVM_ENABLE_ZLIB) + check_library_exists(z compress2 "" HAVE_LIBZ) + else() + set(HAVE_LIBZ 0) + endif() endif() # function checks diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 74a8c36d7ab..1e13731361a 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 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(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 37b272993f3..78c18e61680 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -161,8 +161,11 @@ class DWARFContextInMemory : public DWARFContext { StringRef RangeDWOSection; StringRef AddrSection; + SmallVector 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; } diff --git a/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc b/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc new file mode 100644 index 00000000000..260c3c435c1 --- /dev/null +++ b/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc @@ -0,0 +1,24 @@ +class DummyClass { + int a_; + public: + DummyClass(int a) : a_(a) {} + int add(int b) { + return a_ + b; + } +}; + +int f(int a, int b) { + DummyClass c(a); + return c.add(b); +} + +int main() { + return f(2, 3); +} + +// Built with Clang 3.2 and ld.gold linker: +// $ mkdir -p /tmp/dbginfo +// $ cp dwarfdump-test-zlib.cc /tmp/dbginfo +// $ cd /tmp/dbginfo +// $ clang++ -g dwarfdump-test-zlib.cc -Wl,--compress-debug-sections=zlib \ +// -o diff --git a/test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 b/test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 new file mode 100755 index 0000000000000000000000000000000000000000..16b3153939fa1ba9e4765352951db65620d1c9a1 GIT binary patch literal 9589 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 lit.tmp @$(ECHOPATH) s=@HOST_OS@=$(HOST_OS)=g >> lit.tmp @$(ECHOPATH) s=@HOST_ARCH@=$(HOST_ARCH)=g >> lit.tmp + @$(ECHOPATH) s=@HAVE_LIBZ@=$(HAVE_LIBZ)=g >> lit.tmp @sed -f lit.tmp $(PROJ_SRC_DIR)/lit.site.cfg.in > $@ @-rm -f lit.tmp diff --git a/test/lit.cfg b/test/lit.cfg index ea91f45754d..b423c6e80b7 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -268,6 +268,9 @@ if (config.llvm_use_sanitizer == "Memory" or if not 'hexagon' in config.target_triple: config.available_features.add("object-emission") +if config.have_zlib == "1": + config.available_features.add("zlib") + # llc knows whether he is compiled with -DNDEBUG. import subprocess try: diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index 8024b24fcde..3a680b28126 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -19,6 +19,7 @@ config.host_os = "@HOST_OS@" config.host_arch = "@HOST_ARCH@" config.llvm_use_intel_jitevents = "@LLVM_USE_INTEL_JITEVENTS@" config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" +config.have_zlib = "@HAVE_LIBZ@" # Support substitution of the tools_dir with user parameters. This is # used when we can't determine the tool dir at configuration time.