From 73b734bf637ab1c14ec73823b3c536108cef5437 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 23 Oct 2025 18:20:41 +1100 Subject: [PATCH] Pass `debuginfo_compression` through FFI as an enum --- .../src/back/owned_target_machine.rs | 4 +- compiler/rustc_codegen_llvm/src/back/write.rs | 25 +++++------ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 16 +++++-- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 42 ++++++++++++++----- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 4 +- compiler/rustc_session/src/config.rs | 11 ----- 6 files changed, 60 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index 2972f3d5201ed..f88932d43d2af 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -36,7 +36,7 @@ impl OwnedTargetMachine { use_init_array: bool, split_dwarf_file: &CStr, output_obj_file: &CStr, - debug_info_compression: &CStr, + debug_info_compression: llvm::CompressionKind, use_emulated_tls: bool, use_wasm_eh: bool, ) -> Result> { @@ -62,7 +62,7 @@ impl OwnedTargetMachine { use_init_array, split_dwarf_file.as_ptr(), output_obj_file.as_ptr(), - debug_info_compression.as_ptr(), + debug_info_compression, use_emulated_tls, use_wasm_eh, ) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index d18030b1574c5..cfbb9541ecd2d 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -6,9 +6,6 @@ use std::sync::Arc; use std::{fs, slice, str}; use libc::{c_char, c_int, c_void, size_t}; -use llvm::{ - LLVMRustLLVMHasZlibCompressionForDebugSymbols, LLVMRustLLVMHasZstdCompressionForDebugSymbols, -}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ @@ -252,21 +249,25 @@ pub(crate) fn target_machine_factory( let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); - let debuginfo_compression = sess.opts.debuginfo_compression.to_string(); - match sess.opts.debuginfo_compression { - rustc_session::config::DebugInfoCompression::Zlib => { - if !unsafe { LLVMRustLLVMHasZlibCompressionForDebugSymbols() } { + let debuginfo_compression = match sess.opts.debuginfo_compression { + config::DebugInfoCompression::None => llvm::CompressionKind::None, + config::DebugInfoCompression::Zlib => { + if llvm::LLVMRustLLVMHasZlibCompression() { + llvm::CompressionKind::Zlib + } else { sess.dcx().emit_warn(UnknownCompression { algorithm: "zlib" }); + llvm::CompressionKind::None } } - rustc_session::config::DebugInfoCompression::Zstd => { - if !unsafe { LLVMRustLLVMHasZstdCompressionForDebugSymbols() } { + config::DebugInfoCompression::Zstd => { + if llvm::LLVMRustLLVMHasZstdCompression() { + llvm::CompressionKind::Zstd + } else { sess.dcx().emit_warn(UnknownCompression { algorithm: "zstd" }); + llvm::CompressionKind::None } } - rustc_session::config::DebugInfoCompression::None => {} }; - let debuginfo_compression = SmallCStr::new(&debuginfo_compression); let file_name_display_preference = sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); @@ -310,7 +311,7 @@ pub(crate) fn target_machine_factory( use_init_array, &split_dwarf_file, &output_obj_file, - &debuginfo_compression, + debuginfo_compression, use_emulated_tls, use_wasm_eh, ) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2456ed2e46d67..5a00199d61171 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -677,6 +677,15 @@ pub(crate) enum Opcode { CatchSwitch = 65, } +/// Must match the layout of `LLVMRustCompressionKind`. +#[derive(Copy, Clone)] +#[repr(C)] +pub(crate) enum CompressionKind { + None = 0, + Zlib = 1, + Zstd = 2, +} + unsafe extern "C" { type Opaque; } @@ -2328,7 +2337,7 @@ unsafe extern "C" { UseInitArray: bool, SplitDwarfFile: *const c_char, OutputObjFile: *const c_char, - DebugInfoCompression: *const c_char, + DebugInfoCompression: CompressionKind, UseEmulatedTls: bool, UseWasmEH: bool, ) -> *mut TargetMachine; @@ -2516,9 +2525,8 @@ unsafe extern "C" { pub(crate) fn LLVMRustGetElementTypeArgIndex(CallSite: &Value) -> i32; - pub(crate) fn LLVMRustLLVMHasZlibCompressionForDebugSymbols() -> bool; - - pub(crate) fn LLVMRustLLVMHasZstdCompressionForDebugSymbols() -> bool; + pub(crate) safe fn LLVMRustLLVMHasZlibCompression() -> bool; + pub(crate) safe fn LLVMRustLLVMHasZstdCompression() -> bool; pub(crate) fn LLVMRustGetSymbols( buf_ptr: *const u8, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 616c8a17dd66d..178b43c93ef6b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -224,6 +224,31 @@ static FloatABI::ABIType fromRust(LLVMRustFloatABI RustFloatAbi) { report_fatal_error("Bad FloatABI."); } +// Must match the layout of `rustc_codegen_llvm::llvm::ffi::CompressionKind`. +enum class LLVMRustCompressionKind { + None = 0, + Zlib = 1, + Zstd = 2, +}; + +static llvm::DebugCompressionType fromRust(LLVMRustCompressionKind Kind) { + switch (Kind) { + case LLVMRustCompressionKind::None: + return llvm::DebugCompressionType::None; + case LLVMRustCompressionKind::Zlib: + if (!llvm::compression::zlib::isAvailable()) { + report_fatal_error("LLVMRustCompressionKind::Zlib not available"); + } + return llvm::DebugCompressionType::Zlib; + case LLVMRustCompressionKind::Zstd: + if (!llvm::compression::zstd::isAvailable()) { + report_fatal_error("LLVMRustCompressionKind::Zstd not available"); + } + return llvm::DebugCompressionType::Zstd; + } + report_fatal_error("bad LLVMRustCompressionKind"); +} + extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, RustStringRef OutStr) { ArrayRef CPUTable = @@ -271,7 +296,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool TrapUnreachable, bool Singlethread, bool VerboseAsm, bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, const char *SplitDwarfFile, const char *OutputObjFile, - const char *DebugInfoCompression, bool UseEmulatedTls, bool UseWasmEH) { + LLVMRustCompressionKind DebugInfoCompression, bool UseEmulatedTls, + bool UseWasmEH) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -307,16 +333,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( if (OutputObjFile) { Options.ObjectFilenameForDebug = OutputObjFile; } - if (!strcmp("zlib", DebugInfoCompression) && - llvm::compression::zlib::isAvailable()) { - Options.MCOptions.CompressDebugSections = DebugCompressionType::Zlib; - } else if (!strcmp("zstd", DebugInfoCompression) && - llvm::compression::zstd::isAvailable()) { - Options.MCOptions.CompressDebugSections = DebugCompressionType::Zstd; - } else if (!strcmp("none", DebugInfoCompression)) { - Options.MCOptions.CompressDebugSections = DebugCompressionType::None; - } - + // To avoid fatal errors, make sure the Rust-side code only passes a + // compression kind that is known to be supported by this build of LLVM, via + // `LLVMRustLLVMHasZlibCompression` and `LLVMRustLLVMHasZstdCompression`. + Options.MCOptions.CompressDebugSections = fromRust(DebugInfoCompression); Options.MCOptions.X86RelaxRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; Options.EmulatedTLS = UseEmulatedTls; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6b4f8a6dba79f..55a90baf8cc09 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1640,11 +1640,11 @@ extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) { return false; } -extern "C" bool LLVMRustLLVMHasZlibCompressionForDebugSymbols() { +extern "C" bool LLVMRustLLVMHasZlibCompression() { return llvm::compression::zlib::isAvailable(); } -extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() { +extern "C" bool LLVMRustLLVMHasZstdCompression() { return llvm::compression::zstd::isAvailable(); } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8ff6d567422b9..54317ee6fbb87 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -583,17 +583,6 @@ pub enum DebugInfoCompression { Zstd, } -impl ToString for DebugInfoCompression { - fn to_string(&self) -> String { - match self { - DebugInfoCompression::None => "none", - DebugInfoCompression::Zlib => "zlib", - DebugInfoCompression::Zstd => "zstd", - } - .to_owned() - } -} - #[derive(Clone, Copy, Debug, PartialEq, Hash)] pub enum MirStripDebugInfo { None,