(
die: &write::FilterUnitEntry<'_, Reader<'_>>,
at: &AddressTransform,
)
| 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) { |
no test coverage detected