[llvm] 141c9d7 - [llvm-dwp] Add SHF_COMPRESSED support and remove .zdebug support

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 14 16:19:37 PDT 2022


Author: Fangrui Song
Date: 2022-07-14T16:19:32-07:00
New Revision: 141c9d775961576809f15e83e19a5cd1482f330b

URL: https://github.com/llvm/llvm-project/commit/141c9d775961576809f15e83e19a5cd1482f330b
DIFF: https://github.com/llvm/llvm-project/commit/141c9d775961576809f15e83e19a5cd1482f330b.diff

LOG: [llvm-dwp] Add SHF_COMPRESSED support and remove .zdebug support

clang 14 removed -gz=zlib-gnu and ld.lld/llvm-objcopy removed .zdebug support
recently. llvm-dwp currently doesn't support SHF_COMPRESSED. Add support and
remove .zdebug support.

Simplify llvm::object::Decompressor which has no .zdebug user now.

While here, add tests for ELF32LE, ELF32BE, and ELF64BE.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D129728

Added: 
    

Modified: 
    llvm/include/llvm/Object/Decompressor.h
    llvm/lib/DWP/DWP.cpp
    llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/lib/Object/Decompressor.cpp
    llvm/test/tools/llvm-dwp/X86/compress.test
    llvm/test/tools/llvm-dwp/X86/compressfail.test

Removed: 
    llvm/test/tools/llvm-dwp/Inputs/compress/a.dwo
    llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo
    llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo
    llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o
    llvm/test/tools/llvm-dwp/Inputs/empty_compressed_section.dwo


################################################################################
diff  --git a/llvm/include/llvm/Object/Decompressor.h b/llvm/include/llvm/Object/Decompressor.h
index 00b6c2016742..f43a989d4526 100644
--- a/llvm/include/llvm/Object/Decompressor.h
+++ b/llvm/include/llvm/Object/Decompressor.h
@@ -43,19 +43,9 @@ class Decompressor {
   /// Return memory buffer size required for decompression.
   uint64_t getDecompressedSize() { return DecompressedSize; }
 
-  /// Return true if section is compressed, including gnu-styled case.
-  static bool isCompressed(const object::SectionRef &Section);
-
-  /// Return true if section is a ELF compressed one.
-  static bool isCompressedELFSection(uint64_t Flags, StringRef Name);
-
-  /// Return true if section name matches gnu style compressed one.
-  static bool isGnuStyle(StringRef Name);
-
 private:
   Decompressor(StringRef Data);
 
-  Error consumeCompressedGnuHeader();
   Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
 
   StringRef SectionData;

diff  --git a/llvm/lib/DWP/DWP.cpp b/llvm/lib/DWP/DWP.cpp
index 34615a73e328..44e39c019e0c 100644
--- a/llvm/lib/DWP/DWP.cpp
+++ b/llvm/lib/DWP/DWP.cpp
@@ -16,6 +16,7 @@
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/Object/Decompressor.h"
+#include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 using namespace llvm;
@@ -273,12 +274,16 @@ static Error createError(StringRef Name, Error E) {
 
 static Error
 handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
-                        StringRef &Name, StringRef &Contents) {
-  if (!Decompressor::isGnuStyle(Name))
+                        SectionRef Sec, StringRef Name, StringRef &Contents) {
+  auto *Obj = dyn_cast<ELFObjectFileBase>(Sec.getObject());
+  if (!Obj ||
+      !(static_cast<ELFSectionRef>(Sec).getFlags() & ELF::SHF_COMPRESSED))
     return Error::success();
-
-  Expected<Decompressor> Dec =
-      Decompressor::create(Name, Contents, false /*IsLE*/, false /*Is64Bit*/);
+  bool IsLE = isa<object::ELF32LEObjectFile>(Obj) ||
+              isa<object::ELF64LEObjectFile>(Obj);
+  bool Is64 = isa<object::ELF64LEObjectFile>(Obj) ||
+              isa<object::ELF64BEObjectFile>(Obj);
+  Expected<Decompressor> Dec = Decompressor::create(Name, Contents, IsLE, Is64);
   if (!Dec)
     return createError(Name, Dec.takeError());
 
@@ -286,7 +291,6 @@ handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
   if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
     return createError(Name, std::move(E));
 
-  Name = Name.substr(2); // Drop ".z"
   Contents = UncompressedSections.back();
   return Error::success();
 }
@@ -494,7 +498,8 @@ Error handleSection(
     return ContentsOrErr.takeError();
   StringRef Contents = *ContentsOrErr;
 
-  if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents))
+  if (auto Err = handleCompressedSection(UncompressedSections, Section, Name,
+                                         Contents))
     return Err;
 
   Name = Name.substr(Name.find_first_not_of("._"));

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 2e567d8bc7ee..19d7d659a86a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1645,7 +1645,7 @@ class DWARFObjInMemory final : public DWARFObject {
   /// provided by Data. Otherwise leaves it unchanged.
   Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
                         StringRef &Data) {
-    if (!Decompressor::isCompressed(Sec))
+    if (!Sec.isCompressed())
       return Error::success();
 
     Expected<Decompressor> Decompressor =

diff  --git a/llvm/lib/Object/Decompressor.cpp b/llvm/lib/Object/Decompressor.cpp
index a6a28a0589ac..3842ec92ccfc 100644
--- a/llvm/lib/Object/Decompressor.cpp
+++ b/llvm/lib/Object/Decompressor.cpp
@@ -23,9 +23,7 @@ Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
     return createError("zlib is not available");
 
   Decompressor D(Data);
-  Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
-                               : D.consumeCompressedZLibHeader(Is64Bit, IsLE);
-  if (Err)
+  if (Error Err = D.consumeCompressedZLibHeader(Is64Bit, IsLE))
     return std::move(Err);
   return D;
 }
