Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6050e52

Browse files
committedApr 4, 2020
Auto merge of rust-lang#69718 - arlosi:debughash, r=eddyb
Add hash of source files in debug info LLVM supports placing the hash of source files inside the debug info. This information can be used by a debugger to verify that the source code matches the executable. This change adds support for both hash algorithms supported by LLVM, MD5 and SHA1, controlled by a target option. * DWARF only supports MD5 * LLVM IR supports MD5 and SHA1 (and SHA256 in LLVM 11). * CodeView (.PDB) supports MD5, SHA1, and SHA256. Fixes rust-lang#68980. Tracking issue: rust-lang#70401 rustc dev guide PR with further details: rust-lang/rustc-dev-guide#623
2 parents 9e55101 + f86b078 commit 6050e52

File tree

19 files changed

+332
-92
lines changed

19 files changed

+332
-92
lines changed
 

‎Cargo.lock

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,6 @@ dependencies = [
8787
"scoped_threadpool",
8888
]
8989

90-
[[package]]
91-
name = "arrayref"
92-
version = "0.3.5"
93-
source = "registry+https://github.com/rust-lang/crates.io-index"
94-
checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
95-
9690
[[package]]
9791
name = "arrayvec"
9892
version = "0.4.7"
@@ -187,11 +181,22 @@ dependencies = [
187181

188182
[[package]]
189183
name = "block-buffer"
190-
version = "0.3.3"
184+
version = "0.7.3"
185+
source = "registry+https://github.com/rust-lang/crates.io-index"
186+
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
187+
dependencies = [
188+
"block-padding",
189+
"byte-tools",
190+
"byteorder",
191+
"generic-array",
192+
]
193+
194+
[[package]]
195+
name = "block-padding"
196+
version = "0.1.5"
191197
source = "registry+https://github.com/rust-lang/crates.io-index"
192-
checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
198+
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
193199
dependencies = [
194-
"arrayref",
195200
"byte-tools",
196201
]
197202

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

241246
[[package]]
242247
name = "byte-tools"
243-
version = "0.2.0"
248+
version = "0.3.1"
244249
source = "registry+https://github.com/rust-lang/crates.io-index"
245-
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
250+
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
246251

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

898903
[[package]]
899904
name = "digest"
900-
version = "0.7.6"
905+
version = "0.8.1"
901906
source = "registry+https://github.com/rust-lang/crates.io-index"
902-
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
907+
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
903908
dependencies = [
904909
"generic-array",
905910
]
@@ -1226,9 +1231,9 @@ dependencies = [
12261231

12271232
[[package]]
12281233
name = "generic-array"
1229-
version = "0.9.0"
1234+
version = "0.12.3"
12301235
source = "registry+https://github.com/rust-lang/crates.io-index"
1231-
checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
1236+
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
12321237
dependencies = [
12331238
"typenum",
12341239
]
@@ -1962,6 +1967,17 @@ version = "0.1.8"
19621967
source = "registry+https://github.com/rust-lang/crates.io-index"
19631968
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
19641969

1970+
[[package]]
1971+
name = "md-5"
1972+
version = "0.8.0"
1973+
source = "registry+https://github.com/rust-lang/crates.io-index"
1974+
checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
1975+
dependencies = [
1976+
"block-buffer",
1977+
"digest",
1978+
"opaque-debug",
1979+
]
1980+
19651981
[[package]]
19661982
name = "mdbook"
19671983
version = "0.3.5"
@@ -2250,6 +2266,12 @@ version = "1.1.0"
22502266
source = "registry+https://github.com/rust-lang/crates.io-index"
22512267
checksum = "d6a04cb71e910d0034815600180f62a95bf6e67942d7ab52a166a68c7d7e9cd0"
22522268

2269+
[[package]]
2270+
name = "opaque-debug"
2271+
version = "0.2.3"
2272+
source = "registry+https://github.com/rust-lang/crates.io-index"
2273+
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
2274+
22532275
[[package]]
22542276
name = "open"
22552277
version = "1.2.1"
@@ -2467,9 +2489,9 @@ dependencies = [
24672489

24682490
[[package]]
24692491
name = "pest_meta"
2470-
version = "2.1.0"
2492+
version = "2.1.3"
24712493
source = "registry+https://github.com/rust-lang/crates.io-index"
2472-
checksum = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e"
2494+
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
24732495
dependencies = [
24742496
"maplit",
24752497
"pest",
@@ -4155,11 +4177,13 @@ dependencies = [
41554177
"arena",
41564178
"cfg-if",
41574179
"log",
4180+
"md-5",
41584181
"rustc_data_structures",
41594182
"rustc_index",
41604183
"rustc_macros",
41614184
"scoped-tls",
41624185
"serialize",
4186+
"sha-1",
41634187
"unicode-width",
41644188
]
41654189

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

45364560
[[package]]
45374561
name = "sha-1"
4538-
version = "0.7.0"
4562+
version = "0.8.2"
45394563
source = "registry+https://github.com/rust-lang/crates.io-index"
4540-
checksum = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
4564+
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
45414565
dependencies = [
45424566
"block-buffer",
4543-
"byte-tools",
45444567
"digest",
45454568
"fake-simd",
4569+
"opaque-debug",
45464570
]
45474571

45484572
[[package]]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# `src-hash-algorithm`
2+
3+
The tracking issue for this feature is: [#70401](https://github.com/rust-lang/rust/issues/70401).
4+
5+
------------------------
6+
7+
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.
8+
9+
Supported hash algorithms are: `md5`, and `sha1`. Note that not all hash algorithms are supported by all debug info formats.
10+
11+
By default, the compiler chooses the hash algorithm based on the target specification.

‎src/librustc_codegen_llvm/debuginfo/metadata.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
4141
use rustc_middle::{bug, span_bug};
4242
use rustc_session::config::{self, DebugInfo};
4343
use rustc_span::symbol::{Interner, Symbol};
44-
use rustc_span::{self, FileName, Span};
44+
use rustc_span::{self, FileName, SourceFileHash, Span};
4545
use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf};
4646
use rustc_target::abi::{Int, Pointer, F32, F64};
4747
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
751751
metadata
752752
}
753753

754+
fn hex_encode(data: &[u8]) -> String {
755+
let mut hex_string = String::with_capacity(data.len() * 2);
756+
for byte in data.iter() {
757+
write!(&mut hex_string, "{:02x}", byte).unwrap();
758+
}
759+
hex_string
760+
}
761+
754762
pub fn file_metadata(
755763
cx: &CodegenCx<'ll, '_>,
756764
file_name: &FileName,
757765
defining_crate: CrateNum,
758766
) -> &'ll DIFile {
759767
debug!("file_metadata: file_name: {}, defining_crate: {}", file_name, defining_crate);
760768

769+
let source_file = cx.sess().source_map().get_source_file(file_name);
770+
let hash = source_file.as_ref().map(|f| &f.src_hash);
761771
let file_name = Some(file_name.to_string());
762772
let directory = if defining_crate == LOCAL_CRATE {
763773
Some(cx.sess().working_dir.0.to_string_lossy().to_string())
@@ -766,17 +776,18 @@ pub fn file_metadata(
766776
// independent of the compiler's working directory one way or another.
767777
None
768778
};
769-
file_metadata_raw(cx, file_name, directory)
779+
file_metadata_raw(cx, file_name, directory, hash)
770780
}
771781

772782
pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
773-
file_metadata_raw(cx, None, None)
783+
file_metadata_raw(cx, None, None, None)
774784
}
775785

776786
fn file_metadata_raw(
777787
cx: &CodegenCx<'ll, '_>,
778788
file_name: Option<String>,
779789
directory: Option<String>,
790+
hash: Option<&SourceFileHash>,
780791
) -> &'ll DIFile {
781792
let key = (file_name, directory);
782793

@@ -789,13 +800,27 @@ fn file_metadata_raw(
789800
let file_name = file_name.as_deref().unwrap_or("<unknown>");
790801
let directory = directory.as_deref().unwrap_or("");
791802

803+
let (hash_kind, hash_value) = match hash {
804+
Some(hash) => {
805+
let kind = match hash.kind {
806+
rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
807+
rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
808+
};
809+
(kind, hex_encode(hash.hash_bytes()))
810+
}
811+
None => (llvm::ChecksumKind::None, String::new()),
812+
};
813+
792814
let file_metadata = unsafe {
793815
llvm::LLVMRustDIBuilderCreateFile(
794816
DIB(cx),
795817
file_name.as_ptr().cast(),
796818
file_name.len(),
797819
directory.as_ptr().cast(),
798820
directory.len(),
821+
hash_kind,
822+
hash_value.as_ptr().cast(),
823+
hash_value.len(),
799824
)
800825
};
801826

@@ -920,6 +945,9 @@ pub fn compile_unit_metadata(
920945
name_in_debuginfo.len(),
921946
work_dir.as_ptr().cast(),
922947
work_dir.len(),
948+
llvm::ChecksumKind::None,
949+
ptr::null(),
950+
0,
923951
);
924952

925953
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(

‎src/librustc_codegen_llvm/llvm/ffi.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,15 @@ pub enum ThreadLocalMode {
546546
LocalExec,
547547
}
548548

549+
/// LLVMRustChecksumKind
550+
#[derive(Copy, Clone)]
551+
#[repr(C)]
552+
pub enum ChecksumKind {
553+
None,
554+
MD5,
555+
SHA1,
556+
}
557+
549558
extern "C" {
550559
type Opaque;
551560
}
@@ -1640,6 +1649,9 @@ extern "C" {
16401649
FilenameLen: size_t,
16411650
Directory: *const c_char,
16421651
DirectoryLen: size_t,
1652+
CSKind: ChecksumKind,
1653+
Checksum: *const c_char,
1654+
ChecksumLen: size_t,
16431655
) -> &'a DIFile;
16441656

16451657
pub fn LLVMRustDIBuilderCreateSubroutineType(

‎src/librustc_interface/util.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_session::parse::CrateConfig;
2222
use rustc_session::CrateDisambiguator;
2323
use rustc_session::{config, early_error, filesearch, output, DiagnosticOutput, Session};
2424
use rustc_span::edition::Edition;
25-
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
25+
use rustc_span::source_map::{FileLoader, SourceMap};
2626
use rustc_span::symbol::{sym, Symbol};
2727
use smallvec::SmallVec;
2828
use std::env;
@@ -62,15 +62,13 @@ pub fn create_session(
6262
lint_caps: FxHashMap<lint::LintId, lint::Level>,
6363
descriptions: Registry,
6464
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
65-
let loader = file_loader.unwrap_or(box RealFileLoader);
66-
let source_map = Lrc::new(SourceMap::with_file_loader(loader, sopts.file_path_mapping()));
67-
let mut sess = session::build_session_with_source_map(
65+
let (mut sess, source_map) = session::build_session_with_source_map(
6866
sopts,
6967
input_path,
7068
descriptions,
71-
source_map.clone(),
7269
diagnostic_output,
7370
lint_caps,
71+
file_loader,
7472
);
7573

7674
let codegen_backend = get_codegen_backend(&sess);

‎src/librustc_middle/ich/impls_syntax.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
6161
cnum,
6262
// Do not hash the source as it is not encoded
6363
src: _,
64-
src_hash,
64+
ref src_hash,
6565
external_src: _,
6666
start_pos,
6767
end_pos: _,

‎src/librustc_session/config.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ use rustc_feature::UnstableFeatures;
1818
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST};
1919
use rustc_span::source_map::{FileName, FilePathMapping};
2020
use rustc_span::symbol::{sym, Symbol};
21+
use rustc_span::SourceFileHashAlgorithm;
2122

2223
use rustc_errors::emitter::HumanReadableErrorType;
23-
use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags};
24+
use rustc_errors::{ColorConfig, HandlerFlags};
2425

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

751-
pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
752+
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
752753
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
753-
sp.struct_fatal(&format!("Error loading target specification: {}", e))
754-
.help("Use `--print target-list` for a list of built-in targets")
755-
.emit();
756-
FatalError.raise();
754+
early_error(
755+
error_format,
756+
&format!(
757+
"Error loading target specification: {}. \
758+
Use `--print target-list` for a list of built-in targets",
759+
e
760+
),
761+
)
757762
});
758763

759764
let ptr_width = match &target.target_pointer_width[..] {
760765
"16" => 16,
761766
"32" => 32,
762767
"64" => 64,
763-
w => sp
764-
.fatal(&format!(
768+
w => early_error(
769+
error_format,
770+
&format!(
765771
"target specification was invalid: \
766772
unrecognized target-pointer-width {}",
767773
w
768-
))
769-
.raise(),
774+
),
775+
),
770776
};
771777

772778
Config { target, ptr_width }
@@ -1971,7 +1977,8 @@ impl PpMode {
19711977
crate mod dep_tracking {
19721978
use super::{
19731979
CFGuard, CrateType, DebugInfo, ErrorOutputType, LinkerPluginLto, LtoCli, OptLevel,
1974-
OutputTypes, Passes, Sanitizer, SwitchWithOptPath, SymbolManglingVersion,
1980+
OutputTypes, Passes, Sanitizer, SourceFileHashAlgorithm, SwitchWithOptPath,
1981+
SymbolManglingVersion,
19751982
};
19761983
use crate::lint;
19771984
use crate::utils::NativeLibraryKind;
@@ -2049,6 +2056,7 @@ crate mod dep_tracking {
20492056
impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
20502057
impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
20512058
impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
2059+
impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
20522060

20532061
impl_dep_tracking_hash_for_sortable_vec_of!(String);
20542062
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);

‎src/librustc_session/options.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel
1010

1111
use rustc_feature::UnstableFeatures;
1212
use rustc_span::edition::Edition;
13+
use rustc_span::SourceFileHashAlgorithm;
1314

1415
use std::collections::BTreeMap;
1516

@@ -283,12 +284,14 @@ macro_rules! options {
283284
Some("one of: `disabled`, `trampolines`, or `aliases`");
284285
pub const parse_symbol_mangling_version: Option<&str> =
285286
Some("either `legacy` or `v0` (RFC 2603)");
287+
pub const parse_src_file_hash: Option<&str> =
288+
Some("either `md5`, or `sha1`");
286289
}
287290

288291
#[allow(dead_code)]
289292
mod $mod_set {
290293
use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
291-
SymbolManglingVersion, CFGuard};
294+
SymbolManglingVersion, CFGuard, SourceFileHashAlgorithm};
292295
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
293296
use std::path::PathBuf;
294297
use std::str::FromStr;
@@ -622,6 +625,14 @@ macro_rules! options {
622625
};
623626
true
624627
}
628+
629+
fn parse_src_file_hash(slot: &mut Option<SourceFileHashAlgorithm>, v: Option<&str>) -> bool {
630+
match v.and_then(|s| SourceFileHashAlgorithm::from_str(s).ok()) {
631+
Some(hash_kind) => *slot = Some(hash_kind),
632+
_ => return false,
633+
}
634+
true
635+
}
625636
}
626637
) }
627638

