Merge pull request #972 from l4l/debug-file-hash

Support file hashes in .debug_line
This commit is contained in:
bjorn3 2020-04-21 12:17:46 +02:00 committed by GitHub
commit 5a6d9e1f1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 15 deletions

View file

@ -3,12 +3,12 @@ use std::path::{Component, Path};
use crate::prelude::*;
use rustc_span::{FileName, SourceFileAndLine, Pos};
use rustc_span::{FileName, SourceFile, SourceFileAndLine, Pos, SourceFileHash, SourceFileHashAlgorithm};
use cranelift_codegen::binemit::CodeOffset;
use gimli::write::{
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, UnitEntryId,
Address, AttributeValue, FileId, LineProgram, LineString, FileInfo, LineStringTable, UnitEntryId,
};
// 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] {
}
}
pub(crate) const MD5_LEN: usize = 16;
pub fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
if hash.kind == SourceFileHashAlgorithm::Md5 {
let mut buf = [0u8; MD5_LEN];
buf.copy_from_slice(hash.hash_bytes());
Some(FileInfo {
timestamp: 0,
size: 0,
md5: buf,
})
} else {
None
}
}
fn line_program_add_file(
line_program: &mut LineProgram,
line_strings: &mut LineStringTable,
file: &FileName,
file: &SourceFile,
) -> FileId {
match file {
match &file.name {
FileName::Real(path) => {
let (dir_path, file_name) = split_path_dir_and_file(path);
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
@ -57,13 +73,17 @@ fn line_program_add_file(
line_program.encoding(),
line_strings,
);
line_program.add_file(file_name, dir_id, None)
let info = make_file_info(file.src_hash);
line_program.file_has_md5 &= info.is_some();
line_program.add_file(file_name, dir_id, info)
}
// FIXME give more appropriate file names
_ => {
filename => {
let dir_id = line_program.default_directory();
let dummy_file_name = LineString::new(
file.to_string().into_bytes(),
filename.to_string().into_bytes(),
line_program.encoding(),
line_strings,
);
@ -79,7 +99,7 @@ impl<'tcx> DebugContext<'tcx> {
let file_id = line_program_add_file(
&mut self.dwarf.unit.line_program,
&mut self.dwarf.line_strings,
&loc.file.name,
&loc.file,
);
let entry = self.dwarf.unit.get_mut(entry_id);
@ -167,7 +187,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
true
};
if current_file_changed {
let file_id = line_program_add_file(line_program, line_strings, &file.name);
let file_id = line_program_add_file(line_program, line_strings, &file);
line_program.row().file = file_id;
last_file = Some(file.clone());
}

View file

@ -3,6 +3,8 @@ mod line_info;
use crate::prelude::*;
use rustc_span::FileName;
use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::ValueLocRange;
@ -42,7 +44,14 @@ impl<'tcx> DebugContext<'tcx> {
format: Format::Dwarf32,
// TODO: this should be configurable
// macOS doesn't seem to support DWARF > 3
version: 3,
// 5 version is required for md5 file hash
version: if tcx.sess.target.target.options.is_like_osx {
3
} else {
// FIXME change to version 5 once the gdb and lldb shipping with the latest debian
// support it.
4
},
address_size,
};
@ -52,18 +61,28 @@ impl<'tcx> DebugContext<'tcx> {
// Normally this would use option_env!("CFG_VERSION").
let producer = format!("cg_clif (rustc {})", "unknown version");
let comp_dir = tcx.sess.working_dir.0.to_string_lossy().into_owned();
let name = match tcx.sess.local_crate_source_file {
Some(ref path) => path.to_string_lossy().into_owned(),
None => tcx.crate_name(LOCAL_CRATE).to_string(),
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
Some(path) => {
let name = path.to_string_lossy().into_owned();
let info = tcx.sess
.source_map()
.get_source_file(&FileName::Real(path))
.map(|f| f.src_hash)
.and_then(line_info::make_file_info);
(name, info)
},
None => (tcx.crate_name(LOCAL_CRATE).to_string(), None),
};
let line_program = LineProgram::new(
let mut line_program = LineProgram::new(
encoding,
LineEncoding::default(),
LineString::new(comp_dir.as_bytes(), encoding, &mut dwarf.line_strings),
LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings),
None,
file_info,
);
line_program.file_has_md5 = file_info.is_some();
dwarf.unit.line_program = line_program;
{