1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#[cfg(feature = "fde-custom")]
mod custom;
#[cfg(feature = "fde-static")]
mod fixed;
#[cfg(feature = "fde-gnu-eh-frame-hdr")]
mod gnu_eh_frame_hdr;
#[cfg(feature = "fde-phdr")]
mod phdr;
#[cfg(feature = "fde-registry")]
mod registry;

use crate::util::*;
use gimli::{BaseAddresses, EhFrame, FrameDescriptionEntry};

#[cfg(feature = "fde-custom")]
pub mod custom_eh_frame_finder {
    pub use super::custom::{
        set_custom_eh_frame_finder, EhFrameFinder, FrameInfo, FrameInfoKind,
        SetCustomEhFrameFinderError,
    };
}

#[derive(Debug)]
pub struct FDESearchResult {
    pub fde: FrameDescriptionEntry<StaticSlice>,
    pub bases: BaseAddresses,
    pub eh_frame: EhFrame<StaticSlice>,
}

pub trait FDEFinder {
    fn find_fde(&self, pc: usize) -> Option<FDESearchResult>;
}

pub struct GlobalFinder(());

impl FDEFinder for GlobalFinder {
    fn find_fde(&self, pc: usize) -> Option<FDESearchResult> {
        #[cfg(feature = "fde-custom")]
        if let Some(v) = custom::get_finder().find_fde(pc) {
            return Some(v);
        }
        #[cfg(feature = "fde-registry")]
        if let Some(v) = registry::get_finder().find_fde(pc) {
            return Some(v);
        }
        #[cfg(feature = "fde-gnu-eh-frame-hdr")]
        if let Some(v) = gnu_eh_frame_hdr::get_finder().find_fde(pc) {
            return Some(v);
        }
        #[cfg(feature = "fde-phdr")]
        if let Some(v) = phdr::get_finder().find_fde(pc) {
            return Some(v);
        }
        #[cfg(feature = "fde-static")]
        if let Some(v) = fixed::get_finder().find_fde(pc) {
            return Some(v);
        }
        None
    }
}

pub fn get_finder() -> &'static GlobalFinder {
    &GlobalFinder(())
}