pub fn lookup(&self, pc: u32) -> Result<Option<Function>, Error> {
        let Self {
            pages,
            data,
            global_opcodes,
        } = self;
        let page_index = match pages.binary_search_by_key(&pc, PageEntry::first_address) {
            Ok(i) => i,
            Err(insertion_index) => {
                if insertion_index == 0 {
                    return Ok(None);
                }
                insertion_index - 1
            }
        };
        if page_index == pages.len() - 1 {
            // We found the sentinel last page, which just marks the end of the range.
            // So the looked up address is at or after the end address, i.e. outside the
            // range of addresses covered by this UnwindInfo.
            return Ok(None);
        }
        let page_entry = &pages[page_index];
        let next_page_entry = &pages[page_index + 1];
        let page_offset = page_entry.page_offset();
        match page_entry.page_kind(data)? {
            consts::PAGE_KIND_REGULAR => {
                let page = RegularPage::parse(data, page_offset.into())?;
                let functions = page.functions(data, page_offset)?;
                let function_index =
                    match functions.binary_search_by_key(&pc, RegularFunctionEntry::address) {
                        Ok(i) => i,
                        Err(insertion_index) => {
                            if insertion_index == 0 {
                                return Err(Error::InvalidPageEntryFirstAddress);
                            }
                            insertion_index - 1
                        }
                    };
                let entry = &functions[function_index];
                let fun_address = entry.address();
                let next_fun_address = if let Some(next_entry) = functions.get(function_index + 1) {
                    next_entry.address()
                } else {
                    next_page_entry.first_address()
                };
                Ok(Some(Function {
                    start_address: fun_address,
                    end_address: next_fun_address,
                    opcode: entry.opcode(),
                }))
            }
            consts::PAGE_KIND_COMPRESSED => {
                let page = CompressedPage::parse(data, page_offset.into())?;
                let functions = page.functions(data, page_offset)?;
                let page_address = page_entry.first_address();
                let rel_pc = pc - page_address;
                let function_index = match functions.binary_search_by_key(&rel_pc, |&entry| {
                    CompressedFunctionEntry::new(entry.into()).relative_address()
                }) {
                    Ok(i) => i,
                    Err(insertion_index) => {
                        if insertion_index == 0 {
                            return Err(Error::InvalidPageEntryFirstAddress);
                        }
                        insertion_index - 1
                    }
                };

                let entry = CompressedFunctionEntry::new(functions[function_index].into());
                let fun_address = page_address + entry.relative_address();
                let next_fun_address = if let Some(next_entry) = functions.get(function_index + 1) {
                    let next_entry = CompressedFunctionEntry::new((*next_entry).into());
                    page_address + next_entry.relative_address()
                } else {
                    next_page_entry.first_address()
                };

                let opcode_index: usize = entry.opcode_index().into();
                let opcode = if opcode_index < global_opcodes.len() {
                    global_opcodes[opcode_index].opcode()
                } else {
                    let local_opcodes = page.local_opcodes(data, page_offset)?;
                    let local_index = opcode_index - global_opcodes.len();
                    local_opcodes[local_index].opcode()
                };
                Ok(Some(Function {
                    start_address: fun_address,
                    end_address: next_fun_address,
                    opcode,
                }))
            }
            consts::PAGE_KIND_SENTINEL => {
                // Only the last page should be a sentinel page, and we've already checked earlier
                // that we're not in the last page.
                Err(Error::UnexpectedSentinelPage)
            }
            _ => Err(Error::InvalidPageKind),
        }
    }
/// Looks up the unwind information for the function that covers the given address.
/// Returns `Ok(Some(function))` if a function was found.
/// Returns `Ok(None)` if the address was outside of the range of addresses covered
/// by the unwind info.
/// Returns `Err(error)` if there was a problem with the format of the `__unwind_info`
/// data.
///
/// This lookup is architecture agnostic. The opcode is returned as a u32.
/// To actually perform unwinding, the opcode needs to be parsed in an
/// architecture-specific manner.
///
/// The design of the compact unwinding format makes this lookup extremely cheap.
/// It's just two binary searches: First to find the right page, end then to find
/// the right function within a page. The search happens inside the wrapped data,
/// with no extra copies.
Looks up the unwind information for the function that covers the given address.
Returns `Ok(Some(function))` if a function was found.
Returns `Ok(None)` if the address was outside of the range of addresses covered
by the unwind info.
Returns `Err(error)` if there was a problem with the format of the `__unwind_info`
data.

