Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/aarch64/unwinder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ impl<D: Deref<Target = [u8]>, P: AllocationPolicy> Unwinder for UnwinderAarch64<
self.0.max_known_code_address()
}

fn is_address_in_module(&self, address: u64) -> bool {
self.0.is_address_in_module(address)
}

fn unwind_frame<F>(
&self,
address: FrameAddress,
Expand Down
14 changes: 14 additions & 0 deletions src/unwinder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ pub trait Unwinder: Clone {
/// to make an educated guess at a pointer authentication mask for Aarch64 return addresses.
fn max_known_code_address(&self) -> u64;

/// Returns whether `address` falls within the address range of any known
/// module, i.e. whether it points into code we have a module for.
///
/// A genuine code address (an instruction pointer or a return address)
/// always lies in a known module. This lets a caller reject frames produced
/// by unreliable unwinding — e.g. frame-pointer walks over code without
/// unwind info, which can mistake a stack-local value for a saved return
/// address — that would otherwise surface as unresolved root frames.
fn is_address_in_module(&self, address: u64) -> bool;

/// Unwind a single frame, to recover return address and caller register values.
/// This is the main entry point for unwinding.
fn unwind_frame<F>(
Expand Down Expand Up @@ -284,6 +294,10 @@ impl<D: Deref<Target = [u8]>, A: Unwinding, P: AllocationPolicy> UnwinderInterna
self.modules.last().map_or(0, |m| m.avma_range.end)
}

pub fn is_address_in_module(&self, address: u64) -> bool {
self.find_module_for_address(address).is_some()
}

fn find_module_for_address(&self, address: u64) -> Option<(usize, u32)> {
let (module_index, module) = match self
.modules
Expand Down
4 changes: 4 additions & 0 deletions src/x86_64/unwinder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ impl<D: Deref<Target = [u8]>, P: AllocationPolicy> Unwinder for UnwinderX86_64<D
self.0.max_known_code_address()
}

fn is_address_in_module(&self, address: u64) -> bool {
self.0.is_address_in_module(address)
}

fn unwind_frame<F>(
&self,
address: FrameAddress,
Expand Down