diff options
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/debuginfo')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 36 |
2 files changed, 38 insertions, 28 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 6eb7042da61..b3e978be570 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -1,5 +1,7 @@ // .debug_gdb_scripts binary section. +use std::ffi::CString; + use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::LOCAL_CRATE; @@ -31,7 +33,12 @@ pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Buil pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( cx: &CodegenCx<'ll, '_>, ) -> &'ll Value { - let c_section_var_name = c"__rustc_debug_gdb_scripts_section__"; + let c_section_var_name = CString::new(format!( + "__rustc_debug_gdb_scripts_section_{}_{:08x}", + cx.tcx.crate_name(LOCAL_CRATE), + cx.tcx.stable_crate_id(LOCAL_CRATE), + )) + .unwrap(); let section_var_name = c_section_var_name.to_str().unwrap(); let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr()) }; @@ -84,17 +91,10 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( } pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { - // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create - // ODR violations at link time, this section will not be emitted for rlibs since - // each rlib could produce a different set of visualizers that would be embedded - // in the `.debug_gdb_scripts` section. For that reason, we make sure that the - // section is only emitted for leaf crates. + // We collect pretty printers transitively for all crates, so we make sure + // that the section is only emitted for leaf crates. let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type { - CrateType::Executable - | CrateType::Dylib - | CrateType::Cdylib - | CrateType::Staticlib - | CrateType::Sdylib => { + CrateType::Executable | CrateType::Cdylib | CrateType::Staticlib | CrateType::Sdylib => { // These are crate types for which we will embed pretty printers since they // are treated as leaf crates. true @@ -105,9 +105,11 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { // want to slow down the common case. false } - CrateType::Rlib => { - // As per the above description, embedding pretty printers for rlibs could - // lead to ODR violations so we skip this crate type as well. + CrateType::Rlib | CrateType::Dylib => { + // Don't embed pretty printers for these crate types; the compiler + // can see the `#[debug_visualizer]` attributes when using the + // library, and emitting `.debug_gdb_scripts` regardless would + // break `#![omit_gdb_pretty_printer_section]`. false } }); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 6cbf2dbf7d3..c911435967c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -30,7 +30,7 @@ use tracing::debug; use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node}; use self::namespace::mangled_name_of_instance; -use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; +use self::utils::{DIB, create_DIArray, debug_context, is_node_local_to_unit}; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; use crate::llvm; @@ -131,20 +131,28 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { } /// Creates any deferred debug metadata nodes -pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { - if let Some(dbg_cx) = &cx.dbg_cx { - debug!("finalize"); - - if gdb::needs_gdb_debug_scripts_section(cx) { - // Add a .debug_gdb_scripts section to this compile-unit. This will - // cause GDB to try and load the gdb_load_rust_pretty_printers.py file, - // which activates the Rust pretty printers for binary this section is - // contained in. - gdb::get_or_insert_gdb_debug_scripts_section_global(cx); - } +pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) { + if cx.dbg_cx.is_none() { + return; + } + + debug!("finalize"); - dbg_cx.finalize(cx.sess()); + if gdb::needs_gdb_debug_scripts_section(cx) { + // Add a .debug_gdb_scripts section to this compile-unit. This will + // cause GDB to try and load the gdb_load_rust_pretty_printers.py file, + // which activates the Rust pretty printers for binary this section is + // contained in. + let section_var = gdb::get_or_insert_gdb_debug_scripts_section_global(cx); + + // Make sure that the linker doesn't optimize the global away. Adding + // it to `llvm.used` has the advantage that it works even in no_std + // binaries, where we don't have a main shim and thus don't emit a + // volatile load to preserve the global. + cx.add_used_global(section_var); } + + debug_context(cx).finalize(cx.sess()); } impl<'ll> Builder<'_, 'll, '_> { @@ -614,7 +622,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { metadata::extend_scope_to_file(self, scope_metadata, file) } - fn debuginfo_finalize(&self) { + fn debuginfo_finalize(&mut self) { finalize(self) } |
