Skip to content

Commit bd7b59d

Browse files
authored
Delete DWARF Reader trait, also use gimli::UnitRef (#11883)
* Delete DWARF Reader trait Use the existing Reader type alias instead. Most places were already using this. * Use `gimli::UnitRef` This reduces parameter counts and makes it harder to use the wrong DWARF sections for split DWARF. A drawback is that `UnitRef<'a, R>` is invariant over `R`, so additional lifetime annotations are needed in some places. This probably also fixes a bug with the parsing of `AttributeValue::LocationListsRef`, but I didn't try to test this.
1 parent 7f7b39c commit bd7b59d

File tree

8 files changed

+201
-269
lines changed

8 files changed

+201
-269
lines changed

crates/cranelift/src/debug/gc.rs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ fn build_unit_dependencies(
8585
deps: &mut Dependencies,
8686
) -> read::Result<()> {
8787
let unit = dwarf.unit(header)?;
88+
let unit = unit.unit_ref(dwarf);
8889
let mut tree = unit.entries_tree(None)?;
8990
let root = tree.root()?;
90-
build_die_dependencies(root, dwarf, &unit, at, deps)?;
91+
build_die_dependencies(root, unit, at, deps)?;
9192
Ok(())
9293
}
9394

@@ -144,20 +145,15 @@ fn has_die_back_edge(die: &read::DebuggingInformationEntry<Reader<'_>>) -> read:
144145

145146
fn has_valid_code_range(
146147
die: &read::DebuggingInformationEntry<Reader<'_>>,
147-
dwarf: &read::Dwarf<Reader<'_>>,
148-
unit: &read::Unit<Reader<'_>>,
148+
unit: read::UnitRef<Reader<'_>>,
149149
at: &AddressTransform,
150150
) -> read::Result<bool> {
151151
match die.tag() {
152152
constants::DW_TAG_subprogram => {
153153
if let Some(ranges_attr) = die.attr_value(constants::DW_AT_ranges)? {
154154
let offset = match ranges_attr {
155-
read::AttributeValue::RangeListsRef(val) => {
156-
dwarf.ranges_offset_from_raw(unit, val)
157-
}
158-
read::AttributeValue::DebugRngListsIndex(index) => {
159-
dwarf.ranges_offset(unit, index)?
160-
}
155+
read::AttributeValue::RangeListsRef(val) => unit.ranges_offset_from_raw(val),
156+
read::AttributeValue::DebugRngListsIndex(index) => unit.ranges_offset(index)?,
161157
_ => return Ok(false),
162158
};
163159
let mut has_valid_base = if let Some(read::AttributeValue::Addr(low_pc)) =
@@ -167,7 +163,7 @@ fn has_valid_code_range(
167163
} else {
168164
None
169165
};
170-
let mut it = dwarf.ranges.raw_ranges(offset, unit.encoding())?;
166+
let mut it = unit.raw_ranges(offset)?;
171167
while let Some(range) = it.next()? {
172168
// If at least one of the range addresses can be converted,
173169
// declaring code range as valid.
@@ -188,7 +184,7 @@ fn has_valid_code_range(
188184
}
189185
read::RawRngListEntry::StartxEndx { begin, .. }
190186
| read::RawRngListEntry::StartxLength { begin, .. } => {
191-
let addr = dwarf.address(unit, begin)?;
187+
let addr = unit.address(begin)?;
192188
if at.can_translate_address(addr) {
193189
return Ok(true);
194190
}
@@ -197,7 +193,7 @@ fn has_valid_code_range(
197193
has_valid_base = Some(at.can_translate_address(addr));
198194
}
199195
read::RawRngListEntry::BaseAddressx { addr } => {
200-
let addr = dwarf.address(unit, addr)?;
196+
let addr = unit.address(addr)?;
201197
has_valid_base = Some(at.can_translate_address(addr));
202198
}
203199
read::RawRngListEntry::OffsetPair { .. } => (),
@@ -208,7 +204,7 @@ fn has_valid_code_range(
208204
if let read::AttributeValue::Addr(a) = low_pc {
209205
return Ok(at.can_translate_address(a));
210206
} else if let read::AttributeValue::DebugAddrIndex(i) = low_pc {
211-
let a = dwarf.debug_addr.get_address(4, unit.addr_base, i)?;
207+
let a = unit.address(i)?;
212208
return Ok(at.can_translate_address(a));
213209
}
214210
}
@@ -220,45 +216,43 @@ fn has_valid_code_range(
220216

221217
fn build_die_dependencies(
222218
die: read::EntriesTreeNode<Reader<'_>>,
223-
dwarf: &read::Dwarf<Reader<'_>>,
224-
unit: &read::Unit<Reader<'_>>,
219+
unit: read::UnitRef<Reader<'_>>,
225220
at: &AddressTransform,
226221
deps: &mut Dependencies,
227222
) -> read::Result<()> {
228223
let entry = die.entry();
229-
let offset = entry.offset().to_unit_section_offset(unit);
224+
let offset = entry.offset().to_unit_section_offset(&unit);
230225
let mut attrs = entry.attrs();
231226
while let Some(attr) = attrs.next()? {
232-
build_attr_dependencies(&attr, offset, dwarf, unit, at, deps)?;
227+
build_attr_dependencies(&attr, offset, unit, at, deps)?;
233228
}
234229

235230
let mut children = die.children();
236231
while let Some(child) = children.next()? {
237232
let child_entry = child.entry();
238-
let child_offset = child_entry.offset().to_unit_section_offset(unit);
233+
let child_offset = child_entry.offset().to_unit_section_offset(&unit);
239234
deps.add_edge(child_offset, offset);
240235
if has_die_back_edge(child_entry)? {
241236
deps.add_edge(offset, child_offset);
242237
}
243-
if has_valid_code_range(child_entry, dwarf, unit, at)? {
238+
if has_valid_code_range(child_entry, unit, at)? {
244239
deps.add_root(child_offset);
245240
}
246-
build_die_dependencies(child, dwarf, unit, at, deps)?;
241+
build_die_dependencies(child, unit, at, deps)?;
247242
}
248243
Ok(())
249244
}
250245

251246
fn build_attr_dependencies(
252247
attr: &read::Attribute<Reader<'_>>,
253248
offset: UnitSectionOffset,
254-
_dwarf: &read::Dwarf<Reader<'_>>,
255-
unit: &read::Unit<Reader<'_>>,
249+
unit: read::UnitRef<Reader<'_>>,
256250
_at: &AddressTransform,
257251
deps: &mut Dependencies,
258252
) -> read::Result<()> {
259253
match attr.value() {
260254
read::AttributeValue::UnitRef(val) => {
261-
let ref_offset = val.to_unit_section_offset(unit);
255+
let ref_offset = val.to_unit_section_offset(&unit);
262256
deps.add_edge(offset, ref_offset);
263257
}
264258
read::AttributeValue::DebugInfoRef(val) => {

crates/cranelift/src/debug/transform/attr.rs

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::{TransformError, dbi_log};
1010
use anyhow::{Error, bail};
1111
use cranelift_codegen::isa::TargetIsa;
1212
use gimli::{
13-
AttributeValue, DebugLineOffset, DebuggingInformationEntry, Dwarf, Unit, UnitOffset, write,
13+
AttributeValue, DebugLineOffset, DebuggingInformationEntry, UnitOffset, UnitRef, write,
1414
};
1515

1616
#[derive(Debug)]
@@ -47,10 +47,9 @@ fn is_exprloc_to_loclist_allowed(attr_name: gimli::constants::DwAt) -> bool {
4747
}
4848

4949
pub(crate) fn clone_die_attributes<'a>(
50-
dwarf: &gimli::Dwarf<Reader<'a>>,
51-
unit: &Unit<Reader<'a>>,
50+
unit: UnitRef<Reader<'a>>,
5251
entry: &DebuggingInformationEntry<Reader<'a>>,
53-
addr_tr: &'a AddressTransform,
52+
addr_tr: &AddressTransform,
5453
frame_info: Option<&FunctionFrameInfo>,
5554
out_unit: &mut write::Unit,
5655
out_entry_id: write::UnitEntryId,
@@ -59,7 +58,7 @@ pub(crate) fn clone_die_attributes<'a>(
5958
out_strings: &mut write::StringTable,
6059
pending_die_refs: &mut PendingUnitRefs,
6160
pending_di_refs: &mut PendingDebugInfoRefs,
62-
mut attr_context: EntryAttributesContext<'a>,
61+
mut attr_context: EntryAttributesContext<'_>,
6362
isa: &dyn TargetIsa,
6463
) -> Result<(), Error> {
6564
let unit_encoding = unit.encoding();
@@ -70,12 +69,12 @@ pub(crate) fn clone_die_attributes<'a>(
7069
// FIXME for CU: currently address_transform operate on a single
7170
// function range, and when CU spans multiple ranges the
7271
// transformation may be incomplete.
73-
RangeInfoBuilder::from(dwarf, unit, entry)?
72+
RangeInfoBuilder::from(unit, entry)?
7473
};
7574
range_info.build(addr_tr, out_unit, out_entry_id);
7675

7776
let mut is_obj_ptr = false;
78-
prepare_die_context(dwarf, unit, entry, &mut attr_context, &mut is_obj_ptr)?;
77+
prepare_die_context(unit, entry, &mut attr_context, &mut is_obj_ptr)?;
7978

8079
let mut attrs = entry.attrs();
8180
while let Some(attr) = attrs.next()? {
@@ -133,7 +132,7 @@ pub(crate) fn clone_die_attributes<'a>(
133132
continue;
134133
}
135134
gimli::DW_AT_name => {
136-
let old_name: &str = &dwarf.attr_string(unit, attr.value())?.to_string_lossy();
135+
let old_name: &str = &unit.attr_string(attr.value())?.to_string_lossy();
137136
let new_name = format!("__{old_name}");
138137
dbi_log!(
139138
"Object pointer: renamed '{}' -> '{}'",
@@ -158,7 +157,7 @@ pub(crate) fn clone_die_attributes<'a>(
158157
write::AttributeValue::Address(addr)
159158
}
160159
AttributeValue::DebugAddrIndex(i) => {
161-
let u = dwarf.address(unit, i)?;
160+
let u = unit.address(i)?;
162161
let addr = addr_tr.translate(u).unwrap_or(write::Address::Constant(0));
163162
write::AttributeValue::Address(addr)
164163
}
@@ -202,28 +201,18 @@ pub(crate) fn clone_die_attributes<'a>(
202201
}
203202
AttributeValue::String(d) => write::AttributeValue::String(d.to_vec()),
204203
AttributeValue::DebugStrRef(_) | AttributeValue::DebugStrOffsetsIndex(_) => {
205-
let s = dwarf
206-
.attr_string(unit, attr_value)?
207-
.to_string_lossy()
208-
.into_owned();
204+
let s = unit.attr_string(attr_value)?.to_vec();
209205
write::AttributeValue::StringRef(out_strings.add(s))
210206
}
211207
AttributeValue::RangeListsRef(_) | AttributeValue::DebugRngListsIndex(_) => {
212-
let r = dwarf.attr_ranges_offset(unit, attr_value)?.unwrap();
213-
let range_info = RangeInfoBuilder::from_ranges_ref(dwarf, unit, r)?;
208+
let r = unit.attr_ranges_offset(attr_value)?.unwrap();
209+
let range_info = RangeInfoBuilder::from_ranges_ref(unit, r)?;
214210
let range_list_id = range_info.build_ranges(addr_tr, &mut out_unit.ranges);
215211
write::AttributeValue::RangeListRef(range_list_id)
216212
}
217213
AttributeValue::LocationListsRef(_) | AttributeValue::DebugLocListsIndex(_) => {
218-
let r = dwarf.attr_locations_offset(unit, attr_value)?.unwrap();
219-
let low_pc = 0;
220-
let mut locs = dwarf.locations.locations(
221-
r,
222-
unit_encoding,
223-
low_pc,
224-
&dwarf.debug_addr,
225-
unit.addr_base,
226-
)?;
214+
let r = unit.attr_locations_offset(attr_value)?.unwrap();
215+
let mut locs = unit.locations(r)?;
227216
let frame_base =
228217
if let EntryAttributesContext::Children { frame_base, .. } = attr_context {
229218
frame_base
@@ -373,10 +362,9 @@ pub(crate) fn clone_die_attributes<'a>(
373362
Ok(())
374363
}
375364

376-
fn prepare_die_context(
377-
dwarf: &Dwarf<Reader<'_>>,
378-
unit: &Unit<Reader<'_>>,
379-
entry: &DebuggingInformationEntry<Reader<'_>>,
365+
fn prepare_die_context<'a>(
366+
unit: UnitRef<Reader<'a>>,
367+
entry: &DebuggingInformationEntry<Reader<'a>>,
380368
attr_context: &mut EntryAttributesContext<'_>,
381369
is_obj_ptr: &mut bool,
382370
) -> Result<(), Error> {
@@ -407,7 +395,7 @@ fn prepare_die_context(
407395
subprogram.param_num += 1;
408396

409397
if subprogram.obj_ptr == entry.offset()
410-
|| is_obj_ptr_param(dwarf, unit, entry, subprogram.param_num)?
398+
|| is_obj_ptr_param(unit, entry, subprogram.param_num)?
411399
{
412400
*is_obj_ptr = true;
413401
}
@@ -418,10 +406,9 @@ fn prepare_die_context(
418406
Ok(())
419407
}
420408

421-
fn is_obj_ptr_param(
422-
dwarf: &Dwarf<Reader<'_>>,
423-
unit: &Unit<Reader<'_>>,
424-
entry: &DebuggingInformationEntry<Reader<'_>>,
409+
fn is_obj_ptr_param<'a>(
410+
unit: UnitRef<Reader<'a>>,
411+
entry: &DebuggingInformationEntry<Reader<'a>>,
425412
param_num: isize,
426413
) -> Result<bool, Error> {
427414
debug_assert!(entry.tag() == gimli::DW_TAG_formal_parameter);
@@ -437,7 +424,7 @@ fn is_obj_ptr_param(
437424
{
438425
// Either this has no name (declarations omit them), or its explicitly "this".
439426
let name = entry.attr_value(gimli::DW_AT_name)?;
440-
if name.is_none() || dwarf.attr_string(unit, name.unwrap())?.slice().eq(b"this") {
427+
if name.is_none() || unit.attr_string(name.unwrap())?.slice().eq(b"this") {
441428
// Finally, a type check. We expect a pointer.
442429
if let Some(type_attr) = entry.attr_value(gimli::DW_AT_type)? {
443430
if let Some(type_die) = resolve_die_ref(unit, &type_attr)? {

0 commit comments

Comments
 (0)