@@ -33,21 +31,6 @@ Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
 Decompressor::Decompressor(StringRef Data)
     : SectionData(Data), DecompressedSize(0) {}
 
-Error Decompressor::consumeCompressedGnuHeader() {
-  if (!SectionData.startswith("ZLIB"))
-    return createError("corrupted compressed section header");
-
-  SectionData = SectionData.substr(4);
-
-  // Consume uncompressed section size (big-endian 8 bytes).
-  if (SectionData.size() < 8)
-    return createError("corrupted uncompressed section size");
-  DecompressedSize = read64be(SectionData.data());
-  SectionData = SectionData.substr(8);
-
-  return Error::success();
-}
-
 Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
                                                 bool IsLittleEndian) {
   using namespace ELF;
@@ -72,26 +55,6 @@ Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
   return Error::success();
 }
 
-bool Decompressor::isGnuStyle(StringRef Name) {
-  return Name.startswith(".zdebug");
-}
-
-bool Decompressor::isCompressed(const object::SectionRef &Section) {
-  if (Section.isCompressed())
-    return true;
-
-  Expected<StringRef> SecNameOrErr = Section.getName();
-  if (SecNameOrErr)
-    return isGnuStyle(*SecNameOrErr);
-
-  consumeError(SecNameOrErr.takeError());
-  return false;
-}
-
-bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) {
-  return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
-}
-
 Error Decompressor::decompress(MutableArrayRef<uint8_t> Buffer) {
   size_t Size = Buffer.size();
   return compression::zlib::uncompress(arrayRefFromStringRef(SectionData),

diff  --git a/llvm/test/tools/llvm-dwp/Inputs/compress/a.dwo b/llvm/test/tools/llvm-dwp/Inputs/compress/a.dwo
deleted file mode 100644
index 4bef40598562..000000000000
Binary files a/llvm/test/tools/llvm-dwp/Inputs/compress/a.dwo and /dev/null 
diff er

diff  --git a/llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo b/llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo
deleted file mode 100644
index 0201f07d8daf..000000000000
Binary files a/llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo and /dev/null 
diff er

diff  --git a/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo b/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo
deleted file mode 100644
index 63459442e08d..000000000000
Binary files a/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo and /dev/null 
diff er

diff  --git a/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o b/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o
deleted file mode 100644
index f12bb0985792..000000000000
Binary files a/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o and /dev/null 
diff er

diff  --git a/llvm/test/tools/llvm-dwp/Inputs/empty_compressed_section.dwo b/llvm/test/tools/llvm-dwp/Inputs/empty_compressed_section.dwo
deleted file mode 100644
index bc9b4ff983bc..000000000000
Binary files a/llvm/test/tools/llvm-dwp/Inputs/empty_compressed_section.dwo and /dev/null 
diff er

diff  --git a/llvm/test/tools/llvm-dwp/X86/compress.test b/llvm/test/tools/llvm-dwp/X86/compress.test
index ed405cb48c30..f70495a031fd 100644
--- a/llvm/test/tools/llvm-dwp/X86/compress.test
+++ b/llvm/test/tools/llvm-dwp/X86/compress.test
@@ -1,18 +1,65 @@
-REQUIRES: zlib
-RUN: llvm-dwp %p/../Inputs/compress/a.dwo -o %t
-RUN: llvm-dwarfdump -v %t | FileCheck %s
+# REQUIRES: zlib
+# RUN: yaml2obj -DCLASS=32 -DENDIAN=LSB -DINFO_CHDR=010000005600000001000000 %s -o %t.o
+# RUN: llvm-dwp %t.o -o %t
+# RUN: llvm-dwarfdump -v %t | FileCheck %s
 
-Simple test built from this input which produces DWARF long enough to be compressed in the .[z]debug_info section:
+# RUN: yaml2obj -DCLASS=32 -DENDIAN=MSB -DINFO_CHDR=000000010000005600000001 %s -o %t.o
+# RUN: llvm-dwp %t.o -o %t
+# RUN: llvm-dwarfdump -v %t | FileCheck %s
 
-  void f(int a, int b, int c, int d) {
-  }
+# RUN: yaml2obj -DCLASS=64 -DENDIAN=LSB -DINFO_CHDR=01000000fd7f000056000000000000000100000000000000 %s -o %t.o
+# RUN: llvm-dwp %t.o -o %t
+# RUN: llvm-dwarfdump -v %t | FileCheck %s
 
-Since the compression is pretty orthogonal, we're not trying to test that the
-compression library functioned correctly, just that dwp used it to decompress
-the section - so test a few simple features and be done with it.
+# RUN: yaml2obj -DCLASS=64 -DENDIAN=MSB -DINFO_CHDR=0000000100007ffd00000000000000560000000000000001 %s -o %t.o
+# RUN: llvm-dwp %t.o -o %t
+# RUN: llvm-dwarfdump -v %t | FileCheck %s
 
-CHECK: .debug_info.dwo contents:
-CHECK: Compile Unit:
-CHECK:   DW_TAG_compile_unit
-CHECK:     DW_TAG_subprogram
-CHECK:       DW_TAG_formal_parameter
+## Simple test built from this input which produces DWARF long enough to be compressed in the .[z]debug_info section:
+##
+##   void f(int a, int b, int c, int d) {
+##   }
+
+## Since the compression is pretty orthogonal, we're not trying to test that the
+## compression library functioned correctly, just that dwp used it to decompress
+## the section - so test a few simple features and be done with it.
+
+# CHECK: .debug_info.dwo contents:
+# CHECK: Compile Unit:
+# CHECK:   DW_TAG_compile_unit
+# CHECK:     DW_TAG_subprogram
+# CHECK:       DW_TAG_formal_parameter
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS[[CLASS]]
+  Data:            ELFDATA2[[ENDIAN]]
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .debug_loc.dwo
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+  - Name:            .debug_str.dwo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x1
+    EntSize:         0x1
+    Content:         636C616E672076657273696F6E20332E392E3020287472756E6B203236313232332920286C6C766D2F7472756E6B203236313233342900612E637070005F5A3166696969690066006100696E7400620063006400
+  - Name:            .debug_str_offsets.dwo
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         00000000370000003D00000046000000480000004A0000004E0000005000000052000000
+  - Name:            .debug_info.dwo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_COMPRESSED ]
+    AddressAlign:    0x8
+    Content:         [[INFO_CHDR]]789c0b626060606100010e462083f1e6eb7f7c0d8b756299188480628c614ccc8c8ccc4c136b5818190381024066051b9c59c20e67167040980c2cacac2c0c00109a0afa
+  - Name:            .debug_abbrev.dwo
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         01110125823E130503823EB142070000022E0111813E120640186E823E03823E3A0B3B0B3F190000030500021803823E3A0B3B0B4913000004240003823E3E0B0B0B000000
+  - Name:            .debug_line.dwo
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         0D0000000200070000000101FB0E010000

diff  --git a/llvm/test/tools/llvm-dwp/X86/compressfail.test b/llvm/test/tools/llvm-dwp/X86/compressfail.test
index 0d95ec73dd0f..4b4ec8918b22 100644
--- a/llvm/test/tools/llvm-dwp/X86/compressfail.test
+++ b/llvm/test/tools/llvm-dwp/X86/compressfail.test
@@ -1,6 +1,33 @@
-REQUIRES: zlib
-RUN: not llvm-dwp %p/../Inputs/compressfail/a.dwo -o %t 2>&1 | FileCheck %s
-RUN: not llvm-dwp %p/../Inputs/empty_compressed_section.dwo -o %t 2>&1 | FileCheck %s
-RUN: not llvm-dwp %p/../Inputs/invalid_compressed.dwo -o %t 2>&1 | FileCheck %s
+# REQUIRES: zlib
+# RUN: yaml2obj --docnum=1 %s -o %t1.o
+# RUN: not llvm-dwp %t1.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
+# RUN: yaml2obj --docnum=2 %s -o %t2.o
+# RUN: not llvm-dwp %t2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
 
-CHECK: error: failure while decompressing compressed section: '.zdebug_{{.*}}.dwo'
+# ERR1: error: failure while decompressing compressed section: '.debug_info.dwo', corrupted compressed section header
+# ERR2: error: failure while decompressing compressed section: '.debug_info.dwo', zlib error: Z_DATA_ERROR
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:         .debug_info.dwo
+    Type:         SHT_PROGBITS
+    Flags:        [ SHF_COMPRESSED ]
+    AddressAlign: 8
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:         .debug_info.dwo
+    Type:         SHT_PROGBITS
+    Flags:        [ SHF_COMPRESSED ]
+    AddressAlign: 8
+    Content:      "010000000000000004000000000000000100000000000000ffff"


        


More information about the llvm-commits mailing list