object/read/macho/
function_starts.rs1use crate::read::{Bytes, ReadError, Result};
2
3#[derive(Debug, Default, Clone, Copy)]
5pub struct FunctionStartsIterator<'data> {
6 data: Bytes<'data>,
7 addr: u64,
8}
9
10impl<'data> FunctionStartsIterator<'data> {
11 pub(super) fn new(data: &'data [u8], addr: u64) -> Self {
12 FunctionStartsIterator {
13 data: Bytes(data),
14 addr,
15 }
16 }
17}
18
19impl<'data> FunctionStartsIterator<'data> {
20 pub fn next(&mut self) -> Result<Option<u64>> {
22 if self.data.is_empty() {
23 return Ok(None);
24 }
25
26 let result = self.parse();
27 if result.is_err() {
28 self.data = Bytes(&[]);
29 }
30 result
31 }
32
33 fn parse(&mut self) -> Result<Option<u64>> {
34 let delta = self
35 .data
36 .read_uleb128()
37 .read_error("Invalid ULEB128 in LC_FUNCTION_STARTS")?;
38 if delta == 0 {
39 self.data = Bytes(&[]);
40 return Ok(None);
41 }
42
43 self.addr = self
44 .addr
45 .checked_add(delta)
46 .read_error("Address overflow in LC_FUNCTION_STARTS")?;
47 Ok(Some(self.addr))
48 }
49}
50
51impl<'data> Iterator for FunctionStartsIterator<'data> {
52 type Item = Result<u64>;
53
54 fn next(&mut self) -> Option<Self::Item> {
55 self.next().transpose()
56 }
57}