about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm/debuginfo
diff options
context:
space:
mode:
authorArlo Siemsen <arsiem@microsoft.com>2020-03-30 22:17:15 -0700
committerArlo Siemsen <arsiem@microsoft.com>2020-04-02 14:13:19 -0700
commitf86b078e2df79968e40185c91b0dce81bc580872 (patch)
tree18e3d3337427fa4105ede99f581124d3c97f3c31 /src/librustc_codegen_llvm/debuginfo
parent537ccdf3ac44c8c7a8d36cbdbe6fb224afabb7ae (diff)
downloadrust-f86b078e2df79968e40185c91b0dce81bc580872.tar.gz
rust-f86b078e2df79968e40185c91b0dce81bc580872.zip
Add hash of source files in debug info
* Adds either an MD5 or SHA1 hash to the debug info.
* Adds new unstable option `-Z src-hash-algorithm` to control the hashing algorithm.
Diffstat (limited to 'src/librustc_codegen_llvm/debuginfo')
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index a9e21c056a3..700f25d35bc 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -41,7 +41,7 @@ use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config::{self, DebugInfo};
 use rustc_span::symbol::{Interner, Symbol};
-use rustc_span::{self, FileName, Span};
+use rustc_span::{self, FileName, SourceFileHash, Span};
 use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf};
 use rustc_target::abi::{Int, Pointer, F32, F64};
 use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
@@ -751,6 +751,14 @@ pub fn type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, usage_site_span: Sp
     metadata
 }
 
+fn hex_encode(data: &[u8]) -> String {
+    let mut hex_string = String::with_capacity(data.len() * 2);
+    for byte in data.iter() {
+        write!(&mut hex_string, "{:02x}", byte).unwrap();
+    }
+    hex_string
+}
+
 pub fn file_metadata(
     cx: &CodegenCx<'ll, '_>,
     file_name: &FileName,
@@ -758,6 +766,8 @@ pub fn file_metadata(
 ) -> &'ll DIFile {
     debug!("file_metadata: file_name: {}, defining_crate: {}", file_name, defining_crate);
 
+    let source_file = cx.sess().source_map().get_source_file(file_name);
+    let hash = source_file.as_ref().map(|f| &f.src_hash);
     let file_name = Some(file_name.to_string());
     let directory = if defining_crate == LOCAL_CRATE {
         Some(cx.sess().working_dir.0.to_string_lossy().to_string())
@@ -766,17 +776,18 @@ pub fn file_metadata(
         // independent of the compiler's working directory one way or another.
         None
     };
-    file_metadata_raw(cx, file_name, directory)
+    file_metadata_raw(cx, file_name, directory, hash)
 }
 
 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
-    file_metadata_raw(cx, None, None)
+    file_metadata_raw(cx, None, None, None)
 }
 
 fn file_metadata_raw(
     cx: &CodegenCx<'ll, '_>,
     file_name: Option<String>,
     directory: Option<String>,
+    hash: Option<&SourceFileHash>,
 ) -> &'ll DIFile {
     let key = (file_name, directory);
 
@@ -789,6 +800,17 @@ fn file_metadata_raw(
             let file_name = file_name.as_deref().unwrap_or("<unknown>");
             let directory = directory.as_deref().unwrap_or("");
 
+            let (hash_kind, hash_value) = match hash {
+                Some(hash) => {
+                    let kind = match hash.kind {
+                        rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
+                        rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
+                    };
+                    (kind, hex_encode(hash.hash_bytes()))
+                }
+                None => (llvm::ChecksumKind::None, String::new()),
+            };
+
             let file_metadata = unsafe {
                 llvm::LLVMRustDIBuilderCreateFile(
                     DIB(cx),
@@ -796,6 +818,9 @@ fn file_metadata_raw(
                     file_name.len(),
                     directory.as_ptr().cast(),
                     directory.len(),
+                    hash_kind,
+                    hash_value.as_ptr().cast(),
+                    hash_value.len(),
                 )
             };
 
@@ -920,6 +945,9 @@ pub fn compile_unit_metadata(
             name_in_debuginfo.len(),
             work_dir.as_ptr().cast(),
             work_dir.len(),
+            llvm::ChecksumKind::None,
+            ptr::null(),
+            0,
         );
 
         let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(