framehop/aarch64/
unwinder.rs

1use core::ops::Deref;
2
3use crate::{
4    unwinder::UnwinderInternal, AllocationPolicy, Error, FrameAddress, MayAllocateDuringUnwind,
5    Module, Unwinder,
6};
7
8use super::{ArchAarch64, CacheAarch64, UnwindRegsAarch64};
9
10/// The unwinder for the Aarch64 CPU architecture. Use the [`Unwinder`] trait for unwinding.
11///
12/// Type arguments:
13///
14///  - `D`: The type for unwind section data in the modules. See [`Module`].
15/// -  `P`: The [`AllocationPolicy`].
16pub struct UnwinderAarch64<D, P = MayAllocateDuringUnwind>(UnwinderInternal<D, ArchAarch64, P>);
17
18impl<D, P> Default for UnwinderAarch64<D, P> {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl<D, P> Clone for UnwinderAarch64<D, P> {
25    fn clone(&self) -> Self {
26        Self(self.0.clone())
27    }
28}
29
30impl<D, P> UnwinderAarch64<D, P> {
31    /// Create an unwinder for a process.
32    pub fn new() -> Self {
33        Self(UnwinderInternal::new())
34    }
35}
36
37impl<D: Deref<Target = [u8]>, P: AllocationPolicy> Unwinder for UnwinderAarch64<D, P> {
38    type UnwindRegs = UnwindRegsAarch64;
39    type Cache = CacheAarch64<P>;
40    type Module = Module<D>;
41
42    fn add_module(&mut self, module: Module<D>) {
43        self.0.add_module(module);
44    }
45
46    fn remove_module(&mut self, module_address_range_start: u64) {
47        self.0.remove_module(module_address_range_start);
48    }
49
50    fn max_known_code_address(&self) -> u64 {
51        self.0.max_known_code_address()
52    }
53
54    fn unwind_frame<F>(
55        &self,
56        address: FrameAddress,
57        regs: &mut UnwindRegsAarch64,
58        cache: &mut CacheAarch64<P>,
59        read_stack: &mut F,
60    ) -> Result<Option<u64>, Error>
61    where
62        F: FnMut(u64) -> Result<u64, ()>,
63    {
64        self.0.unwind_frame(address, regs, &mut cache.0, read_stack)
65    }
66}