Skip to content
This repository was archived by the owner on Mar 24, 2022. It is now read-only.

Commit 6ddb7a3

Browse files
committed
forced unwinding of guests has had its assumptions challenged
when forced unwinding was first envisioned, guests did not run at all from the point they faulted. this mean that the fault address would be a simple `guest_ctx.get_ip()` away. in the mean time, the Lucet signal handler learning how to be crossplatform broke this assumption: it now works by *overwriting* the guest's instruction pointer, swapping to the guest, and letting a function run. consequently, the guest instruction pointer is replaced and when a guest unwind is instigated after a guest faults, the return address before `initiate_unwind` (or `unwind_stub`, if present) will no longer be correct. libgcc_s will then fail to locate an FDE to describe the call frame above runtime-added unwind machinery, fail to unwind, and SIGABRT. the solution is quite simple: since the rip-accessing code is already handling a guest fault, we know the original faulting guest `rip` is preserved in the fault's `details`. insted of `guest_ctx.get_ip()`, get the address from `details.rip_addr`.
1 parent 0d9db26 commit 6ddb7a3

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

lucet-runtime/lucet-runtime-internals/src/instance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ impl Instance {
12771277
Ok(_) => lucet_bail!("resume with forced unwind returned normally"),
12781278
}
12791279
}
1280-
State::Faulted { context, .. } => {
1280+
State::Faulted { context, details, .. } => {
12811281
#[unwind(allowed)]
12821282
extern "C" fn initiate_unwind() {
12831283
panic!(TerminationDetails::ForcedUnwind);
@@ -1287,7 +1287,7 @@ impl Instance {
12871287
context.as_ptr().save_to_context(&mut self.ctx);
12881288

12891289
// get the instruction pointer when the fault was raised
1290-
let guest_addr = context.as_ptr().get_ip();
1290+
let guest_addr = details.rip_addr;
12911291

12921292
// if we should unwind by returning into the guest to cause a fault, do so with the redzone
12931293
// available in case the guest was at or close to overflowing.

0 commit comments

Comments
 (0)