Split debuginfo/line_info.rs from debuginfo/mod.rs

This commit is contained in:
bjorn3 2019-11-12 21:08:08 +01:00
parent ed758912d3
commit beda7870fb
2 changed files with 153 additions and 134 deletions

149
src/debuginfo/line_info.rs Normal file
View file

@ -0,0 +1,149 @@
use crate::prelude::*;
use syntax::source_map::FileName;
use gimli::write::{
Address, AttributeValue, FileId, LineProgram, LineString,
LineStringTable, Range, UnitEntryId,
};
fn line_program_add_file(
line_program: &mut LineProgram,
line_strings: &mut LineStringTable,
file: &FileName,
) -> FileId {
match file {
FileName::Real(path) => {
let dir_name = path.parent().unwrap().to_str().unwrap().as_bytes();
let dir_id = if !dir_name.is_empty() {
let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
line_program.add_directory(dir_name)
} else {
line_program.default_directory()
};
let file_name = LineString::new(
path.file_name().unwrap().to_str().unwrap().as_bytes(),
line_program.encoding(),
line_strings,
);
line_program.add_file(file_name, dir_id, None)
}
// FIXME give more appropriate file names
_ => {
let dir_id = line_program.default_directory();
let dummy_file_name = LineString::new(
file.to_string().into_bytes(),
line_program.encoding(),
line_strings,
);
line_program.add_file(dummy_file_name, dir_id, None)
}
}
}
impl<'tcx> DebugContext<'tcx> {
pub(super) fn emit_location(&mut self, entry_id: UnitEntryId, span: Span) {
let loc = self.tcx.sess.source_map().lookup_char_pos(span.lo());
let file_id = line_program_add_file(
&mut self.dwarf.unit.line_program,
&mut self.dwarf.line_strings,
&loc.file.name,
);
let entry = self.dwarf.unit.get_mut(entry_id);
entry.set(
gimli::DW_AT_decl_file,
AttributeValue::FileIndex(Some(file_id)),
);
entry.set(
gimli::DW_AT_decl_line,
AttributeValue::Udata(loc.line as u64),
);
// FIXME: probably omit this
entry.set(
gimli::DW_AT_decl_column,
AttributeValue::Udata(loc.col.to_usize() as u64),
);
}
}
impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
pub(crate) fn create_debug_lines(
&mut self,
context: &Context,
isa: &dyn cranelift::codegen::isa::TargetIsa,
source_info_set: &indexmap::IndexSet<(Span, mir::SourceScope)>,
) {
let tcx = self.debug_context.tcx;
let line_program = &mut self.debug_context.dwarf.unit.line_program;
line_program.begin_sequence(Some(Address::Symbol {
symbol: self.symbol,
addend: 0,
}));
let encinfo = isa.encoding_info();
let func = &context.func;
let mut ebbs = func.layout.ebbs().collect::<Vec<_>>();
ebbs.sort_by_key(|ebb| func.offsets[*ebb]); // Ensure inst offsets always increase
let line_strings = &mut self.debug_context.dwarf.line_strings;
let mut create_row_for_span = |line_program: &mut LineProgram, span: Span| {
let loc = tcx.sess.source_map().lookup_char_pos(span.lo());
let file_id = line_program_add_file(line_program, line_strings, &loc.file.name);
/*println!(
"srcloc {:>04X} {}:{}:{}",
line_program.row().address_offset,
file.display(),
loc.line,
loc.col.to_u32()
);*/
line_program.row().file = file_id;
line_program.row().line = loc.line as u64;
line_program.row().column = loc.col.to_u32() as u64 + 1;
line_program.generate_row();
};
let mut end = 0;
for ebb in ebbs {
for (offset, inst, size) in func.inst_offsets(ebb, &encinfo) {
let srcloc = func.srclocs[inst];
line_program.row().address_offset = offset as u64;
if !srcloc.is_default() {
let source_info = *source_info_set.get_index(srcloc.bits() as usize).unwrap();
create_row_for_span(line_program, source_info.0);
} else {
create_row_for_span(line_program, self.mir.span);
}
end = offset + size;
}
}
line_program.end_sequence(end as u64);
let entry = self.debug_context.dwarf.unit.get_mut(self.entry_id);
entry.set(
gimli::DW_AT_low_pc,
AttributeValue::Address(Address::Symbol { symbol: self.symbol, addend: 0 }),
);
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(end as u64));
self.debug_context.emit_location(self.entry_id, self.mir.span);
self.debug_context
.unit_range_list
.0
.push(Range::StartLength {
begin: Address::Symbol {
symbol: self.symbol,
addend: 0,
},
length: end as u64,
});
}
}

View file

