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

Commit 23c9721

Browse files
acfoltzeriximeow
authored andcommitted
simplify unwinding implementation by using Faulted state
This state already had the context information we needed to initiate unwinding, so we didn't need to add an extra field on our `Context`, or preemptively overwrite the guest context in the signal handler
1 parent b3e289d commit 23c9721

4 files changed

Lines changed: 16 additions & 20 deletions

File tree

lucet-runtime/lucet-runtime-internals/src/context/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ pub struct Context {
125125
backstop_callback: *const unsafe extern "C" fn(*mut Instance),
126126
backstop_data: *mut Instance,
127127
sigset: signal::SigSet,
128-
pub(crate) stop_addr: Option<u64>,
129128
}
130129

131130
impl Context {
@@ -140,7 +139,6 @@ impl Context {
140139
backstop_callback: Context::default_backstop_callback as *const _,
141140
backstop_data: ptr::null_mut(),
142141
sigset: signal::SigSet::empty(),
143-
stop_addr: None,
144142
}
145143
}
146144
}

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

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,20 +1077,21 @@ impl Instance {
10771077
Ok(_) => lucet_bail!("resume with forced unwind returned normally"),
10781078
}
10791079
}
1080-
State::Faulted { .. } => {
1080+
State::Faulted { context, .. } => {
1081+
#[unwind(allowed)]
1082+
extern "C" fn initiate_unwind() {
1083+
panic!(TerminationDetails::ForcedUnwind);
1084+
}
1085+
1086+
// set up the guest context as it was when the fault was raised
1087+
context.as_ptr().save_to_context(&mut self.ctx);
1088+
1089+
// get the instruction pointer when the fault was raised
1090+
let guest_addr = context.as_ptr().get_ip();
1091+
10811092
// if we should unwind by returning into the guest to cause a fault, do so with the redzone
10821093
// available in case the guest was at or close to overflowing.
10831094
self.with_redzone_stack(|inst| {
1084-
#[unwind(allowed)]
1085-
extern "C" fn initiate_unwind() {
1086-
panic!(TerminationDetails::ForcedUnwind);
1087-
}
1088-
1089-
let guest_addr = inst
1090-
.ctx
1091-
.stop_addr
1092-
.expect("guest that stopped in guest code has an address it stopped at");
1093-
10941095
// set up the faulting instruction pointer as the return address for `initiate_unwind`;
10951096
// extremely unsafe, doesn't handle any edge cases yet
10961097
//
@@ -1148,22 +1149,19 @@ impl Instance {
11481149
inst.push(initiate_unwind as u64)
11491150
.expect("stack has available space");
11501151

1151-
inst.state = State::Ready;
1152-
11531152
match inst.swap_and_return() {
11541153
Ok(_) => panic!("forced unwinding shouldn't return normally"),
11551154
Err(Error::RuntimeTerminated(TerminationDetails::ForcedUnwind)) => (),
11561155
Err(e) => panic!("unexpected error: {}", e),
11571156
}
11581157

11591158
// we've unwound the stack, so we know there are no longer any host frames.
1160-
// inst.hostcall_count = 0;
1161-
inst.ctx.stop_addr = None;
1159+
debug_assert_eq!(inst.hostcall_count, 0);
11621160

11631161
Ok(())
11641162
})
11651163
}
1166-
st => panic!("should never do forced unwinding in this state: {}", st),
1164+
st => lucet_bail!("should never do forced unwinding in this state: {}", st),
11671165
}
11681166
}
11691167
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ extern "C" fn handle_signal(signum: c_int, siginfo_ptr: *mut siginfo_t, ucontext
196196
let trapcode = inst.module.lookup_trapcode(rip);
197197

198198
let behavior = (inst.signal_handler)(inst, &trapcode, signum, siginfo_ptr, ucontext_ptr);
199-
let switch_to_host = match behavior {
199+
match behavior {
200200
SignalBehavior::Continue => {
201201
// return to the guest context without making any modifications to the instance
202202
false

lucet-runtime/lucet-runtime-internals/src/sysdeps/linux.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl UContext {
7676
}
7777
}
7878

79-
pub fn as_ptr(&mut self) -> UContextPtr {
79+
pub fn as_ptr(&self) -> UContextPtr {
8080
UContextPtr::new(&self.context as *const _ as *const _)
8181
}
8282
}

0 commit comments

Comments
 (0)