Bläddra i källkod

Static FDE searcher

Gary Guo 3 år sedan
förälder
incheckning
f4dd644e67
3 ändrade filer med 51 tillägg och 0 borttagningar
  1. 1 0
      Cargo.toml
  2. 44 0
      src/unwinder/find_fde/fixed.rs
  3. 6 0
      src/unwinder/find_fde/mod.rs

+ 1 - 0
Cargo.toml

@@ -17,6 +17,7 @@ alloc = []
 unwinder = []
 fde-phdr = ["libc"]
 fde-registry = ["alloc"]
+fde-static = []
 dwarf-expr = []
 hide-trace = []
 personality = []

+ 44 - 0
src/unwinder/find_fde/fixed.rs

@@ -0,0 +1,44 @@
+use super::FDESearchResult;
+use crate::util::*;
+
+use gimli::{BaseAddresses, EhFrame, NativeEndian, UnwindSection};
+
+pub struct StaticFinder(());
+
+pub fn get_finder() -> &'static StaticFinder {
+    &StaticFinder(())
+}
+
+extern "C" {
+    static __executable_start: u8;
+    static __etext: u8;
+    static __eh_frame: u8;
+}
+
+impl super::FDEFinder for StaticFinder {
+    fn find_fde(&self, pc: usize) -> Option<FDESearchResult> {
+        unsafe {
+            let text_start = &__executable_start as *const u8 as usize;
+            let text_end = &__etext as *const u8 as usize;
+            if !(text_start..text_end).contains(&pc) {
+                return None;
+            }
+
+            let eh_frame = &__eh_frame as *const u8 as usize;
+            let bases = BaseAddresses::default()
+                .set_eh_frame(eh_frame as _)
+                .set_text(text_start 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,
+                });
+            }
+
+            None
+        }
+    }
+}

+ 6 - 0
src/unwinder/find_fde/mod.rs

@@ -1,3 +1,5 @@
+#[cfg(feature = "fde-static")]
+mod fixed;
 #[cfg(feature = "fde-phdr")]
 mod phdr;
 #[cfg(feature = "fde-registry")]
@@ -29,6 +31,10 @@ impl FDEFinder for GlobalFinder {
         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
     }
 }