瀏覽代碼

Add a cdylib target

Gary Guo 3 年之前
父節點
當前提交
f76376c101
共有 5 個文件被更改,包括 115 次插入2 次删除
  1. 3 0
      Cargo.toml
  2. 12 0
      cdylib/Cargo.toml
  3. 96 0
      cdylib/src/lib.rs
  4. 2 2
      src/find_fde/registry.rs
  5. 2 0
      src/lib.rs

+ 3 - 0
Cargo.toml

@@ -4,6 +4,9 @@ version = "0.1.0"
 authors = ["Gary Guo <gary@garyguo.net>"]
 edition = "2018"
 
+[workspace]
+members = ["cdylib"]
+
 [dependencies]
 gimli = { version = "0.25.0", default-features = false, features = ["read"] }
 libc = { version = "0.2", optional = true }

+ 12 - 0
cdylib/Cargo.toml

@@ -0,0 +1,12 @@
+[package]
+name = "unwind_dyn"
+version = "0.1.0"
+authors = ["Gary Guo <gary@garyguo.net>"]
+edition = "2018"
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+unwind = { path = "../", features = ["fde-registry"] }
+libc = "0.2"

+ 96 - 0
cdylib/src/lib.rs

@@ -0,0 +1,96 @@
+#![no_std]
+#![feature(default_alloc_error_handler)]
+#![feature(lang_items)]
+#![warn(rust_2018_idioms)]
+#![warn(unsafe_op_in_unsafe_fn)]
+
+// Keep this explicit
+#[allow(unused_extern_crates)]
+extern crate unwind;
+
+use core::alloc::{GlobalAlloc, Layout};
+use core::panic::PanicInfo;
+use core::{cmp, mem, ptr};
+use libc::c_int;
+use unwind::*;
+
+pub struct System;
+
+const MIN_ALIGN: usize = mem::size_of::<usize>() * 2;
+
+// Taken std
+unsafe impl GlobalAlloc for System {
+    #[inline]
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
+            unsafe { libc::malloc(layout.size()) as *mut u8 }
+        } else {
+            let mut out = ptr::null_mut();
+            let align = layout.align().max(mem::size_of::<usize>());
+            let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
+            if ret != 0 {
+                ptr::null_mut()
+            } else {
+                out as *mut u8
+            }
+        }
+    }
+
+    #[inline]
+    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
+            unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
+        } else {
+            let ptr = unsafe { self.alloc(layout) };
+            if !ptr.is_null() {
+                unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
+            }
+            ptr
+        }
+    }
+
+    #[inline]
+    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
+        unsafe { libc::free(ptr as *mut libc::c_void) }
+    }
+
+    #[inline]
+    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+        if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
+            unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
+        } else {
+            let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
+
+            let new_ptr = unsafe { self.alloc(new_layout) };
+            if !new_ptr.is_null() {
+                let size = cmp::min(layout.size(), new_size);
+                unsafe { ptr::copy_nonoverlapping(ptr, new_ptr, size) };
+                unsafe { self.dealloc(ptr, layout) };
+            }
+            new_ptr
+        }
+    }
+}
+
+#[global_allocator]
+static GLOBAL: System = System;
+
+#[panic_handler]
+fn panic(_info: &PanicInfo<'_>) -> ! {
+    // `unwind` crate should never panic.
+    unsafe { core::hint::unreachable_unchecked() }
+}
+
+#[lang = "eh_personality"]
+extern "C" fn personality(
+    version: c_int,
+    _actions: UnwindAction,
+    _exception_class: u64,
+    _exception: &mut UnwindException,
+    _ctx: &mut UnwindContext<'_>,
+) -> UnwindReasonCode {
+    if version != 1 {
+        return UnwindReasonCode::FATAL_PHASE1_ERROR;
+    }
+    UnwindReasonCode::CONTINUE_UNWIND
+}

+ 2 - 2
src/find_fde/registry.rs

@@ -76,8 +76,8 @@ pub fn get_finder() -> &'static Registry {
 impl super::FDEFinder for Registry {
     fn find_fde(&self, pc: usize) -> Option<FDESearchResult> {
         unsafe {
-        let guard = lock_global_state();
-        let mut cur = guard.object;
+            let guard = lock_global_state();
+            let mut cur = guard.object;
 
             while !cur.is_null() {
                 let bases = BaseAddresses::default()

+ 2 - 0
src/lib.rs

@@ -13,3 +13,5 @@ mod arch;
 mod find_fde;
 mod frame;
 mod util;
+
+pub use abi::*;