framehop/x86_64/
unwinder.rs

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