about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa
diff options
context:
space:
mode:
authorridwanabdillahi <91507758+ridwanabdillahi@users.noreply.github.com>2022-04-25 18:02:43 -0700
committerridwanabdillahi <91507758+ridwanabdillahi@users.noreply.github.com>2022-05-03 10:53:54 -0700
commit175a4eab84379cebfc230ea357ae02dc9be39660 (patch)
tree19f4ae4b9b91cb53e6ee05368127daa4fbc88d33 /compiler/rustc_codegen_ssa
parente1df625306f4136949e02612406f0c60df6008f3 (diff)
downloadrust-175a4eab84379cebfc230ea357ae02dc9be39660.tar.gz
rust-175a4eab84379cebfc230ea357ae02dc9be39660.zip
Add support for a new attribute `#[debugger_visualizer]` to support embedding debugger visualizers into a generated PDB.
Cleanup `DebuggerVisualizerFile` type and other minor cleanup of queries.

Merge the queries for debugger visualizers into a single query.

Revert move of `resolve_path` to `rustc_builtin_macros`. Update dependencies in Cargo.toml for `rustc_passes`.

Respond to PR comments. Load visualizer files into opaque bytes `Vec<u8>`. Debugger visualizers for dynamically linked crates should not be embedded in the current crate.

Update the unstable book with the new feature. Add the tracking issue for the debugger_visualizer feature.

Respond to PR comments and minor cleanups.
Diffstat (limited to 'compiler/rustc_codegen_ssa')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs51
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs23
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
4 files changed, 83 insertions, 11 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 6887f0666a4..04ec1e7f3c1 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{ErrorGuaranteed, Handler};
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
-use rustc_hir::def_id::CrateNum;
+use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
 use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
