]> git.lizzy.rs Git - rust.git/blobdiff - src/shims/backtrace.rs
Add an `fn_ptr` field to `MiriFrame`
[rust.git] / src / shims / backtrace.rs
index bd36587116a06f5822b2da1c30fff69b62b88177..9b396c718493fc2a54892ac7215d4a751563819a 100644 (file)
@@ -92,8 +92,18 @@ fn handle_miri_resolve_frame(
             throw_ub_format!("expected function pointer, found {:?}", ptr);
         };
 
-        if dest.layout.layout.fields.count() != 4 {
-            throw_ub_format!("bad declaration of miri_resolve_frame - should return a struct with 4 fields");
+        // Reconstruct the original function pointer,
+        // which we pass to user code.
+        let mut fn_ptr = ptr;
+        fn_ptr.offset = Size::from_bytes(0);
+        let fn_ptr = Scalar::Ptr(fn_ptr);
+
+        let num_fields = dest.layout.layout.fields.count();
+
+        if num_fields != 4 && num_fields != 5 {
+            // Always mention 5 fields, since the 4-field struct is only supported
+            // for backwards compatiblity. New code should declare 5 fields
+            throw_ub_format!("bad declaration of miri_resolve_frame - should return a struct with 5 fields");
         }
 
         let pos = BytePos(ptr.offset.bytes().try_into().unwrap());
@@ -122,6 +132,11 @@ fn handle_miri_resolve_frame(
         this.write_immediate(filename_alloc.to_ref(), this.mplace_field(dest, 1)?.into())?;
         this.write_scalar(lineno_alloc, this.mplace_field(dest, 2)?.into())?;
         this.write_scalar(colno_alloc, this.mplace_field(dest, 3)?.into())?;
+
+        if num_fields == 5 {
+            this.write_scalar(fn_ptr, this.mplace_field(dest, 4)?.into())?;
+        }
+
         Ok(())
     }
 }