Implement local reading for locals on stack

This commit is contained in:
bjorn3 2019-11-12 21:36:31 +01:00
parent d8e9148c2e
commit 8edbbc45f7
3 changed files with 49 additions and 29 deletions

View file

@ -17,7 +17,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
let mut debug_context = cx
.debug_context
.as_mut()
.map(|debug_context| FunctionDebugContext::new(debug_context, instance, func_id, &name, &sig));
.map(|debug_context| FunctionDebugContext::new(debug_context, instance, func_id, &name));
// Make FunctionBuilder
let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
@ -61,6 +61,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
let instance = fx.instance;
let clif_comments = fx.clif_comments;
let source_info_set = fx.source_info_set;
let local_map = fx.local_map;
#[cfg(debug_assertions)]
crate::pretty_clif::write_clif_file(cx.tcx, "unopt", instance, &func, &clif_comments, None);
@ -92,7 +93,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
let isa = cx.module.isa();
debug_context
.as_mut()
.map(|x| x.define(context, isa, &source_info_set));
.map(|x| x.define(context, isa, &source_info_set, local_map));
// Clear context to make it usable for the next function
context.clear();

View file

@ -5,7 +5,7 @@ use syntax::source_map::FileName;
use cranelift::codegen::binemit::CodeOffset;
use gimli::write::{
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, Range, UnitEntryId,
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, UnitEntryId,
};
fn line_program_add_file(

View file

@ -172,7 +172,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
instance: Instance<'tcx>,
func_id: FuncId,
name: &str,
_sig: &Signature,
) -> Self {
let mir = debug_context.tcx.instance_mir(instance.def);
@ -235,6 +234,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
context: &Context,
isa: &dyn cranelift::codegen::isa::TargetIsa,
source_info_set: &indexmap::IndexSet<(Span, mir::SourceScope)>,
local_map: HashMap<mir::Local, CPlace<'tcx>>,
) {
let end = self.create_debug_lines(context, isa, source_info_set);
@ -251,34 +251,53 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
for (value_label, value_loc_ranges) in value_labels_ranges.iter() {
let var_id = self.define_local(mir::Local::from_u32(value_label.as_u32()));
for (local, _local_decl) in self.mir.local_decls.iter_enumerated() {
let var_id = self.define_local(local);
let value_label = cranelift::codegen::ir::ValueLabel::from_u32(local.as_u32());
let loc_list = LocationList(
value_loc_ranges
.iter()
.map(|value_loc_range| Location::StartEnd {
begin: Address::Symbol {
symbol: self.symbol,
addend: i64::from(value_loc_range.start),
},
end: Address::Symbol {
symbol: self.symbol,
addend: i64::from(value_loc_range.end),
},
data: Expression(
translate_loc(value_loc_range.loc, &context.func.stack_slots).unwrap(),
),
})
.collect(),
);
let loc_list_id = self.debug_context.dwarf.unit.locations.add(loc_list);
let location = match local_map[&local].inner() {
CPlaceInner::Var(_) => {
if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) {
let loc_list = LocationList(
value_loc_ranges
.iter()
.map(|value_loc_range| Location::StartEnd {
begin: Address::Symbol {
symbol: self.symbol,
addend: i64::from(value_loc_range.start),
},
end: Address::Symbol {
symbol: self.symbol,
addend: i64::from(value_loc_range.end),
},
data: Expression(
translate_loc(value_loc_range.loc, &context.func.stack_slots).unwrap(),
),
})
.collect(),
);
let loc_list_id = self.debug_context.dwarf.unit.locations.add(loc_list);
AttributeValue::LocationListRef(loc_list_id)
} else {
// FIXME set value labels for unused locals
AttributeValue::Exprloc(Expression(vec![]))
}
}
CPlaceInner::Addr(_, _) => {
// FIXME implement this (used by arguments and returns)
AttributeValue::Exprloc(Expression(vec![]))
}
CPlaceInner::Stack(stack_slot) => {
AttributeValue::Exprloc(Expression(translate_loc(ValueLoc::Stack(*stack_slot), &context.func.stack_slots).unwrap()))
}
CPlaceInner::NoPlace => AttributeValue::Exprloc(Expression(vec![])),
};
let var_entry = self.debug_context.dwarf.unit.get_mut(var_id);
var_entry.set(
gimli::DW_AT_location,
AttributeValue::LocationListRef(loc_list_id),
);
var_entry.set(gimli::DW_AT_location, location);
}
}
}