@@ -2099,8 +2099,14 @@ fn add_order_independent_options(
     // Pass optimization flags down to the linker.
     cmd.optimize();
 
+    let debugger_visualizer_paths = if sess.target.is_like_msvc {
+        collect_debugger_visualizers(tmpdir, sess, &codegen_results.crate_info)
+    } else {
+        Vec::new()
+    };
+
     // Pass debuginfo and strip flags down to the linker.
-    cmd.debuginfo(strip_value(sess));
+    cmd.debuginfo(strip_value(sess), &debugger_visualizer_paths);
 
     // We want to prevent the compiler from accidentally leaking in any system libraries,
     // so by default we tell linkers not to link to any default libraries.
@@ -2119,6 +2125,47 @@ fn add_order_independent_options(
     add_rpath_args(cmd, sess, codegen_results, out_filename);
 }
 
+// Write the debugger visualizer files for each crate to the temp directory and gather the file paths.
+fn collect_debugger_visualizers(
+    tmpdir: &Path,
+    sess: &Session,
+    crate_info: &CrateInfo,
+) -> Vec<PathBuf> {
+    let mut visualizer_paths = Vec::new();
+    let debugger_visualizers = &crate_info.debugger_visualizers;
+    let mut index = 0;
+
+    for (&cnum, visualizers) in debugger_visualizers {
+        let crate_name = if cnum == LOCAL_CRATE {
+            crate_info.local_crate_name.as_str()
+        } else {
+            crate_info.crate_name[&cnum].as_str()
+        };
+
+        for visualizer in visualizers {
+            let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", crate_name, index));
+
+            match fs::write(&visualizer_out_file, &visualizer.src) {
+                Ok(()) => {
+                    visualizer_paths.push(visualizer_out_file.clone());
+                    index += 1;
+                }
+                Err(error) => {
+                    sess.warn(
+                        format!(
+                            "Unable to write debugger visualizer file `{}`: {} ",
+                            visualizer_out_file.display(),
+                            error
+                        )
+                        .as_str(),
+                    );
+                }
+            };
+        }
+    }
+    visualizer_paths
+}
+
 /// # Native library linking
 ///
 /// User-supplied library search paths (-L on the command line). These are the same paths used to
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 50db2c22ae6..2a71377d2f1 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -183,7 +183,7 @@ pub trait Linker {
     fn optimize(&mut self);
     fn pgo_gen(&mut self);
     fn control_flow_guard(&mut self);
-    fn debuginfo(&mut self, strip: Strip);
+    fn debuginfo(&mut self, strip: Strip, debugger_visualizers: &[PathBuf]);
     fn no_crt_objects(&mut self);
     fn no_default_libraries(&mut self);
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
@@ -611,7 +611,7 @@ impl<'a> Linker for GccLinker<'a> {
 
     fn control_flow_guard(&mut self) {}
 
-    fn debuginfo(&mut self, strip: Strip) {
+    fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
         // MacOS linker doesn't support stripping symbols directly anymore.
         if self.sess.target.is_like_osx {
             return;
@@ -915,7 +915,7 @@ impl<'a> Linker for MsvcLinker<'a> {
         self.cmd.arg("/guard:cf");
     }
 
-    fn debuginfo(&mut self, strip: Strip) {
+    fn debuginfo(&mut self, strip: Strip, debugger_visualizers: &[PathBuf]) {
         match strip {
             Strip::None => {
                 // This will cause the Microsoft linker to generate a PDB file
@@ -942,6 +942,13 @@ impl<'a> Linker for MsvcLinker<'a> {
                         }
                     }
                 }
+
+                // This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file
+                for path in debugger_visualizers {
+                    let mut arg = OsString::from("/NATVIS:");
+                    arg.push(path);
+                    self.cmd.arg(arg);
+                }
             }
             Strip::Debuginfo | Strip::Symbols => {
                 self.cmd.arg("/DEBUG:NONE");
@@ -1124,7 +1131,7 @@ impl<'a> Linker for EmLinker<'a> {
 
     fn control_flow_guard(&mut self) {}
 
-    fn debuginfo(&mut self, _strip: Strip) {
+    fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
         // Preserve names or generate source maps depending on debug info
         self.cmd.arg(match self.sess.opts.debuginfo {
             DebugInfo::None => "-g0",
@@ -1315,7 +1322,7 @@ impl<'a> Linker for WasmLd<'a> {
 
     fn pgo_gen(&mut self) {}
 
-    fn debuginfo(&mut self, strip: Strip) {
+    fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
         match strip {
             Strip::None => {}
             Strip::Debuginfo => {
@@ -1450,7 +1457,7 @@ impl<'a> Linker for L4Bender<'a> {
 
     fn pgo_gen(&mut self) {}
 
-    fn debuginfo(&mut self, strip: Strip) {
+    fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
         match strip {
             Strip::None => {}
             Strip::Debuginfo => {
@@ -1600,7 +1607,7 @@ impl<'a> Linker for PtxLinker<'a> {
         self.cmd.arg("-L").arg(path);
     }
 
-    fn debuginfo(&mut self, _strip: Strip) {
+    fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
         self.cmd.arg("--debug");
     }
 
@@ -1699,7 +1706,7 @@ impl<'a> Linker for BpfLinker<'a> {
         self.cmd.arg("-L").arg(path);
     }
 
-    fn debuginfo(&mut self, _strip: Strip) {
+    fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
         self.cmd.arg("--debug");
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 5bc95614c19..7b7e09208a2 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -847,7 +847,13 @@ impl CrateInfo {
             missing_lang_items: Default::default(),
             dependency_formats: tcx.dependency_formats(()).clone(),
             windows_subsystem,
+            debugger_visualizers: Default::default(),
         };
+        let debugger_visualizers = tcx.debugger_visualizers(LOCAL_CRATE).clone();
+        if !debugger_visualizers.is_empty() {
+            info.debugger_visualizers.insert(LOCAL_CRATE, debugger_visualizers);
+        }
+
         let lang_items = tcx.lang_items();
 
         let crates = tcx.crates(());
@@ -862,7 +868,9 @@ impl CrateInfo {
             info.native_libraries
                 .insert(cnum, tcx.native_libraries(cnum).iter().map(Into::into).collect());
             info.crate_name.insert(cnum, tcx.crate_name(cnum));
-            info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum).clone());
+
+            let used_crate_source = tcx.used_crate_source(cnum);
+            info.used_crate_source.insert(cnum, used_crate_source.clone());
             if tcx.is_compiler_builtins(cnum) {
                 info.compiler_builtins = Some(cnum);
             }
@@ -883,6 +891,14 @@ impl CrateInfo {
             let missing =
                 missing.iter().cloned().filter(|&l| lang_items::required(tcx, l)).collect();
             info.missing_lang_items.insert(cnum, missing);
+
+            // Only include debugger visualizer files from crates that will be statically linked.
+            if used_crate_source.rlib.is_some() || used_crate_source.rmeta.is_some() {
+                let debugger_visualizers = tcx.debugger_visualizers(cnum).clone();
+                if !debugger_visualizers.is_empty() {
+                    info.debugger_visualizers.insert(cnum, debugger_visualizers);
+                }
+            }
         }
 
         info
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 05d32972dab..d6979bb625c 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -36,6 +36,7 @@ use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT
 use rustc_session::cstore::{self, CrateSource};
 use rustc_session::utils::NativeLibKind;
 use rustc_span::symbol::Symbol;
+use rustc_span::DebuggerVisualizerFile;
 use std::path::{Path, PathBuf};
 
 pub mod back;
@@ -157,6 +158,7 @@ pub struct CrateInfo {
     pub missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>,
     pub dependency_formats: Lrc<Dependencies>,
     pub windows_subsystem: Option<String>,
+    pub debugger_visualizers: FxHashMap<CrateNum, Vec<DebuggerVisualizerFile>>,
 }
 
 #[derive(Encodable, Decodable)]