@ -1,15 +1,14 @@
mod emit;
mod line_info;
use crate::prelude::*;
use syntax::source_map::FileName;
use cranelift::codegen::ir::{StackSlots, ValueLoc};
use cranelift::codegen::isa::RegUnit;
use gimli::write::{
self, Address, AttributeValue, DwarfUnit, Expression, FileId, LineProgram, LineString,
LineStringTable, Location, LocationList, Range, RangeList, UnitEntryId, Writer,
self, Address, AttributeValue, DwarfUnit, Expression, LineProgram, LineString,
Location, LocationList, RangeList, UnitEntryId, Writer,
};
use gimli::{Encoding, Format, LineEncoding, Register, RunTimeEndian, X86_64};
@ -24,40 +23,6 @@ fn target_endian(tcx: TyCtxt) -> RunTimeEndian {
}
}
fn line_program_add_file(
line_program: &mut LineProgram,
line_strings: &mut LineStringTable,
file: &FileName,
) -> FileId {
match file {
FileName::Real(path) => {
let dir_name = path.parent().unwrap().to_str().unwrap().as_bytes();
let dir_id = if !dir_name.is_empty() {
let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
line_program.add_directory(dir_name)
} else {
line_program.default_directory()
};
let file_name = LineString::new(
path.file_name().unwrap().to_str().unwrap().as_bytes(),
line_program.encoding(),
line_strings,
);
line_program.add_file(file_name, dir_id, None)
}
// FIXME give more appropriate file names
_ => {
let dir_id = line_program.default_directory();
let dummy_file_name = LineString::new(
file.to_string().into_bytes(),
line_program.encoding(),
line_strings,
);
line_program.add_file(dummy_file_name, dir_id, None)
}
}
}
pub struct DebugContext<'tcx> {
tcx: TyCtxt<'tcx>,
@ -135,32 +100,6 @@ impl<'tcx> DebugContext<'tcx> {
}
}
fn emit_location(&mut self, entry_id: UnitEntryId, span: Span) {
let loc = self.tcx.sess.source_map().lookup_char_pos(span.lo());
let file_id = line_program_add_file(
&mut self.dwarf.unit.line_program,
&mut self.dwarf.line_strings,
&loc.file.name,
);
let entry = self.dwarf.unit.get_mut(entry_id);
entry.set(
gimli::DW_AT_decl_file,
AttributeValue::FileIndex(Some(file_id)),
);
entry.set(
gimli::DW_AT_decl_line,
AttributeValue::Udata(loc.line as u64),
);
// FIXME: probably omit this
entry.set(
gimli::DW_AT_decl_column,
AttributeValue::Udata(loc.col.to_usize() as u64),
);
}
fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId {
if let Some(type_id) = self.types.get(ty) {
return *type_id;
@ -248,13 +187,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
AttributeValue::StringRef(name_id),
);
entry.set(
gimli::DW_AT_low_pc,
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
);
debug_context.emit_location(entry_id, mir.span);
FunctionDebugContext {
debug_context,
entry_id,
@ -305,58 +237,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
isa: &dyn cranelift::codegen::isa::TargetIsa,
source_info_set: &indexmap::IndexSet<(Span, mir::SourceScope)>,
) {
let tcx = self.debug_context.tcx;
let line_program = &mut self.debug_context.dwarf.unit.line_program;
line_program.begin_sequence(Some(Address::Symbol {
symbol: self.symbol,
addend: 0,
}));
let encinfo = isa.encoding_info();
let func = &context.func;
let mut ebbs = func.layout.ebbs().collect::<Vec<_>>();
ebbs.sort_by_key(|ebb| func.offsets[*ebb]); // Ensure inst offsets always increase
let line_strings = &mut self.debug_context.dwarf.line_strings;
let mut create_row_for_span = |line_program: &mut LineProgram, span: Span| {
let loc = tcx.sess.source_map().lookup_char_pos(span.lo());
let file_id = line_program_add_file(line_program, line_strings, &loc.file.name);
/*println!(
"srcloc {:>04X} {}:{}:{}",
line_program.row().address_offset,
file.display(),
loc.line,
loc.col.to_u32()
);*/
line_program.row().file = file_id;
line_program.row().line = loc.line as u64;
line_program.row().column = loc.col.to_u32() as u64 + 1;
line_program.generate_row();
};
let mut end = 0;
for ebb in ebbs {
for (offset, inst, size) in func.inst_offsets(ebb, &encinfo) {
let srcloc = func.srclocs[inst];
line_program.row().address_offset = offset as u64;
if !srcloc.is_default() {
let source_info = *source_info_set.get_index(srcloc.bits() as usize).unwrap();
create_row_for_span(line_program, source_info.0);
} else {
create_row_for_span(line_program, self.mir.span);
}
end = offset + size;
}
}
line_program.end_sequence(end as u64);
let entry = self.debug_context.dwarf.unit.get_mut(self.entry_id);
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(end as u64));
self.create_debug_lines(context, isa, source_info_set);
{
let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
@ -391,17 +272,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
);
}
}
self.debug_context
.unit_range_list
.0
.push(Range::StartLength {
begin: Address::Symbol {
symbol: self.symbol,
addend: 0,
},
length: end as u64,
});
}
}