about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs57
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs36
3 files changed, 47 insertions, 58 deletions
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 5dda836988c..d7da03bf490 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -109,11 +109,16 @@ pub(crate) fn compile_codegen_unit(
             }
 
             // Finalize code coverage by injecting the coverage map. Note, the coverage map will
-            // also be added to the `llvm.compiler.used` variable, created next.
+            // also be added to the `llvm.compiler.used` variable, created below.
             if cx.sess().instrument_coverage() {
                 cx.coverageinfo_finalize();
             }
 
+            // Finalize debuginfo. This adds to `llvm.used`, created below.
+            if cx.sess().opts.debuginfo != DebugInfo::None {
+                cx.debuginfo_finalize();
+            }
+
             // Create the llvm.used and llvm.compiler.used variables.
             if !cx.used_statics.is_empty() {
                 cx.create_used_variable_impl(c"llvm.used", &cx.used_statics);
@@ -130,11 +135,6 @@ pub(crate) fn compile_codegen_unit(
                     llvm::LLVMDeleteGlobal(old_g);
                 }
             }
-
-            // Finalize debuginfo
-            if cx.sess().opts.debuginfo != DebugInfo::None {
-                cx.debuginfo_finalize();
-            }
         }
 
         ModuleCodegen::new_regular(cgu_name.to_string(), llvm_module)
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index 6eb7042da61..fccd32dec95 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
@@ -1,11 +1,13 @@
 // .debug_gdb_scripts binary section.
 
-use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
+use std::collections::BTreeSet;
+use std::ffi::CString;
+
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::bug;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType;
-use rustc_session::config::{CrateType, DebugInfo};
+use rustc_session::config::DebugInfo;
 
 use crate::builder::Builder;
 use crate::common::CodegenCx;
@@ -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()) };
@@ -44,10 +51,14 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
 
         // Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
         // attribute.
-        let visualizers = collect_debugger_visualizers_transitive(
-            cx.tcx,
-            DebuggerVisualizerType::GdbPrettyPrinter,
-        );
+        let visualizers = cx
+            .tcx
+            .debugger_visualizers(LOCAL_CRATE)
+            .iter()
+            .filter(|visualizer| {
+                visualizer.visualizer_type == DebuggerVisualizerType::GdbPrettyPrinter
+            })
+            .collect::<BTreeSet<_>>();
         let crate_name = cx.tcx.crate_name(LOCAL_CRATE);
         for (index, visualizer) in visualizers.iter().enumerate() {
             // The initial byte `4` instructs GDB that the following pretty printer
@@ -84,35 +95,5 @@ 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.
-    let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type {
-        CrateType::Executable
-        | CrateType::Dylib
-        | 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
-        }
-        CrateType::ProcMacro => {
-            // We could embed pretty printers for proc macro crates too but it does not
-            // seem like a good default, since this is a rare use case and we don't
-            // 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.
-            false
-        }
-    });
-
-    cx.sess().opts.debuginfo != DebugInfo::None
-        && cx.sess().target.emit_debug_gdb_scripts
-        && embed_visualizers
+    cx.sess().opts.debuginfo != DebugInfo::None && cx.sess().target.emit_debug_gdb_scripts
 }
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)
     }