From 53509fe412932959da805130daaa8fc6723372e8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:09:05 +0000 Subject: [PATCH] [STASH] Debuginfo for stackslots --- src/debuginfo/mod.rs | 40 ++++++++++++++++++++++++++++ src/debuginfo/placeholder_types.rs | 42 ++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/debuginfo/placeholder_types.rs diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index f3a8623e2..52cde8b78 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -3,6 +3,7 @@ mod emit; mod line_info; mod object; +mod placeholder_types; mod types; mod unwind; @@ -23,6 +24,7 @@ use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; use rustc_target::callconv::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; +use self::placeholder_types::PlaceholderTypeDebugContext; pub(crate) use self::types::TypeDebugContext; pub(crate) use self::unwind::UnwindContext; use crate::debuginfo::emit::{address_for_data, address_for_func}; @@ -41,6 +43,7 @@ pub(crate) struct DebugContext { stack_pointer_register: Register, namespace_map: DefIdMap, array_size_type: UnitEntryId, + placeholder_types: PlaceholderTypeDebugContext, filename_display_preference: FileNameDisplayPreference, } @@ -145,6 +148,8 @@ impl DebugContext { AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), ); + let placeholder_types = PlaceholderTypeDebugContext::new(&mut dwarf); + DebugContext { endian, dwarf, @@ -153,6 +158,7 @@ impl DebugContext { stack_pointer_register, namespace_map: DefIdMap::default(), array_size_type, + placeholder_types, filename_display_preference, } } @@ -317,6 +323,22 @@ impl DebugContext { } impl FunctionDebugContext { + fn define_raw_local( + &mut self, + debug_context: &mut DebugContext, + scope: UnitEntryId, + name: String, + dw_ty: UnitEntryId, + ) -> UnitEntryId { + let var_id = debug_context.dwarf.unit.add(scope, gimli::DW_TAG_variable); + let var_entry = debug_context.dwarf.unit.get_mut(var_id); + + var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes())); + var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); + + var_id + } + pub(crate) fn finalize( mut self, debug_context: &mut DebugContext, @@ -335,5 +357,23 @@ impl FunctionDebugContext { func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); // Using Udata for DW_AT_high_pc requires at least DWARF4 func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + + for (stack_slot, &offset) in &context.compiled_code().unwrap().sized_stackslot_offsets { + let size = context.func.sized_stack_slots[stack_slot].size; + + let array_type_id = debug_context.placeholder_type(size.into()); + + let var_id = self.define_raw_local( + debug_context, + self.entry_id, + stack_slot.to_string(), + array_type_id, + ); + let var_entry = debug_context.dwarf.unit.get_mut(var_id); + + let mut expr = Expression::new(); + expr.op_fbreg(offset.into()); + var_entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(expr)); + } } } diff --git a/src/debuginfo/placeholder_types.rs b/src/debuginfo/placeholder_types.rs new file mode 100644 index 000000000..7bc2f741e --- /dev/null +++ b/src/debuginfo/placeholder_types.rs @@ -0,0 +1,42 @@ +use gimli::write::{AttributeValue, DwarfUnit, UnitEntryId}; +use rustc_data_structures::fx::FxHashMap; + +use super::DebugContext; + +pub(crate) struct PlaceholderTypeDebugContext { + // Placeholders + u8_type: UnitEntryId, + placeholder_types: FxHashMap, +} + +impl PlaceholderTypeDebugContext { + pub(super) fn new(dwarf: &mut DwarfUnit) -> Self { + let u8_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); + let u8_type_entry = dwarf.unit.get_mut(u8_type); + u8_type_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(dwarf.strings.add("u8"))); + u8_type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); + u8_type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(1)); + + PlaceholderTypeDebugContext { u8_type, placeholder_types: FxHashMap::default() } + } +} + +impl DebugContext { + pub(crate) fn placeholder_type(&mut self, size: u64) -> UnitEntryId { + *self.placeholder_types.placeholder_types.entry(size).or_insert_with(|| { + let array_type_id = + self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type); + let array_type_entry = self.dwarf.unit.get_mut(array_type_id); + array_type_entry + .set(gimli::DW_AT_type, AttributeValue::UnitRef(self.placeholder_types.u8_type)); + + let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type); + let subrange_entry = self.dwarf.unit.get_mut(subrange_id); + subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type)); + subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0)); + subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(size)); + + array_type_id + }) + } +}