diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 3c44f8ebf4c..0c8c10c15e2 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -6,6 +6,7 @@ use crate::prelude::*; use rustc_span::{FileName, SourceFile, SourceFileAndLine, Pos, SourceFileHash, SourceFileHashAlgorithm}; use cranelift_codegen::binemit::CodeOffset; +use cranelift_codegen::machinst::MachSrcLoc; use gimli::write::{ Address, AttributeValue, FileId, LineProgram, LineString, FileInfo, LineStringTable, UnitEntryId, @@ -128,18 +129,8 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> { source_info_set: &indexmap::IndexSet, ) -> CodeOffset { 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 blocks = func.layout.blocks().collect::>(); - blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase let line_strings = &mut self.debug_context.dwarf.line_strings; let function_span = self.mir.span; @@ -197,22 +188,58 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> { line_program.generate_row(); }; - let mut end = 0; - for block in blocks { - for (offset, inst, size) in func.inst_offsets(block, &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(); + line_program.begin_sequence(Some(Address::Symbol { + symbol: self.symbol, + addend: 0, + })); + + let mut func_end = 0; + + if let Some(ref mcr) = &context.mach_compile_result { + for &MachSrcLoc { start, end, loc } in mcr.sections.get_srclocs_sorted() { + // FIXME get_srclocs_sorted omits default srclocs + if func_end < start { + line_program.row().address_offset = func_end as u64; + create_row_for_span(line_program, self.mir.span); + } + line_program.row().address_offset = start as u64; + if !loc.is_default() { + let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap(); create_row_for_span(line_program, source_info.span); } else { create_row_for_span(line_program, self.mir.span); } - end = offset + size; + func_end = end; + } + // FIXME get_srclocs_sorted omits default srclocs + if func_end < mcr.sections.total_size() { + line_program.row().address_offset = func_end as u64; + create_row_for_span(line_program, self.mir.span); + func_end = mcr.sections.total_size(); + } + } else { + let encinfo = isa.encoding_info(); + let mut blocks = func.layout.blocks().collect::>(); + blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase + + for block in blocks { + for (offset, inst, size) in func.inst_offsets(block, &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.span); + } else { + create_row_for_span(line_program, self.mir.span); + } + func_end = offset + size; + } } } - line_program.end_sequence(end as u64); + assert_ne!(func_end, 0); + + line_program.end_sequence(func_end as u64); let entry = self.debug_context.dwarf.unit.get_mut(self.entry_id); entry.set( @@ -222,11 +249,11 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> { addend: 0, }), ); - entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(end as u64)); + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(func_end as u64)); self.debug_context .emit_location(self.entry_id, self.mir.span); - end + func_end } } diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 4927035035d..fb0a8b006c1 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -312,10 +312,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> { source_info_set: &indexmap::IndexSet, local_map: FxHashMap>, ) { - if isa.get_mach_backend().is_some() { - return; // The AArch64 backend doesn't support line debuginfo yet. - } - let end = self.create_debug_lines(context, isa, source_info_set); self.debug_context @@ -329,6 +325,10 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> { length: u64::from(end), }); + if isa.get_mach_backend().is_some() { + return; // Not yet implemented for the AArch64 backend. + } + let func_entry = self.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, AttributeValue::Address(Address::Symbol {