about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSean Cross <sean@xobs.io>2023-10-23 15:48:54 +0800
committerSean Cross <sean@xobs.io>2023-12-06 09:07:07 +0800
commita6b8de68a6322dd18a3f7de9c921af091279e2fe (patch)
tree229bd96ae7ba47a724428a6605807ee248271b17
parent2a533df5bd5e85cdcc3eba23a1a1545b10af1e0f (diff)
downloadrust-a6b8de68a6322dd18a3f7de9c921af091279e2fe.tar.gz
rust-a6b8de68a6322dd18a3f7de9c921af091279e2fe.zip
std: xous: take eh_frame address from main args
The main() function takes an argument that contains the eh_frame
address. Implement `unwinding` support by looking for unwinding data at
this address.

Signed-off-by: Sean Cross <sean@xobs.io>
-rw-r--r--library/std/src/sys/xous/os.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/library/std/src/sys/xous/os.rs b/library/std/src/sys/xous/os.rs
index 3d19fa4b31a..8d2eaee8aa6 100644
--- a/library/std/src/sys/xous/os.rs
+++ b/library/std/src/sys/xous/os.rs
@@ -8,6 +8,28 @@ use crate::os::xous::ffi::Error as XousError;
 use crate::path::{self, PathBuf};
 
 #[cfg(not(test))]
+#[cfg(feature = "panic_unwind")]
+mod eh_unwinding {
+    pub(crate) struct EhFrameFinder(usize /* eh_frame */);
+    pub(crate) static mut EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder(0);
+    impl EhFrameFinder {
+        pub(crate) unsafe fn init(&mut self, eh_frame: usize) {
+            unsafe {
+                EH_FRAME_SETTINGS.0 = eh_frame;
+            }
+        }
+    }
+    unsafe impl unwind::EhFrameFinder for EhFrameFinder {
+        fn find(&self, _pc: usize) -> Option<unwind::FrameInfo> {
+            Some(unwind::FrameInfo {
+                text_base: None,
+                kind: unwind::FrameInfoKind::EhFrame(self.0),
+            })
+        }
+    }
+}
+
+#[cfg(not(test))]
 mod c_compat {
     use crate::os::xous::ffi::exit;
     extern "C" {
@@ -20,7 +42,12 @@ mod c_compat {
     }
 
     #[no_mangle]
-    pub extern "C" fn _start() {
+    pub extern "C" fn _start(eh_frame: usize) {
+        #[cfg(feature = "panic_unwind")]
+        unsafe {
+            super::eh_unwinding::EH_FRAME_SETTINGS.init(eh_frame);
+            unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok();
+        }
         exit(unsafe { main() });
     }