Skip to content

Add hash of source files in debug info #69718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 4, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 44 additions & 20 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -87,12 +87,6 @@ dependencies = [
"scoped_threadpool",
]

[[package]]
name = "arrayref"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"

[[package]]
name = "arrayvec"
version = "0.4.7"
@@ -187,11 +181,22 @@ dependencies = [

[[package]]
name = "block-buffer"
version = "0.3.3"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array",
]

[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
dependencies = [
"arrayref",
"byte-tools",
]

@@ -240,9 +245,9 @@ version = "0.1.0"

[[package]]
name = "byte-tools"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"

[[package]]
name = "bytecount"
@@ -897,9 +902,9 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"

[[package]]
name = "digest"
version = "0.7.6"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array",
]
@@ -1226,9 +1231,9 @@ dependencies = [

[[package]]
name = "generic-array"
version = "0.9.0"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [
"typenum",
]
@@ -1962,6 +1967,17 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"

[[package]]
name = "md-5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
dependencies = [
"block-buffer",
"digest",
"opaque-debug",
]

[[package]]
name = "mdbook"
version = "0.3.5"
@@ -2250,6 +2266,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6a04cb71e910d0034815600180f62a95bf6e67942d7ab52a166a68c7d7e9cd0"

[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"

[[package]]
name = "open"
version = "1.2.1"
@@ -2467,9 +2489,9 @@ dependencies = [

[[package]]
name = "pest_meta"
version = "2.1.0"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
@@ -4155,11 +4177,13 @@ dependencies = [
"arena",
"cfg-if",
"log",
"md-5",
"rustc_data_structures",
"rustc_index",
"rustc_macros",
"scoped-tls",
"serialize",
"sha-1",
"unicode-width",
]

@@ -4535,14 +4559,14 @@ dependencies = [

[[package]]
name = "sha-1"
version = "0.7.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
"block-buffer",
"byte-tools",
"digest",
"fake-simd",
"opaque-debug",
]

[[package]]
11 changes: 11 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/src-hash-algorithm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# `src-hash-algorithm`

The tracking issue for this feature is: [#70401](https://github.com/rust-lang/rust/issues/70401).

------------------------

The `-Z src-hash-algorithm` compiler flag controls which algorithm is used when hashing each source file. The hash is stored in the debug info and can be used by a debugger to verify the source code matches the executable.

Supported hash algorithms are: `md5`, and `sha1`. Note that not all hash algorithms are supported by all debug info formats.

By default, the compiler chooses the hash algorithm based on the target specification.
34 changes: 31 additions & 3 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
@@ -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,13 +751,23 @@ 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,
defining_crate: CrateNum,
) -> &'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,13 +800,27 @@ 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),
file_name.as_ptr().cast(),
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(
12 changes: 12 additions & 0 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -546,6 +546,15 @@ pub enum ThreadLocalMode {
LocalExec,
}

/// LLVMRustChecksumKind
#[derive(Copy, Clone)]
#[repr(C)]
pub enum ChecksumKind {
None,
MD5,
SHA1,
}

extern "C" {
type Opaque;
}
@@ -1640,6 +1649,9 @@ extern "C" {
FilenameLen: size_t,
Directory: *const c_char,
DirectoryLen: size_t,
CSKind: ChecksumKind,
Checksum: *const c_char,
ChecksumLen: size_t,
) -> &'a DIFile;

pub fn LLVMRustDIBuilderCreateSubroutineType(
8 changes: 3 additions & 5 deletions src/librustc_interface/util.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ use rustc_session::parse::CrateConfig;
use rustc_session::CrateDisambiguator;
use rustc_session::{config, early_error, filesearch, output, DiagnosticOutput, Session};
use rustc_span::edition::Edition;
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
use rustc_span::source_map::{FileLoader, SourceMap};
use rustc_span::symbol::{sym, Symbol};
use smallvec::SmallVec;
use std::env;
@@ -62,15 +62,13 @@ pub fn create_session(
lint_caps: FxHashMap<lint::LintId, lint::Level>,
descriptions: Registry,
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
let loader = file_loader.unwrap_or(box RealFileLoader);
let source_map = Lrc::new(SourceMap::with_file_loader(loader, sopts.file_path_mapping()));
let mut sess = session::build_session_with_source_map(
let (mut sess, source_map) = session::build_session_with_source_map(
sopts,
input_path,
descriptions,
source_map.clone(),
diagnostic_output,
lint_caps,
file_loader,
);

let codegen_backend = get_codegen_backend(&sess);
2 changes: 1 addition & 1 deletion src/librustc_middle/ich/impls_syntax.rs
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
cnum,
// Do not hash the source as it is not encoded
src: _,
src_hash,
ref src_hash,
external_src: _,
start_pos,
end_pos: _,
30 changes: 19 additions & 11 deletions src/librustc_session/config.rs
Original file line number Diff line number Diff line change
@@ -18,9 +18,10 @@ use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST};
use rustc_span::source_map::{FileName, FilePathMapping};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::SourceFileHashAlgorithm;

use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags};
use rustc_errors::{ColorConfig, HandlerFlags};

use std::collections::btree_map::{
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
@@ -748,25 +749,30 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
user_cfg
}

pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
sp.struct_fatal(&format!("Error loading target specification: {}", e))
.help("Use `--print target-list` for a list of built-in targets")
.emit();
FatalError.raise();
early_error(
error_format,
&format!(
"Error loading target specification: {}. \
Use `--print target-list` for a list of built-in targets",
e
),
)
});

let ptr_width = match &target.target_pointer_width[..] {
"16" => 16,
"32" => 32,
"64" => 64,
w => sp
.fatal(&format!(
w => early_error(
error_format,
&format!(
"target specification was invalid: \
unrecognized target-pointer-width {}",
w
))
.raise(),
),
),
};

Config { target, ptr_width }
@@ -1971,7 +1977,8 @@ impl PpMode {
crate mod dep_tracking {
use super::{
CFGuard, CrateType, DebugInfo, ErrorOutputType, LinkerPluginLto, LtoCli, OptLevel,
OutputTypes, Passes, Sanitizer, SwitchWithOptPath, SymbolManglingVersion,
OutputTypes, Passes, Sanitizer, SourceFileHashAlgorithm, SwitchWithOptPath,
SymbolManglingVersion,
};
use crate::lint;
use crate::utils::NativeLibraryKind;
@@ -2049,6 +2056,7 @@ crate mod dep_tracking {
impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);

impl_dep_tracking_hash_for_sortable_vec_of!(String);
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
Loading