[llvm] fbf5e87 - [MC] Support writing ELFCOMPRESS_ZSTD compressed debug info sections

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 8 01:00:16 PDT 2022


Author: Fangrui Song
Date: 2022-09-08T01:00:06-07:00
New Revision: fbf5e87219c5690c9ae1496a5bbda1198ee87b83

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

LOG: [MC] Support writing ELFCOMPRESS_ZSTD compressed debug info sections

and add --compress-debug-sections=zstd to llvm-mc for testing.

Reviewed By: dblaikie

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

Added: 
    llvm/test/MC/ELF/compress-debug-sections-zstd-unavailable.s
    llvm/test/MC/ELF/compress-debug-sections-zstd.s

Modified: 
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/test/MC/ELF/compress-debug-sections-zlib-unavailable.s
    llvm/tools/llvm-mc/llvm-mc.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index f6360c4e2f21b..bb058690ebda3 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -848,27 +848,34 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
   auto &MC = Asm.getContext();
   const auto &MAI = MC.getAsmInfo();
 
-  bool CompressionEnabled =
-      MAI->compressDebugSections() != DebugCompressionType::None;
-  if (!CompressionEnabled || !SectionName.startswith(".debug_")) {
+  const DebugCompressionType CompressionType = MAI->compressDebugSections();
+  if (CompressionType == DebugCompressionType::None ||
+      !SectionName.startswith(".debug_")) {
     Asm.writeSectionData(W.OS, &Section, Layout);
     return;
   }
 
-  assert(MAI->compressDebugSections() == DebugCompressionType::Z &&
-         "expected zlib style compression");
-
   SmallVector<char, 128> UncompressedData;
   raw_svector_ostream VecOS(UncompressedData);
   Asm.writeSectionData(VecOS, &Section, Layout);
-
-  SmallVector<uint8_t, 128> Compressed;
-  const uint32_t ChType = ELF::ELFCOMPRESS_ZLIB;
-  compression::zlib::compress(
+  ArrayRef<uint8_t> Uncompressed =
       makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
-                   UncompressedData.size()),
-      Compressed);
+                   UncompressedData.size());
 
