Skip to content

Commit 53509fe

Browse files
committed
[STASH] Debuginfo for stackslots
1 parent 357deaa commit 53509fe

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/debuginfo/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
mod emit;
44
mod line_info;
55
mod object;
6+
mod placeholder_types;
67
mod types;
78
mod unwind;
89

@@ -23,6 +24,7 @@ use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId};
2324
use rustc_target::callconv::FnAbi;
2425

2526
pub(crate) use self::emit::{DebugReloc, DebugRelocName};
27+
use self::placeholder_types::PlaceholderTypeDebugContext;
2628
pub(crate) use self::types::TypeDebugContext;
2729
pub(crate) use self::unwind::UnwindContext;
2830
use crate::debuginfo::emit::{address_for_data, address_for_func};
@@ -41,6 +43,7 @@ pub(crate) struct DebugContext {
4143
stack_pointer_register: Register,
4244
namespace_map: DefIdMap<UnitEntryId>,
4345
array_size_type: UnitEntryId,
46+
placeholder_types: PlaceholderTypeDebugContext,
4447

4548
filename_display_preference: FileNameDisplayPreference,
4649
}
@@ -145,6 +148,8 @@ impl DebugContext {
145148
AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()),
146149
);
147150

151+
let placeholder_types = PlaceholderTypeDebugContext::new(&mut dwarf);
152+
148153
DebugContext {
149154
endian,
150155
dwarf,
@@ -153,6 +158,7 @@ impl DebugContext {
153158
stack_pointer_register,
154159
namespace_map: DefIdMap::default(),
155160
array_size_type,
161+
placeholder_types,
156162
filename_display_preference,
157163
}
158164
}
@@ -317,6 +323,22 @@ impl DebugContext {
317323
}
318324

319325
impl FunctionDebugContext {
326+
fn define_raw_local(
327+
&mut self,
328+
debug_context: &mut DebugContext,
329+
scope: UnitEntryId,
330+
name: String,
331+
dw_ty: UnitEntryId,
332+
) -> UnitEntryId {
333+
let var_id = debug_context.dwarf.unit.add(scope, gimli::DW_TAG_variable);
334+
let var_entry = debug_context.dwarf.unit.get_mut(var_id);
335+
336+
var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
337+
var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
338+
339+
var_id
340+
}
341+
320342
pub(crate) fn finalize(
321343
mut self,
322344
debug_context: &mut DebugContext,
@@ -335,5 +357,23 @@ impl FunctionDebugContext {
335357
func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
336358
// Using Udata for DW_AT_high_pc requires at least DWARF4
337359
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
360+
361+
for (stack_slot, &offset) in &context.compiled_code().unwrap().sized_stackslot_offsets {
362+
let size = context.func.sized_stack_slots[stack_slot].size;
363+
364+
let array_type_id = debug_context.placeholder_type(size.into());
365+
366+
let var_id = self.define_raw_local(
367+
debug_context,
368+
self.entry_id,
369+
stack_slot.to_string(),
370+
array_type_id,
371+
);
372+
let var_entry = debug_context.dwarf.unit.get_mut(var_id);
373+
374+
let mut expr = Expression::new();
375+
expr.op_fbreg(offset.into());
376+
var_entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(expr));
377+
}
338378
}
339379
}

src/debuginfo/placeholder_types.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use gimli::write::{AttributeValue, DwarfUnit, UnitEntryId};
2+
use rustc_data_structures::fx::FxHashMap;
3+
4+
use super::DebugContext;
5+
6+
pub(crate) struct PlaceholderTypeDebugContext {
7+
// Placeholders
8+
u8_type: UnitEntryId,
9+
placeholder_types: FxHashMap<u64, UnitEntryId>,
10+
}
11+
12+
impl PlaceholderTypeDebugContext {
13+
pub(super) fn new(dwarf: &mut DwarfUnit) -> Self {
14+
let u8_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type);
15+
let u8_type_entry = dwarf.unit.get_mut(u8_type);
16+
u8_type_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(dwarf.strings.add("u8")));
17+
u8_type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned));
18+
u8_type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(1));
19+
20+
PlaceholderTypeDebugContext { u8_type, placeholder_types: FxHashMap::default() }
21+
}
22+
}
23+
24+
impl DebugContext {
25+
pub(crate) fn placeholder_type(&mut self, size: u64) -> UnitEntryId {
26+
*self.placeholder_types.placeholder_types.entry(size).or_insert_with(|| {
27+
let array_type_id =
28+
self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type);
29+
let array_type_entry = self.dwarf.unit.get_mut(array_type_id);
30+
array_type_entry
31+
.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.placeholder_types.u8_type));
32+
33+
let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type);
34+
let subrange_entry = self.dwarf.unit.get_mut(subrange_id);
35+
subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type));
36+
subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0));
37+
subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(size));
38+
39+
array_type_id
40+
})
41+
}
42+
}

0 commit comments

Comments
 (0)