Support file hashes in .debug_line
This commit is contained in:
parent
a78f851ea4
commit
077209e565
@ -1,14 +1,15 @@
|
||||
use std::ffi::OsStr;
|
||||
use std::time::SystemTime;
|
||||
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()`.
|
||||
@ -38,9 +39,9 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
|
||||
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 +58,32 @@ fn line_program_add_file(
|
||||
line_program.encoding(),
|
||||
line_strings,
|
||||
);
|
||||
line_program.add_file(file_name, dir_id, None)
|
||||
|
||||
let md5 = Some(file.src_hash)
|
||||
.filter(|h| matches!(h, SourceFileHash { kind: SourceFileHashAlgorithm::Md5, .. }))
|
||||
.map(|h| {
|
||||
let mut buf = [0u8; super::MD5_LEN];
|
||||
buf.copy_from_slice(h.hash_bytes());
|
||||
buf
|
||||
});
|
||||
|
||||
line_program.file_has_timestamp = true;
|
||||
line_program.file_has_md5 = md5.is_some();
|
||||
|
||||
line_program.add_file(file_name, dir_id, Some(FileInfo {
|
||||
timestamp: SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.map(|t| t.as_secs())
|
||||
.unwrap_or(0),
|
||||
size: 0,
|
||||
md5: md5.unwrap_or_default(),
|
||||
}))
|
||||
}
|
||||
// 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());
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
mod emit;
|
||||
mod line_info;
|
||||
|
||||
use std::time::SystemTime;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_span::{FileName, SourceFileHash, SourceFileHashAlgorithm};
|
||||
|
||||
use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::ValueLocRange;
|
||||
|
||||
use gimli::write::{
|
||||
self, Address, AttributeValue, DwarfUnit, Expression, LineProgram, LineString, Location,
|
||||
LocationList, Range, RangeList, UnitEntryId, Writer,
|
||||
LocationList, Range, RangeList, UnitEntryId, Writer, FileInfo,
|
||||
};
|
||||
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
|
||||
|
||||
@ -24,6 +28,8 @@ fn target_endian(tcx: TyCtxt<'_>) -> RunTimeEndian {
|
||||
}
|
||||
}
|
||||
|
||||
const MD5_LEN: usize = 16;
|
||||
|
||||
pub(crate) struct DebugContext<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
@ -42,7 +48,8 @@ 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: 5,
|
||||
address_size,
|
||||
};
|
||||
|
||||
@ -52,18 +59,41 @@ 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, md5) = match tcx.sess.local_crate_source_file.clone() {
|
||||
Some(path) => {
|
||||
let name = path.to_string_lossy().into_owned();
|
||||
let hash = tcx.sess
|
||||
.source_map()
|
||||
.get_source_file(&FileName::Real(path))
|
||||
.map(|f| f.src_hash)
|
||||
.filter(|h| matches!(h, SourceFileHash { kind: SourceFileHashAlgorithm::Md5, .. }))
|
||||
.map(|h| {
|
||||
let mut buf = [0u8; MD5_LEN];
|
||||
buf.copy_from_slice(h.hash_bytes());
|
||||
buf
|
||||
});
|
||||
(name, hash)
|
||||
},
|
||||
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,
|
||||
Some(FileInfo {
|
||||
timestamp: SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.map(|t| t.as_secs())
|
||||
.unwrap_or(0),
|
||||
size: 0,
|
||||
md5: md5.unwrap_or_default(),
|
||||
}),
|
||||
);
|
||||
line_program.file_has_timestamp = true;
|
||||
line_program.file_has_md5 = md5.is_some();
|
||||
|
||||
dwarf.unit.line_program = line_program;
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user