diff options
-rwxr-xr-x | cmake/config-ix.cmake | 6 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFContext.cpp | 38 | ||||
-rw-r--r-- | lib/DebugInfo/DWARFContext.h | 3 | ||||
-rw-r--r-- | test/DebugInfo/Inputs/dwarfdump-test-zlib.cc | 24 | ||||
-rwxr-xr-x | test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 | bin | 0 -> 9589 bytes | |||
-rw-r--r-- | test/DebugInfo/dwarfdump-zlib.test | 12 | ||||
-rw-r--r-- | test/Makefile | 1 | ||||
-rw-r--r-- | test/lit.cfg | 3 | ||||
-rw-r--r-- | test/lit.site.cfg.in | 1 |
9 files changed, 87 insertions, 1 deletions
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index c426f41..7c4285a 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 74a8c36..1e13731 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 37b2729..78c18e6 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; } diff --git a/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc b/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc new file mode 100644 index 0000000..260c3c4 --- /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 <output> diff --git a/test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 b/test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 Binary files differnew file mode 100755 index 0000000..16b3153 --- /dev/null +++ b/test/DebugInfo/Inputs/dwarfdump-test-zlib.elf-x86-64 diff --git a/test/DebugInfo/dwarfdump-zlib.test b/test/DebugInfo/dwarfdump-zlib.test new file mode 100644 index 0000000..8ce2cf7 --- /dev/null +++ b/test/DebugInfo/dwarfdump-zlib.test @@ -0,0 +1,12 @@ +REQUIRES: zlib + +RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-zlib.elf-x86-64 \ +RUN: | FileCheck %s -check-prefix FULLDUMP +RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-zlib.elf-x86-64 \ +RUN: --address=0x400559 --functions | FileCheck %s -check-prefix MAIN + +FULLDUMP: .debug_abbrev contents +FULLDUMP: .debug_info contents + +MAIN: main +MAIN-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test-zlib.cc:16 diff --git a/test/Makefile b/test/Makefile index 8d05c57..2213319 100644 --- a/test/Makefile +++ b/test/Makefile @@ -141,6 +141,7 @@ lit.site.cfg: FORCE @$(ECHOPATH) s=@LLVM_BINDINGS@=$(BINDINGS_TO_BUILD)=g >> 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 ea91f45..b423c6e 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 8024b24..3a680b2 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. |