+  SmallVector<uint8_t, 128> Compressed;
+  uint32_t ChType;
+  switch (CompressionType) {
+  case DebugCompressionType::None:
+    llvm_unreachable("has been handled");
+  case DebugCompressionType::Z:
+    ChType = ELF::ELFCOMPRESS_ZLIB;
+    break;
+  case DebugCompressionType::Zstd:
+    ChType = ELF::ELFCOMPRESS_ZSTD;
+    break;
+  }
+  compression::compress(compression::Params(CompressionType), Uncompressed,
+                        Compressed);
   if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
                              Sec.getAlignment())) {
     W.OS << UncompressedData;

diff  --git a/llvm/test/MC/ELF/compress-debug-sections-zlib-unavailable.s b/llvm/test/MC/ELF/compress-debug-sections-zlib-unavailable.s
index 31391582ec2d4..fa5ce9f614c54 100644
--- a/llvm/test/MC/ELF/compress-debug-sections-zlib-unavailable.s
+++ b/llvm/test/MC/ELF/compress-debug-sections-zlib-unavailable.s
@@ -1,4 +1,5 @@
 // REQUIRES: !zlib
 // RUN: not llvm-mc -filetype=obj -compress-debug-sections=zlib -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s
 
-// CHECK: llvm-mc{{[^:]*}}: error: build tools with zlib to enable -compress-debug-sections
+// CHECK:     llvm-mc{{[^:]*}}: error: build tools with LLVM_ENABLE_ZLIB to enable --compress-debug-sections=zlib
+// CHECK-NOT: {{.}}

diff  --git a/llvm/test/MC/ELF/compress-debug-sections-zstd-unavailable.s b/llvm/test/MC/ELF/compress-debug-sections-zstd-unavailable.s
new file mode 100644
index 0000000000000..3db2b27520453
--- /dev/null
+++ b/llvm/test/MC/ELF/compress-debug-sections-zstd-unavailable.s
@@ -0,0 +1,5 @@
+# UNSUPPORTED: zstd
+# RUN: not llvm-mc -filetype=obj -compress-debug-sections=zstd -triple x86_64 %s 2>&1 | FileCheck %s
+
+# CHECK:     error: --compress-debug-sections: LLVM was not built with LLVM_ENABLE_ZSTD or did not find zstd at build time
+# CHECK-NOT: {{.}}

diff  --git a/llvm/test/MC/ELF/compress-debug-sections-zstd.s b/llvm/test/MC/ELF/compress-debug-sections-zstd.s
new file mode 100644
index 0000000000000..01ae21a2b8abb
--- /dev/null
+++ b/llvm/test/MC/ELF/compress-debug-sections-zstd.s
@@ -0,0 +1,115 @@
+# REQUIRES: zstd
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 -compress-debug-sections=zstd %s -o %t
+# RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SEC
+# RUN: llvm-objdump -s %t | FileCheck %s
+
+## Check that the large debug sections .debug_line and .debug_frame are compressed
+## and have the SHF_COMPRESSED flag.
+# SEC: .nonalloc     PROGBITS [[#%x,]] [[#%x,]] [[#%x,]] 00     0 0  1
+# SEC: .debug_line   PROGBITS [[#%x,]] [[#%x,]] [[#%x,]] 00   C 0 0  8
+# SEC: .debug_abbrev PROGBITS [[#%x,]] [[#%x,]] [[#%x,]] 00     0 0  1
+# SEC: .debug_info   PROGBITS [[#%x,]] [[#%x,]] [[#%x,]] 00     0 0  1
+# SEC: .debug_str    PROGBITS [[#%x,]] [[#%x,]] [[#%x,]] 01 MSC 0 0  8
+# SEC: .debug_frame  PROGBITS [[#%x,]] [[#%x,]] [[#%x,]] 00   C 0 0  8
+
+# CHECK:      Contents of section .debug_line
+## ch_type == ELFCOMPRESS_ZSTD (2)
+# CHECK-NEXT: 0000 02000000 00000000 55010000 00000000
+# CHECK-NEXT: 0010 01000000 00000000 {{.*}}
+
+## The compress/decompress round trip should be identical to the uncompressed output.
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.uncom
+# RUN: llvm-objcopy --decompress-debug-sections %t %t.decom
+# RUN: cmp %t.uncom %t.decom
+
+## Don't compress a section not named .debug_*.
+	.section .nonalloc,"", at progbits
+.rept 50
+.asciz "aaaaaaaaaa"
+.endr
+
+	.section	.debug_line,"", at progbits
+
+	.section	.debug_abbrev,"", at progbits
+.Lsection_abbrev:
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	0                       # DW_CHILDREN_no
+	.byte	27                      # DW_AT_comp_dir
+	.byte	14                      # DW_FORM_strp
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+
+	.section	.debug_info,"", at progbits
+	.long	12                      # Length of Unit
+	.short	4                       # DWARF version number
+	.long	.Lsection_abbrev        # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] DW_TAG_compile_unit
+	.long	.Linfo_string0          # DW_AT_comp_dir
+
+	.text
+foo:
+	.cfi_startproc
+	.file 1 "Driver.ii"
+
+.rept 3
+.ifdef I386
+	pushl	%ebp
+	.cfi_def_cfa_offset 8
+	.cfi_offset %ebp, -8
+	movl	%esp, %ebp
+	.cfi_def_cfa_register %ebp
+	pushl	%ebx
+	pushl	%edi
+	pushl	%esi
+	.cfi_offset %esi, -20
+	.cfi_offset %edi, -16
+	.cfi_offset %ebx, -12
+	.loc	1 1 1 prologue_end
+	popl	%esi
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+	.cfi_def_cfa %esp, 4
+.else
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	.cfi_offset %rbx, -56
+	.cfi_offset %r12, -48
+	.cfi_offset %r13, -40
+	.cfi_offset %r14, -32
+	.cfi_offset %r15, -24
+	.loc	1 1 1 prologue_end
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	.cfi_def_cfa %rsp, 8
+.endif
+.endr
+
+# pad out the line table to make sure it's big enough to warrant compression
+	.irpc i, 123456789
+	  .irpc j, 0123456789
+	    .loc 1 \i\j \j
+	    nop
+	   .endr
+	.endr
+	.cfi_endproc
+	.cfi_sections .debug_frame
+
+	.section        .debug_str,"MS", at progbits,1
+.Linfo_string0:
+	.asciz  "perfectly compressable data sample *****************************************"

diff  --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index aa380d3fe9bc1..1ca30d19fecc4 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -76,8 +76,8 @@ static cl::opt<DebugCompressionType> CompressDebugSections(
     cl::init(DebugCompressionType::None),
     cl::desc("Choose DWARF debug sections compression:"),
     cl::values(clEnumValN(DebugCompressionType::None, "none", "No compression"),
-               clEnumValN(DebugCompressionType::Z, "zlib",
-                          "Use zlib compression")),
+               clEnumValN(DebugCompressionType::Z, "zlib", "Use zlib"),
+               clEnumValN(DebugCompressionType::Zstd, "zstd", "Use zstd")),
     cl::cat(MCCategory));
 
 static cl::opt<bool>
@@ -399,15 +399,15 @@ int main(int argc, char **argv) {
   assert(MAI && "Unable to create target asm info!");
 
   MAI->setRelaxELFRelocations(RelaxELFRel);
-
   if (CompressDebugSections != DebugCompressionType::None) {
-    if (!compression::zlib::isAvailable()) {
+    if (const char *Reason = compression::getReasonIfUnsupported(
+            compression::formatFor(CompressDebugSections))) {
       WithColor::error(errs(), ProgName)
-          << "build tools with zlib to enable -compress-debug-sections";
+          << "--compress-debug-sections: " << Reason;
       return 1;
     }
-    MAI->setCompressDebugSections(CompressDebugSections);
   }
+  MAI->setCompressDebugSections(CompressDebugSections);
   MAI->setPreserveAsmComments(PreserveComments);
 
   // Package up features to be passed to target/subtarget


        


More information about the llvm-commits mailing list