diff --git a/src/base.rs b/src/base.rs index b2026f30d17a..73af2ea33be3 100644 --- a/src/base.rs +++ b/src/base.rs @@ -214,10 +214,10 @@ fn compile_fn<'tcx>( let unwind_context = &mut cx.unwind_context; cx.profiler.verbose_generic_activity("generate debug info").run(|| { if let Some(debug_context) = debug_context { - debug_context.define_function( + debug_context.define_function(codegened_func.symbol_name.name).finalize( + debug_context, tcx, codegened_func.func_id, - codegened_func.symbol_name.name, context, codegened_func.function_span, &codegened_func.source_info_set, diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 3e42905c8406..0726807000da 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -10,7 +10,9 @@ use crate::prelude::*; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::TargetIsa; -use gimli::write::{Address, AttributeValue, DwarfUnit, LineProgram, LineString, Range, RangeList}; +use gimli::write::{ + Address, AttributeValue, DwarfUnit, LineProgram, LineString, Range, RangeList, UnitEntryId, +}; use gimli::{Encoding, Format, LineEncoding, RunTimeEndian}; pub(crate) use emit::{DebugReloc, DebugRelocName}; @@ -23,6 +25,10 @@ pub(crate) struct DebugContext { unit_range_list: RangeList, } +pub(crate) struct FunctionDebugContext { + entry_id: UnitEntryId, +} + impl DebugContext { pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa) -> Self { let encoding = Encoding { @@ -93,17 +99,7 @@ impl DebugContext { DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()) } } - pub(crate) fn define_function( - &mut self, - tcx: TyCtxt<'_>, - func_id: FuncId, - name: &str, - context: &Context, - function_span: Span, - source_info_set: &indexmap::IndexSet, - ) { - let symbol = func_id.as_u32() as usize; - + pub(crate) fn define_function(&mut self, name: &str) -> FunctionDebugContext { // FIXME: add to appropriate scope instead of root let scope = self.dwarf.unit.root(); @@ -114,15 +110,37 @@ impl DebugContext { entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); - let end = - self.create_debug_lines(tcx, symbol, entry_id, context, function_span, source_info_set); + FunctionDebugContext { entry_id } + } +} - self.unit_range_list.0.push(Range::StartLength { +impl FunctionDebugContext { + pub(crate) fn finalize( + self, + debug_context: &mut DebugContext, + tcx: TyCtxt<'_>, + func_id: FuncId, + context: &Context, + function_span: Span, + source_info_set: &indexmap::IndexSet, + ) { + let symbol = func_id.as_u32() as usize; + + let end = debug_context.create_debug_lines( + tcx, + symbol, + self.entry_id, + context, + function_span, + source_info_set, + ); + + debug_context.unit_range_list.0.push(Range::StartLength { begin: Address::Symbol { symbol, addend: 0 }, length: u64::from(end), }); - let func_entry = self.dwarf.unit.get_mut(entry_id); + let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id); // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. func_entry.set( gimli::DW_AT_low_pc,