This lookup is architecture agnostic. The opcode is returned as a u32.
To actually perform unwinding, the opcode needs to be parsed in an
architecture-specific manner.

The design of the compact unwinding format makes this lookup extremely cheap.
It's just two binary searches: First to find the right page, end then to find
the right function within a page. The search happens inside the wrapped data,
with no extra copies.
Looks up the unwind information for the function that covers the given address . Returns ` Ok ( Some ( function )) ` if a function was found . Returns ` Ok ( None ) ` if the address was outside of the range of addresses covered by the unwind info . Returns ` Err ( error ) ` if there was a problem with the format of the ` __unwind_info ` data . This lookup is architecture agnostic . The opcode is returned as a u32 . To actually perform unwinding the opcode needs to be parsed in an architecture - specific manner . The design of the compact unwinding format makes this lookup extremely cheap . It ' s just two binary searches : First to find the right page end then to find the right function within a page . The search happens inside the wrapped data with no extra copies .
pub fn lookup(&self, pc: u32) -> Result<Option<Function>, Error> {
        let Self {
            pages,
            data,
            global_opcodes,
        } = self;
        let page_index = match pages.binary_search_by_key(&pc, PageEntry::first_address) {
            Ok(i) => i,
            Err(insertion_index) => {
                if insertion_index == 0 {
                    return Ok(None);
                }
                insertion_index - 1
            }
        };
        if page_index == pages.len() - 1 {
            // We found the sentinel last page, which just marks the end of the range.
            // So the looked up address is at or after the end address, i.e. outside the
            // range of addresses covered by this UnwindInfo.
            return Ok(None);
        }
        let page_entry = &pages[page_index];
        let next_page_entry = &pages[page_index + 1];
        let page_offset = page_entry.page_offset();
        match page_entry.page_kind(data)? {
            consts::PAGE_KIND_REGULAR => {
                let page = RegularPage::parse(data, page_offset.into())?;
                let functions = page.functions(data, page_offset)?;
                let function_index =
                    match functions.binary_search_by_key(&pc, RegularFunctionEntry::address) {
                        Ok(i) => i,
                        Err(insertion_index) => {
                            if insertion_index == 0 {
                                return Err(Error::InvalidPageEntryFirstAddress);
                            }
                            insertion_index - 1
                        }
                    };
                let entry = &functions[function_index];
                let fun_address = entry.address();
                let next_fun_address = if let Some(next_entry) = functions.get(function_index + 1) {
                    next_entry.address()
                } else {
                    next_page_entry.first_address()
                };
                Ok(Some(Function {
                    start_address: fun_address,
                    end_address: next_fun_address,
                    opcode: entry.opcode(),
                }))
            }
            consts::PAGE_KIND_COMPRESSED => {
                let page = CompressedPage::parse(data, page_offset.into())?;
                let functions = page.functions(data, page_offset)?;
                let page_address = page_entry.first_address();
                let rel_pc = pc - page_address;
                let function_index = match functions.binary_search_by_key(&rel_pc, |&entry| {
                    CompressedFunctionEntry::new(entry.into()).relative_address()
                }) {
                    Ok(i) => i,
                    Err(insertion_index) => {
                        if insertion_index == 0 {
                            return Err(Error::InvalidPageEntryFirstAddress);
                        }
                        insertion_index - 1
                    }
                };
                let entry = CompressedFunctionEntry::new(functions[function_index].into());
                let fun_address = page_address + entry.relative_address();
                let next_fun_address = if let Some(next_entry) = functions.get(function_index + 1) {
                    let next_entry = CompressedFunctionEntry::new((*next_entry).into());
                    page_address + next_entry.relative_address()
                } else {
                    next_page_entry.first_address()
                };
                let opcode_index: usize = entry.opcode_index().into();
                let opcode = if opcode_index < global_opcodes.len() {
                    global_opcodes[opcode_index].opcode()
                } else {
                    let local_opcodes = page.local_opcodes(data, page_offset)?;
                    let local_index = opcode_index - global_opcodes.len();
                    local_opcodes[local_index].opcode()
                };
                Ok(Some(Function {
                    start_address: fun_address,
                    end_address: next_fun_address,
                    opcode,
                }))
            }
            consts::PAGE_KIND_SENTINEL => {
                // Only the last page should be a sentinel page, and we've already checked earlier
                // that we're not in the last page.
                Err(Error::UnexpectedSentinelPage)
            }
            _ => Err(Error::InvalidPageKind),
        }
    }
