Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/cranelift/src/debug/gc.rs
3079 views
1
use crate::debug::Reader;
2
use crate::debug::transform::AddressTransform;
3
use gimli::constants;
4
use gimli::read;
5
use gimli::write;
6
7
pub fn build_dependencies(
8
filter: &mut write::FilterUnitSection<'_, Reader<'_>>,
9
at: &AddressTransform,
10
) -> write::ConvertResult<()> {
11
while let Some(mut unit) = filter.read_unit()? {
12
build_die_dependencies(&mut unit, at)?;
13
}
14
Ok(())
15
}
16
17
fn has_valid_code_range(
18
die: &write::FilterUnitEntry<'_, Reader<'_>>,
19
at: &AddressTransform,
20
) -> read::Result<bool> {
21
let unit = die.read_unit;
22
match die.tag {
23
constants::DW_TAG_subprogram => {
24
if let Some(ranges_attr) = die.attr_value(constants::DW_AT_ranges) {
25
let offset = match ranges_attr {
26
read::AttributeValue::RangeListsRef(val) => unit.ranges_offset_from_raw(val),
27
read::AttributeValue::DebugRngListsIndex(index) => unit.ranges_offset(index)?,
28
_ => return Ok(false),
29
};
30
let mut has_valid_base = if let Some(read::AttributeValue::Addr(low_pc)) =
31
die.attr_value(constants::DW_AT_low_pc)
32
{
33
Some(at.can_translate_address(low_pc))
34
} else {
35
None
36
};
37
let mut it = unit.raw_ranges(offset)?;
38
while let Some(range) = it.next()? {
39
// If at least one of the range addresses can be converted,
40
// declaring code range as valid.
41
match range {
42
read::RawRngListEntry::AddressOrOffsetPair { .. }
43
if has_valid_base.is_some() =>
44
{
45
if has_valid_base.unwrap() {
46
return Ok(true);
47
}
48
}
49
read::RawRngListEntry::StartEnd { begin, .. }
50
| read::RawRngListEntry::StartLength { begin, .. }
51
| read::RawRngListEntry::AddressOrOffsetPair { begin, .. } => {
52
if at.can_translate_address(begin) {
53
return Ok(true);
54
}
55
}
56
read::RawRngListEntry::StartxEndx { begin, .. }
57
| read::RawRngListEntry::StartxLength { begin, .. } => {
58
let addr = unit.address(begin)?;
59
if at.can_translate_address(addr) {
60
return Ok(true);
61
}
62
}
63
read::RawRngListEntry::BaseAddress { addr } => {
64
has_valid_base = Some(at.can_translate_address(addr));
65
}
66
read::RawRngListEntry::BaseAddressx { addr } => {
67
let addr = unit.address(addr)?;
68
has_valid_base = Some(at.can_translate_address(addr));
69
}
70
read::RawRngListEntry::OffsetPair { .. } => (),
71
}
72
}
73
return Ok(false);
74
} else if let Some(low_pc) = die.attr_value(constants::DW_AT_low_pc) {
75
if let read::AttributeValue::Addr(a) = low_pc {
76
return Ok(at.can_translate_address(a));
77
} else if let read::AttributeValue::DebugAddrIndex(i) = low_pc {
78
let a = unit.address(i)?;
79
return Ok(at.can_translate_address(a));
80
}
81
}
82
}
83
_ => (),
84
}
85
Ok(false)
86
}
87
88
fn build_die_dependencies(
89
unit: &mut write::FilterUnit<'_, Reader<'_>>,
90
at: &AddressTransform,
91
) -> write::ConvertResult<()> {
92
let mut die = write::FilterUnitEntry::null(unit.read_unit);
93
while unit.read_entry(&mut die)? {
94
if has_valid_code_range(&die, at)? {
95
unit.require_entry(die.offset);
96
}
97
}
98
Ok(())
99
}
100
101