]> git.lizzy.rs Git - rust.git/blobdiff - src/debuginfo/unwind.rs
Update Cranelift
[rust.git] / src / debuginfo / unwind.rs
index a0f933d7c62b1b33ab78e2deca15034cf0774e72..dc630fa5fd421afaade48a8f2c43bfb7e3bdad7b 100644 (file)
@@ -1,6 +1,8 @@
+//! Unwind info generation (`.eh_frame`)
+
 use crate::prelude::*;
 
-use cranelift_codegen::isa::{TargetIsa, unwind::UnwindInfo};
+use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
 
 use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
 
@@ -13,14 +15,14 @@ pub(crate) struct UnwindContext<'tcx> {
 }
 
 impl<'tcx> UnwindContext<'tcx> {
-    pub(crate) fn new(
-        tcx: TyCtxt<'tcx>,
-        module: &mut Module<impl Backend>,
-    ) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, isa: &dyn TargetIsa) -> Self {
         let mut frame_table = FrameTable::default();
 
-
-        let cie_id = if let Some(cie) = module.isa().create_systemv_cie() {
+        let cie_id = if let Some(mut cie) = isa.create_systemv_cie() {
+            if isa.flags().is_pic() {
+                cie.fde_address_encoding =
+                    gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0);
+            }
             Some(frame_table.add_cie(cie))
         } else {
             None
@@ -42,19 +44,25 @@ pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &
 
         match unwind_info {
             UnwindInfo::SystemV(unwind_info) => {
-                self.frame_table.add_fde(self.cie_id.unwrap(), unwind_info.to_fde(Address::Symbol {
-                    symbol: func_id.as_u32() as usize,
-                    addend: 0,
-                }));
-            },
+                self.frame_table.add_fde(
+                    self.cie_id.unwrap(),
+                    unwind_info.to_fde(Address::Symbol {
+                        symbol: func_id.as_u32() as usize,
+                        addend: 0,
+                    }),
+                );
+            }
             UnwindInfo::WindowsX64(_) => {
                 // FIXME implement this
             }
+            unwind_info => unimplemented!("{:?}", unwind_info),
         }
     }
 
     pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
-        let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
+        let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(
+            self.tcx,
+        )));
         self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
 
         if !eh_frame.0.writer.slice().is_empty() {
@@ -69,11 +77,14 @@ pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
         }
     }
 
+    #[cfg(feature = "jit")]
     pub(crate) unsafe fn register_jit(
         self,
-        jit_module: &mut Module<cranelift_simplejit::SimpleJITBackend>,
+        jit_module: &cranelift_jit::JITModule,
     ) -> Option<UnwindRegistry> {
-        let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
+        let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(
+            self.tcx,
+        )));
         self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
 
         if eh_frame.0.writer.slice().is_empty() {
@@ -90,33 +101,34 @@ pub(crate) unsafe fn register_jit(
         // =======================================================================
         // Everything after this line up to the end of the file is loosly based on
         // https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs
-        cfg_if::cfg_if! {
-            if #[cfg(target_os = "macos")] {
-                // On macOS, `__register_frame` takes a pointer to a single FDE
-                let start = eh_frame.as_ptr();
-                let end = start.add(eh_frame.len());
-                let mut current = start;
-
-                // Walk all of the entries in the frame table and register them
-                while current < end {
-                    let len = std::ptr::read::<u32>(current as *const u32) as usize;
-
-                    // Skip over the CIE
-                    if current != start {
-                        __register_frame(current);
-                        registrations.push(current as usize);
-                    }
-
-                    // Move to the next table entry (+4 because the length itself is not inclusive)
-                    current = current.add(len + 4);
+        #[cfg(target_os = "macos")]
+        {
+            // On macOS, `__register_frame` takes a pointer to a single FDE
+            let start = eh_frame.as_ptr();
+            let end = start.add(eh_frame.len());
+            let mut current = start;
+
+            // Walk all of the entries in the frame table and register them
+            while current < end {
+                let len = std::ptr::read::<u32>(current as *const u32) as usize;
+
+                // Skip over the CIE
+                if current != start {
+                    __register_frame(current);
+                    registrations.push(current as usize);
                 }
-            } else {
-                // On other platforms, `__register_frame` will walk the FDEs until an entry of length 0
-                let ptr = eh_frame.as_ptr();
-                __register_frame(ptr);
-                registrations.push(ptr as usize);
+
+                // Move to the next table entry (+4 because the length itself is not inclusive)
+                current = current.add(len + 4);
             }
         }
+        #[cfg(not(target_os = "macos"))]
+        {
+            // On other platforms, `__register_frame` will walk the FDEs until an entry of length 0
+            let ptr = eh_frame.as_ptr();
+            __register_frame(ptr);
+            registrations.push(ptr as usize);
+        }
 
         Some(UnwindRegistry {
             _frame_table: eh_frame,