From 5baf0dcdaef4eefb32dbf9881150098b1233d782 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Sat, 5 Aug 2023 20:44:54 +0800 Subject: [PATCH] find_fde: make `text_base` optional No platforms currently use relative addressing. Make this parameter optional in order to support targets where this value is not available. Signed-off-by: Sean Cross --- src/unwinder/find_fde/custom.rs | 53 ++++++++++++++------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/src/unwinder/find_fde/custom.rs b/src/unwinder/find_fde/custom.rs index cf9883d..7f89590 100644 --- a/src/unwinder/find_fde/custom.rs +++ b/src/unwinder/find_fde/custom.rs @@ -1,6 +1,7 @@ use super::{FDEFinder, FDESearchResult}; use crate::util::{deref_pointer, get_unlimited_slice}; +use core::num::NonZeroUsize; use core::sync::atomic::{AtomicU32, Ordering}; use gimli::{BaseAddresses, EhFrame, EhFrameHdr, NativeEndian, UnwindSection}; @@ -22,7 +23,7 @@ pub unsafe trait EhFrameFinder { } pub struct FrameInfo { - pub text_base: usize, + pub text_base: Option, pub kind: FrameInfoKind, } @@ -102,19 +103,18 @@ fn find_fde(eh_frame_finder: &T, pc: usize) -> Option fn find_fde_with_eh_frame_hdr( pc: usize, - text_base: usize, + text_base: Option, eh_frame_hdr: usize, ) -> Option { unsafe { - let bases = BaseAddresses::default() - .set_text(text_base as _) - .set_eh_frame_hdr(eh_frame_hdr as _); - let eh_frame_hdr = EhFrameHdr::new( - get_unlimited_slice(eh_frame_hdr as usize as _), - NativeEndian, - ) - .parse(&bases, core::mem::size_of::() as _) - .ok()?; + let mut bases = BaseAddresses::default().set_eh_frame_hdr(eh_frame_hdr as _); + if let Some(text_base) = text_base { + bases = bases.set_text(text_base.get() as _); + } + let eh_frame_hdr = + EhFrameHdr::new(get_unlimited_slice(eh_frame_hdr as usize as _), NativeEndian) + .parse(&bases, core::mem::size_of::() as _) + .ok()?; let eh_frame = deref_pointer(eh_frame_hdr.eh_frame_ptr()); let bases = bases.set_eh_frame(eh_frame as _); let eh_frame = EhFrame::new(get_unlimited_slice(eh_frame as _), NativeEndian); @@ -124,40 +124,33 @@ fn find_fde_with_eh_frame_hdr( if let Ok(fde) = table.fde_for_address(&eh_frame, &bases, pc as _, EhFrame::cie_from_offset) { - return Some(FDESearchResult { - fde, - bases, - eh_frame, - }); + return Some(FDESearchResult { fde, bases, eh_frame }); } } // Otherwise do the linear search. if let Ok(fde) = eh_frame.fde_for_address(&bases, pc as _, EhFrame::cie_from_offset) { - return Some(FDESearchResult { - fde, - bases, - eh_frame, - }); + return Some(FDESearchResult { fde, bases, eh_frame }); } None } } -fn find_fde_with_eh_frame(pc: usize, text_base: usize, eh_frame: usize) -> Option { +fn find_fde_with_eh_frame( + pc: usize, + text_base: Option, + eh_frame: usize, +) -> Option { unsafe { - let bases = BaseAddresses::default() - .set_text(text_base as _) - .set_eh_frame(eh_frame as _); + let mut bases = BaseAddresses::default().set_eh_frame(eh_frame as _); + if let Some(text_base) = text_base { + bases = bases.set_text(text_base.get() as _); + } let eh_frame = EhFrame::new(get_unlimited_slice(eh_frame as _), NativeEndian); if let Ok(fde) = eh_frame.fde_for_address(&bases, pc as _, EhFrame::cie_from_offset) { - return Some(FDESearchResult { - fde, - bases, - eh_frame, - }); + return Some(FDESearchResult { fde, bases, eh_frame }); } None