Index: llvm/trunk/include/llvm/Object/COFF.h
===================================================================
--- llvm/trunk/include/llvm/Object/COFF.h
+++ llvm/trunk/include/llvm/Object/COFF.h
@@ -694,6 +694,7 @@
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+  bool isSectionCompressed(DataRefImpl Sec) const override;
   bool isSectionText(DataRefImpl Sec) const override;
   bool isSectionData(DataRefImpl Sec) const override;
   bool isSectionBSS(DataRefImpl Sec) const override;
Index: llvm/trunk/include/llvm/Object/ELFObjectFile.h
===================================================================
--- llvm/trunk/include/llvm/Object/ELFObjectFile.h
+++ llvm/trunk/include/llvm/Object/ELFObjectFile.h
@@ -222,6 +222,7 @@
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+  bool isSectionCompressed(DataRefImpl Sec) const override;
   bool isSectionText(DataRefImpl Sec) const override;
   bool isSectionData(DataRefImpl Sec) const override;
   bool isSectionBSS(DataRefImpl Sec) const override;
@@ -584,6 +585,11 @@
 }
 
 template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
+  return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
+}
+
+template <class ELFT>
 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
   return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
 }
Index: llvm/trunk/include/llvm/Object/MachO.h
===================================================================
--- llvm/trunk/include/llvm/Object/MachO.h
+++ llvm/trunk/include/llvm/Object/MachO.h
@@ -222,6 +222,7 @@
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+  bool isSectionCompressed(DataRefImpl Sec) const override;
   bool isSectionText(DataRefImpl Sec) const override;
   bool isSectionData(DataRefImpl Sec) const override;
   bool isSectionBSS(DataRefImpl Sec) const override;
Index: llvm/trunk/include/llvm/Object/ObjectFile.h
===================================================================
--- llvm/trunk/include/llvm/Object/ObjectFile.h
+++ llvm/trunk/include/llvm/Object/ObjectFile.h
@@ -89,6 +89,7 @@
   /// @brief Get the alignment of this section as the actual value (not log 2).
   uint64_t getAlignment() const;
 
+  bool isCompressed() const;
   bool isText() const;
   bool isData() const;
   bool isBSS() const;
@@ -214,6 +215,7 @@
   virtual std::error_code getSectionContents(DataRefImpl Sec,
                                              StringRef &Res) const = 0;
   virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
+  virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
   virtual bool isSectionText(DataRefImpl Sec) const = 0;
   virtual bool isSectionData(DataRefImpl Sec) const = 0;
   virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
@@ -380,6 +382,10 @@
   return OwningObject->getSectionAlignment(SectionPimpl);
 }
 
+inline bool SectionRef::isCompressed() const {
+  return OwningObject->isSectionCompressed(SectionPimpl);
+}
+
 inline bool SectionRef::isText() const {
   return OwningObject->isSectionText(SectionPimpl);
 }
Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ llvm/trunk/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 @@
   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 @@
   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 @@
 
     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();
     }
 
Index: llvm/trunk/lib/Object/COFFObjectFile.cpp
===================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp
@@ -292,6 +292,10 @@
   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;
Index: llvm/trunk/lib/Object/MachOObjectFile.cpp
===================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp
@@ -653,6 +653,10 @@
   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;
Index: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc
===================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-zlib.cc
@@ -16,9 +16,11 @@
   return f(2, 3);
 }
 
-// Built with Clang 3.2 and ld.gold linker:
+// Built with Clang 3.9 and GNU gold (GNU Binutils for Ubuntu 2.26) 1.11:
 // $ 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>
+// $ clang++ -g dwarfdump-test-zlib.cc -Wl,--compress-debug-sections=zlib -o dwarfdump-test-zlib.elf-x86-64
+// $ clang++ -g dwarfdump-test-zlib.cc -Wl,--compress-debug-sections=zlib-gnu -o dwarfdump-test-zlibgnu.elf-x86-64
+// llvm-readobj -sections can be used to see that outputs really contain the compressed sections, also output in both
+//   cases is slightly smaller, that is because of compression.
\ No newline at end of file
Index: llvm/trunk/test/DebugInfo/dwarfdump-zlib.test
===================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-zlib.test
+++ llvm/trunk/test/DebugInfo/dwarfdump-zlib.test
@@ -1,6 +1,12 @@
 REQUIRES: zlib
 
 RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-zlib.elf-x86-64 | FileCheck %s
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-zlibgnu.elf-x86-64 | FileCheck %s
 
 CHECK: .debug_abbrev contents
+
+// Dump content of a little section to check that both zlib and zlib gnu styles do
+// the decompression correctly and result is the same. This and above also checks
+// that sections names are properly shown in zlib-gnu style (without additional 'z' prefix).
 CHECK: .debug_info contents
+CHECK: 0x00000000: Compile Unit: length = 0x00000144 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000148)