pub fn lookup ( & self , pc : u32 ) -> Result < Option < Function > , Error > { let Self { pages , data , global_opcodes , } = self ; let page_index = match pages . binary_search_by_key ( & pc , PageEntry :: first_address ) { Ok ( i ) => i , Err ( insertion_index ) => { if insertion_index == 0 { return Ok ( None ) ; } insertion_index - 1 } } ; if page_index == pages . len ( ) - 1 { // We found the sentinel last page, which just marks the end of the range. // So the looked up address is at or after the end address, i.e. outside the // range of addresses covered by this UnwindInfo. return Ok ( None ) ; } let page_entry = & pages [ page_index ] ; let next_page_entry = & pages [ page_index + 1 ] ; let page_offset = page_entry . page_offset ( ) ; match page_entry . page_kind ( data ) ? { consts :: PAGE_KIND_REGULAR => { let page = RegularPage :: parse ( data , page_offset . into ( ) ) ? ; let functions = page . functions ( data , page_offset ) ? ; let function_index = match functions . binary_search_by_key ( & pc , RegularFunctionEntry :: address ) { Ok ( i ) => i , Err ( insertion_index ) => { if insertion_index == 0 { return Err ( Error :: InvalidPageEntryFirstAddress ) ; } insertion_index - 1 } } ; let entry = & functions [ function_index ] ; let fun_address = entry . address ( ) ; let next_fun_address = if let Some ( next_entry ) = functions . get ( function_index + 1 ) { next_entry . address ( ) } else { next_page_entry . first_address ( ) } ; Ok ( Some ( Function { start_address : fun_address , end_address : next_fun_address , opcode : entry . opcode ( ) , } ) ) } consts :: PAGE_KIND_COMPRESSED => { let page = CompressedPage :: parse ( data , page_offset . into ( ) ) ? ; let functions = page . functions ( data , page_offset ) ? ; let page_address = page_entry . first_address ( ) ; let rel_pc = pc - page_address ; let function_index = match functions . binary_search_by_key ( & rel_pc , | & entry | { CompressedFunctionEntry :: new ( entry . into ( ) ) . relative_address ( ) } ) { Ok ( i ) => i , Err ( insertion_index ) => { if insertion_index == 0 { return Err ( Error :: InvalidPageEntryFirstAddress ) ; } insertion_index - 1 } } ; let entry = CompressedFunctionEntry :: new ( functions [ function_index ] . into ( ) ) ; let fun_address = page_address + entry . relative_address ( ) ; let next_fun_address = if let Some ( next_entry ) = functions . get ( function_index + 1 ) { let next_entry = CompressedFunctionEntry :: new ( ( * next_entry ) . into ( ) ) ; page_address + next_entry . relative_address ( ) } else { next_page_entry . first_address ( ) } ; let opcode_index : usize = entry . opcode_index ( ) . into ( ) ; let opcode = if opcode_index < global_opcodes . len ( ) { global_opcodes [ opcode_index ] . opcode ( ) } else { let local_opcodes = page . local_opcodes ( data , page_offset ) ? ; let local_index = opcode_index - global_opcodes . len ( ) ; local_opcodes [ local_index ] . opcode ( ) } ; Ok ( Some ( Function { start_address : fun_address , end_address : next_fun_address , opcode , } ) ) } consts :: PAGE_KIND_SENTINEL => { // Only the last page should be a sentinel page, and we've already checked earlier // that we're not in the last page. Err ( Error :: UnexpectedSentinelPage ) } _ => Err ( Error :: InvalidPageKind ) , } }
Looks up the unwind information for the function that covers the given address.
Looks up the unwind information for the function that covers the given address .
&self
pc
u32
&self
pc
u32