@@ -961,4 +972,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
961972
"use new LLVM pass manager"),
962973
link_native_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
963974
"Link native libraries in the linker invocation."),
975+
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
976+
"hash algorithm of source files in debug info (`md5`, or `sha1`)"),
964977
}

‎src/librustc_session/session.rs

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
2020
use rustc_errors::json::JsonEmitter;
2121
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
2222
use rustc_span::edition::Edition;
23-
use rustc_span::source_map::{self, MultiSpan, Span};
23+
use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
24+
use rustc_span::SourceFileHashAlgorithm;
2425
use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
2526

2627
use std::cell::{self, RefCell};
@@ -870,16 +871,15 @@ pub fn build_session(
870871
local_crate_source_file: Option<PathBuf>,
871872
registry: rustc_errors::registry::Registry,
872873
) -> Session {
873-
let file_path_mapping = sopts.file_path_mapping();
874-
875874
build_session_with_source_map(
876875
sopts,
877876
local_crate_source_file,
878877
registry,
879-
Lrc::new(source_map::SourceMap::new(file_path_mapping)),
880878
DiagnosticOutput::Default,
881879
Default::default(),
880+
None,
882881
)
882+
.0
883883
}
884884

885885
fn default_emitter(
@@ -956,10 +956,10 @@ pub fn build_session_with_source_map(
956956
sopts: config::Options,
957957
local_crate_source_file: Option<PathBuf>,
958958
registry: rustc_errors::registry::Registry,
959-
source_map: Lrc<source_map::SourceMap>,
960959
diagnostics_output: DiagnosticOutput,
961-
lint_caps: FxHashMap<lint::LintId, lint::Level>,
962-
) -> Session {
960+
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
961+
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
962+
) -> (Session, Lrc<SourceMap>) {
963963
// FIXME: This is not general enough to make the warning lint completely override
964964
// normal diagnostic warnings, since the warning lint can also be denied and changed
965965
// later via the source code.
@@ -977,23 +977,33 @@ pub fn build_session_with_source_map(
977977
DiagnosticOutput::Default => None,
978978
DiagnosticOutput::Raw(write) => Some(write),
979979
};
980+
981+
let target_cfg = config::build_target_config(&sopts, sopts.error_format);
982+
let host_triple = TargetTriple::from_triple(config::host_triple());
983+
let host = Target::search(&host_triple).unwrap_or_else(|e| {
984+
early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
985+
});
986+
987+
let loader = file_loader.unwrap_or(Box::new(RealFileLoader));
988+
let hash_kind = sopts.debugging_opts.src_hash_algorithm.unwrap_or_else(|| {
989+
if target_cfg.target.options.is_like_msvc {
990+
SourceFileHashAlgorithm::Sha1
991+
} else {
992+
SourceFileHashAlgorithm::Md5
993+
}
994+
});
995+
let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
996+
loader,
997+
sopts.file_path_mapping(),
998+
hash_kind,
999+
));
9801000
let emitter = default_emitter(&sopts, registry, &source_map, write_dest);
9811001

