Skip to content

Commit

Permalink
[STASH] Debuginfo for stackslots
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Nov 28, 2024
1 parent 95bb635 commit e2ee40c
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
mod emit;
mod line_info;
mod object;
mod placeholder_types;
mod types;
mod unwind;

Expand All @@ -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};
Expand All @@ -41,6 +43,7 @@ pub(crate) struct DebugContext {
stack_pointer_register: Register,
namespace_map: DefIdMap<UnitEntryId>,
array_size_type: UnitEntryId,
placeholder_types: PlaceholderTypeDebugContext,

filename_display_preference: FileNameDisplayPreference,
}
Expand Down Expand Up @@ -145,6 +148,8 @@ impl DebugContext {
AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()),
);

let placeholder_types = PlaceholderTypeDebugContext::new(&mut dwarf);

DebugContext {
endian,
dwarf,
Expand All @@ -153,6 +158,7 @@ impl DebugContext {
stack_pointer_register,
namespace_map: DefIdMap::default(),
array_size_type,
placeholder_types,
filename_display_preference,
}
}
Expand Down Expand Up @@ -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,
Expand All @@ -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));
}
}
}
42 changes: 42 additions & 0 deletions src/debuginfo/placeholder_types.rs
Original file line number Diff line number Diff line change
@@ -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<u64, UnitEntryId>,
}

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
})
}
}

0 comments on commit e2ee40c

Please sign in to comment.