#[derive(Default)]
pub(crate) struct RangeAttributes<R: gimli::Reader> {
pub(crate) low_pc: Option<u64>,
pub(crate) high_pc: Option<u64>,
pub(crate) size: Option<u64>,
pub(crate) ranges_offset: Option<gimli::RangeListsOffset<R::Offset>>,
}
impl<R: gimli::Reader> RangeAttributes<R> {
pub(crate) fn for_each_range<F: FnMut(gimli::Range)>(
&self,
unit: gimli::UnitRef<'_, R>,
mut f: F,
) -> gimli::Result<bool> {
let mut added_any = false;
let mut add_range = |range: gimli::Range| {
if range.begin < range.end {
f(range);
added_any = true
}
};
if let Some(ranges_offset) = self.ranges_offset {
let mut range_list = unit.ranges(ranges_offset)?;
while let Some(range) = range_list.next()? {
add_range(range);
}
} else if let (Some(begin), Some(end)) = (self.low_pc, self.high_pc) {
add_range(gimli::Range { begin, end });
} else if let (Some(begin), Some(size)) = (self.low_pc, self.size) {
add_range(gimli::Range {
begin,
end: begin + size,
});
}
Ok(added_any)
}
pub(crate) fn bounds(&self) -> Option<gimli::Range> {
if let (Some(begin), Some(end)) = (self.low_pc, self.high_pc) {
Some(gimli::Range { begin, end })
} else if let (Some(begin), Some(size)) = (self.low_pc, self.size) {
Some(gimli::Range {
begin,
end: begin + size,
})
} else {
None
}
}
}