982-
let diagnostic_handler = rustc_errors::Handler::with_emitter_and_flags(
1002+
let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags(
9831003
emitter,
9841004
sopts.debugging_opts.diagnostic_handler_flags(can_emit_warnings),
9851005
);
9861006

987-
build_session_(sopts, local_crate_source_file, diagnostic_handler, source_map, lint_caps)
988-
}
989-
990-
fn build_session_(
991-
sopts: config::Options,
992-
local_crate_source_file: Option<PathBuf>,
993-
span_diagnostic: rustc_errors::Handler,
994-
source_map: Lrc<source_map::SourceMap>,
995-
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
996-
) -> Session {
9971007
let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.debugging_opts.self_profile
9981008
{
9991009
let directory =
@@ -1015,13 +1025,7 @@ fn build_session_(
10151025
None
10161026
};
10171027

1018-
let host_triple = TargetTriple::from_triple(config::host_triple());
1019-
let host = Target::search(&host_triple).unwrap_or_else(|e| {
1020-
span_diagnostic.fatal(&format!("Error loading host specification: {}", e)).raise()
1021-
});
1022-
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
1023-
1024-
let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map);
1028+
let parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map.clone());
10251029
let sysroot = match &sopts.maybe_sysroot {
10261030
Some(sysroot) => sysroot.clone(),
10271031
None => filesearch::get_or_default_sysroot(),
@@ -1135,7 +1139,7 @@ fn build_session_(
11351139

11361140
validate_commandline_args_with_session_available(&sess);
11371141

1138-
sess
1142+
(sess, source_map)
11391143
}
11401144

11411145
// If it is useful to have a Session available already for validating a

‎src/librustc_span/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ scoped-tls = "1.0"
1919
unicode-width = "0.1.4"
2020
cfg-if = "0.1.2"
2121
log = "0.4"
22+
sha-1 = "0.8"
23+
md-5 = "0.8"

‎src/librustc_span/lib.rs

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ use std::borrow::Cow;
4747
use std::cell::RefCell;
4848
use std::cmp::{self, Ordering};
4949
use std::fmt;
50-
use std::hash::{Hash, Hasher};
50+
use std::hash::Hash;
5151
use std::ops::{Add, Sub};
5252
use std::path::PathBuf;
53+
use std::str::FromStr;
54+
55+
use md5::Md5;
56+
use sha1::Digest;
57+
use sha1::Sha1;
5358

5459
#[cfg(test)]
5560
mod tests;
@@ -874,6 +879,70 @@ impl ExternalSource {
874879
#[derive(Debug)]
875880
pub struct OffsetOverflowError;
876881

882+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
883+
pub enum SourceFileHashAlgorithm {
884+
Md5,
885+
Sha1,
886+
}
887+
888+
impl FromStr for SourceFileHashAlgorithm {
889+
type Err = ();
890+
891+
fn from_str(s: &str) -> Result<SourceFileHashAlgorithm, ()> {
892+
match s {
893+
"md5" => Ok(SourceFileHashAlgorithm::Md5),
894+
"sha1" => Ok(SourceFileHashAlgorithm::Sha1),
895+
_ => Err(()),
896+
}
897+
}
898+
}
899+
900+
rustc_data_structures::impl_stable_hash_via_hash!(SourceFileHashAlgorithm);
901+
902+
/// The hash of the on-disk source file used for debug info.
903+
#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
904+
#[derive(HashStable_Generic)]
905+
pub struct SourceFileHash {
906+
pub kind: SourceFileHashAlgorithm,
907+
value: [u8; 20],
908+
}
909+
910+
impl SourceFileHash {
911+
pub fn new(kind: SourceFileHashAlgorithm, src: &str) -> SourceFileHash {
912+
let mut hash = SourceFileHash { kind, value: Default::default() };
913+
let len = hash.hash_len();
914+
let value = &mut hash.value[..len];
915+
let data = src.as_bytes();
916+
match kind {
917+
SourceFileHashAlgorithm::Md5 => {
918+
value.copy_from_slice(&Md5::digest(data));
919+
}
920+
SourceFileHashAlgorithm::Sha1 => {
921+
value.copy_from_slice(&Sha1::digest(data));
922+
}
923+
}
924+
hash
925+
}
926+
927+
/// Check if the stored hash matches the hash of the string.
928+
pub fn matches(&self, src: &str) -> bool {
929+
Self::new(self.kind, src) == *self
930+
}
931+
932+
/// The bytes of the hash.
933+
pub fn hash_bytes(&self) -> &[u8] {
934+
let len = self.hash_len();
935+
&self.value[..len]
936+
}
937+
938+
fn hash_len(&self) -> usize {
939+
match self.kind {
940+
SourceFileHashAlgorithm::Md5 => 16,
941+
SourceFileHashAlgorithm::Sha1 => 20,
942+
}
943+
}
944+
}
945+
877946
/// A single source in the `SourceMap`.
878947
#[derive(Clone)]
879948
pub struct SourceFile {
@@ -889,7 +958,7 @@ pub struct SourceFile {
889958
/// The complete source code.
890959
pub src: Option<Lrc<String>>,
891960
/// The source code's hash.
892-
pub src_hash: u128,
961+
pub src_hash: SourceFileHash,
893962
/// The external source code (used for external crates, which will have a `None`
894963
/// value as `self.src`.
895964
pub external_src: Lock<ExternalSource>,
@@ -987,7 +1056,8 @@ impl Decodable for SourceFile {
9871056
let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
9881057
let name_was_remapped: bool =
9891058
d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?;
990-
let src_hash: u128 = d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
1059+
let src_hash: SourceFileHash =
1060+
d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
9911061
let start_pos: BytePos =
9921062
d.read_struct_field("start_pos", 3, |d| Decodable::decode(d))?;
9931063
let end_pos: BytePos = d.read_struct_field("end_pos", 4, |d| Decodable::decode(d))?;
@@ -1062,14 +1132,12 @@ impl SourceFile {
10621132
unmapped_path: FileName,
10631133
mut src: String,
10641134
start_pos: BytePos,
1135+
hash_kind: SourceFileHashAlgorithm,
10651136
) -> Self {
1137+
// Compute the file hash before any normalization.
1138+
let src_hash = SourceFileHash::new(hash_kind, &src);
10661139
let normalized_pos = normalize_src(&mut src, start_pos);
10671140

1068-
let src_hash = {
1069-
let mut hasher: StableHasher = StableHasher::new();
1070-
hasher.write(src.as_bytes());
1071-
hasher.finish::<u128>()
1072-
};
10731141
let name_hash = {
10741142
let mut hasher: StableHasher = StableHasher::new();
10751143
name.hash(&mut hasher);
@@ -1125,10 +1193,7 @@ impl SourceFile {
11251193
} = &mut *external_src
11261194
{
11271195
if let Some(src) = src {
1128-
let mut hasher: StableHasher = StableHasher::new();
1129-
hasher.write(src.as_bytes());
1130-
1131-
if hasher.finish::<u128>() == self.src_hash {
1196+
if self.src_hash.matches(&src) {
11321197
*src_kind = ExternalSourceKind::Present(Lrc::new(src));
11331198
return true;
11341199
}

‎src/librustc_span/source_map.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,27 +141,31 @@ pub struct SourceMap {
141141
// This is used to apply the file path remapping as specified via
142142
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
143143
path_mapping: FilePathMapping,
144+
145+
/// The algorithm used for hashing the contents of each source file.
146+
hash_kind: SourceFileHashAlgorithm,
144147
}
145148

146149
impl SourceMap {
147150
pub fn new(path_mapping: FilePathMapping) -> SourceMap {
148-
SourceMap {
149-
used_address_space: AtomicU32::new(0),
150-
files: Default::default(),
151-
file_loader: Box::new(RealFileLoader),
151+
Self::with_file_loader_and_hash_kind(
152+
Box::new(RealFileLoader),
152153
path_mapping,
153-
}
154+
SourceFileHashAlgorithm::Md5,
155+
)
154156
}
155157

156-
pub fn with_file_loader(
158+
pub fn with_file_loader_and_hash_kind(
157159
file_loader: Box<dyn FileLoader + Sync + Send>,
158160
path_mapping: FilePathMapping,
161+
hash_kind: SourceFileHashAlgorithm,
159162
) -> SourceMap {
160163
SourceMap {
161164
used_address_space: AtomicU32::new(0),
162165
files: Default::default(),
163166
file_loader,
164167
path_mapping,
168+
hash_kind,
165169
}
166170
}
167171

@@ -275,6 +279,7 @@ impl SourceMap {
275279
unmapped_path,
276280
src,
277281
Pos::from_usize(start_pos),
282+
self.hash_kind,
278283
));
279284

280285
let mut files = self.files.borrow_mut();
@@ -296,7 +301,7 @@ impl SourceMap {
296301
&self,
297302
filename: FileName,
298303
name_was_remapped: bool,
299-
src_hash: u128,
304+
src_hash: SourceFileHash,
300305
name_hash: u128,
301306
source_len: usize,
302307
cnum: CrateNum,

‎src/libserialize/serialize.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,30 @@ impl<T: Decodable> Decodable for Vec<T> {
706706
}
707707
}
708708

709+
impl Encodable for [u8; 20] {
710+
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
711+
s.emit_seq(self.len(), |s| {
712+
for (i, e) in self.iter().enumerate() {
713+
s.emit_seq_elt(i, |s| e.encode(s))?
714+
}
715+
Ok(())
716+
})
717+
}
718+
}
719+
720+
impl Decodable for [u8; 20] {
721+
fn decode<D: Decoder>(d: &mut D) -> Result<[u8; 20], D::Error> {
722+
d.read_seq(|d, len| {
723+
assert!(len == 20);
724+
let mut v = [0u8; 20];
725+
for i in 0..len {
726+
v[i] = d.read_seq_elt(i, |d| Decodable::decode(d))?;
727+
}
728+
Ok(v)
729+
})
730+
}
731+
}
732+
709733
impl<'a, T: Encodable> Encodable for Cow<'a, [T]>
710734
where
711735
[T]: ToOwned<Owned = Vec<T>>,

‎src/rustllvm/RustWrapper.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,25 @@ static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind)
640640
}
641641
}
642642

643+
enum class LLVMRustChecksumKind {
644+
None,
645+
MD5,
646+
SHA1,
647+
};
648+
649+
static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
650+
switch (Kind) {
651+
case LLVMRustChecksumKind::None:
652+
return None;
653+
case LLVMRustChecksumKind::MD5:
654+
return DIFile::ChecksumKind::CSK_MD5;
655+
case LLVMRustChecksumKind::SHA1:
656+
return DIFile::ChecksumKind::CSK_SHA1;
657+
default:
658+
report_fatal_error("bad ChecksumKind.");
659+
}
660+
}
661+
643662
extern "C" uint32_t LLVMRustDebugMetadataVersion() {
644663
return DEBUG_METADATA_VERSION;
645664
}
@@ -686,9 +705,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
686705
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
687706
LLVMRustDIBuilderRef Builder,
688707
const char *Filename, size_t FilenameLen,
689-
const char *Directory, size_t DirectoryLen) {
708+
const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
709+
const char *Checksum, size_t ChecksumLen) {
710+
Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
711+
Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
712+
if (llvmCSKind)
713+
CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
690714
return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
691-
StringRef(Directory, DirectoryLen)));
715+
StringRef(Directory, DirectoryLen),
716+
CSInfo));
692717
}
693718

694719
extern "C" LLVMMetadataRef

‎src/test/codegen/remap_path_prefix/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn main() {
2222
}
2323

2424
// Here we check that local debuginfo is mapped correctly.
25-
// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/")
25+
// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/"
2626

2727
// And here that debuginfo from other crates are expanded to absolute paths.
28-
// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: "")
28+
// CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: ""

‎src/test/codegen/remap_path_prefix/xcrate-generic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ pub fn foo() {
1111
}
1212

1313
// Here we check that local debuginfo is mapped correctly.
14-
// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: "")
14+
// CHECK: !DIFile(filename: "/the/aux-src/xcrate-generic.rs", directory: ""
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -g -Z src-hash-algorithm=md5
2+
3+
#![crate_type = "lib"]
4+
5+
pub fn test() {}
6+
// CHECK: checksumkind: CSK_MD5
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -g -Z src-hash-algorithm=sha1
2+
3+
#![crate_type = "lib"]
4+
5+
pub fn test() {}
6+
// CHECK: checksumkind: CSK_SHA1

‎src/tools/tidy/src/deps.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const LICENSES: &[&str] = &[
2626
const EXCEPTIONS: &[(&str, &str)] = &[
2727
("mdbook", "MPL-2.0"), // mdbook
2828
("openssl", "Apache-2.0"), // cargo, mdbook
29-
("arrayref", "BSD-2-Clause"), // mdbook via handlebars via pest
3029
("toml-query", "MPL-2.0"), // mdbook
3130
("toml-query_derive", "MPL-2.0"), // mdbook
3231
("is-match", "MPL-2.0"), // mdbook
@@ -74,6 +73,9 @@ const WHITELIST: &[&str] = &[
7473
"backtrace",
7574
"backtrace-sys",
7675
"bitflags",
76+
"block-buffer",
77+
"block-padding",
78+
"byte-tools",
7779
"byteorder",
7880
"c2-chacha",
7981
"cc",
@@ -87,15 +89,18 @@ const WHITELIST: &[&str] = &[
8789
"crossbeam-queue",
8890
"crossbeam-utils",
8991
"datafrog",
92+
"digest",
9093
"dlmalloc",
9194
"either",
9295
"ena",
9396
"env_logger",
97+
"fake-simd",
9498
"filetime",
9599
"flate2",
96100
"fortanix-sgx-abi",
97101
"fuchsia-zircon",
98102
"fuchsia-zircon-sys",
103+
"generic-array",
99104
"getopts",
100105
"getrandom",
101106
"hashbrown",
@@ -111,13 +116,15 @@ const WHITELIST: &[&str] = &[
111116
"lock_api",
112117
"log",
113118
"log_settings",
119+
"md-5",
114120
"measureme",
115121
"memchr",
116122
"memmap",
117123
"memoffset",
118124
"miniz_oxide",
119125
"nodrop",
120126
"num_cpus",
127+
"opaque-debug",
121128
"parking_lot",
122129
"parking_lot_core",
123130
"pkg-config",
@@ -150,6 +157,7 @@ const WHITELIST: &[&str] = &[
150157
"semver-parser",
151158
"serde",
152159
"serde_derive",
160+
"sha-1",
153161
"smallvec",
154162
"stable_deref_trait",
155163
"syn",
@@ -159,6 +167,7 @@ const WHITELIST: &[&str] = &[
159167
"termion",
160168
"termize",
161169
"thread_local",
170+
"typenum",
162171
"ucd-util",
163172
"unicode-normalization",
164173
"unicode-script",

0 commit comments

Comments
 (0)
This repository has been archived.