[llvm] 9397648 - [MC] Support writing ELFCOMPRESS_ZSTD compressed debug info sections
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 8 00:03:48 PDT 2022
Author: Fangrui Song
Date: 2022-09-08T00:03:40-07:00
New Revision: 9397648ac8ad192f7e6e6a8e6894c27bf7e024e9
URL: https://github.com/llvm/llvm-project/commit/9397648ac8ad192f7e6e6a8e6894c27bf7e024e9
DIFF: https://github.com/llvm/llvm-project/commit/9397648ac8ad192f7e6e6a8e6894c27bf7e024e9.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