Skip to content

Commit 5a6d9e1

Browse files
authored
Merge pull request #972 from l4l/debug-file-hash
Support file hashes in .debug_line
2 parents 385c656 + c3c5c4b commit 5a6d9e1

File tree

2 files changed

+54
-15
lines changed

2 files changed

+54
-15
lines changed

src/debuginfo/line_info.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ use std::path::{Component, Path};
33

44
use crate::prelude::*;
55

6-
use rustc_span::{FileName, SourceFileAndLine, Pos};
6+
use rustc_span::{FileName, SourceFile, SourceFileAndLine, Pos, SourceFileHash, SourceFileHashAlgorithm};
77

88
use cranelift_codegen::binemit::CodeOffset;
99

1010
use gimli::write::{
11-
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, UnitEntryId,
11+
Address, AttributeValue, FileId, LineProgram, LineString, FileInfo, LineStringTable, UnitEntryId,
1212
};
1313

1414
// OPTIMIZATION: It is cheaper to do this in one pass than using `.parent()` and `.file_name()`.
@@ -35,12 +35,28 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
3535
}
3636
}
3737

38+
pub(crate) const MD5_LEN: usize = 16;
39+
40+
pub fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
41+
if hash.kind == SourceFileHashAlgorithm::Md5 {
42+
let mut buf = [0u8; MD5_LEN];
43+
buf.copy_from_slice(hash.hash_bytes());
44+
Some(FileInfo {
45+
timestamp: 0,
46+
size: 0,
47+
md5: buf,
48+
})
49+
} else {
50+
None
51+
}
52+
}
53+
3854
fn line_program_add_file(
3955
line_program: &mut LineProgram,
4056
line_strings: &mut LineStringTable,
41-
file: &FileName,
57+
file: &SourceFile,
4258
) -> FileId {
43-
match file {
59+
match &file.name {
4460
FileName::Real(path) => {
4561
let (dir_path, file_name) = split_path_dir_and_file(path);
4662
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
@@ -57,13 +73,17 @@ fn line_program_add_file(
5773
line_program.encoding(),
5874
line_strings,
5975
);
60-
line_program.add_file(file_name, dir_id, None)
76+
77+
let info = make_file_info(file.src_hash);
78+
79+
line_program.file_has_md5 &= info.is_some();
80+
line_program.add_file(file_name, dir_id, info)
6181
}
6282
// FIXME give more appropriate file names
63-
_ => {
83+
filename => {
6484
let dir_id = line_program.default_directory();
6585
let dummy_file_name = LineString::new(
66-
file.to_string().into_bytes(),
86+
filename.to_string().into_bytes(),
6787
line_program.encoding(),
6888
line_strings,
6989
);
@@ -79,7 +99,7 @@ impl<'tcx> DebugContext<'tcx> {
7999
let file_id = line_program_add_file(
80100
&mut self.dwarf.unit.line_program,
81101
&mut self.dwarf.line_strings,
82-
&loc.file.name,
102+
&loc.file,
83103
);
84104

85105
let entry = self.dwarf.unit.get_mut(entry_id);
@@ -167,7 +187,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
167187
true
168188
};
169189
if current_file_changed {
170-
let file_id = line_program_add_file(line_program, line_strings, &file.name);
190+
let file_id = line_program_add_file(line_program, line_strings, &file);
171191
line_program.row().file = file_id;
172192
last_file = Some(file.clone());
173193
}

src/debuginfo/mod.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ mod line_info;
33

44
use crate::prelude::*;
55

6+
use rustc_span::FileName;
7+
68
use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc};
79
use cranelift_codegen::isa::TargetIsa;
810
use cranelift_codegen::ValueLocRange;
@@ -42,7 +44,14 @@ impl<'tcx> DebugContext<'tcx> {
4244
format: Format::Dwarf32,
4345
// TODO: this should be configurable
4446
// macOS doesn't seem to support DWARF > 3
45-
version: 3,
47+
// 5 version is required for md5 file hash
48+
version: if tcx.sess.target.target.options.is_like_osx {
49+
3
50+
} else {
51+
// FIXME change to version 5 once the gdb and lldb shipping with the latest debian
52+
// support it.
53+
4
54+
},
4655
address_size,
4756
};
4857

@@ -52,18 +61,28 @@ impl<'tcx> DebugContext<'tcx> {
5261
// Normally this would use option_env!("CFG_VERSION").
5362
let producer = format!("cg_clif (rustc {})", "unknown version");
5463
let comp_dir = tcx.sess.working_dir.0.to_string_lossy().into_owned();
55-
let name = match tcx.sess.local_crate_source_file {
56-
Some(ref path) => path.to_string_lossy().into_owned(),
57-
None => tcx.crate_name(LOCAL_CRATE).to_string(),
64+
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
65+
Some(path) => {
66+
let name = path.to_string_lossy().into_owned();
67+
let info = tcx.sess
68+
.source_map()
69+
.get_source_file(&FileName::Real(path))
70+
.map(|f| f.src_hash)
71+
.and_then(line_info::make_file_info);
72+
(name, info)
73+
},
74+
None => (tcx.crate_name(LOCAL_CRATE).to_string(), None),
5875
};
5976

60-
let line_program = LineProgram::new(
77+
let mut line_program = LineProgram::new(
6178
encoding,
6279
LineEncoding::default(),
6380
LineString::new(comp_dir.as_bytes(), encoding, &mut dwarf.line_strings),
6481
LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings),
65-
None,
82+
file_info,
6683
);
84+
line_program.file_has_md5 = file_info.is_some();
85+
6786
dwarf.unit.line_program = line_program;
6887

6988
{

0 commit comments

Comments
 (0)