This repository was archived by the owner on Mar 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 167
Multiplatform signals #437
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| use crate::alloc::validate_sigstack_size; | ||
| use crate::context::Context; | ||
| use crate::error::Error; | ||
| use crate::instance::{ | ||
| siginfo_ext::SiginfoExt, FaultDetails, Instance, State, TerminationDetails, CURRENT_INSTANCE, | ||
|
|
@@ -333,11 +332,23 @@ extern "C" fn handle_signal(signum: c_int, siginfo_ptr: *mut siginfo_t, ucontext | |
| }); | ||
|
|
||
| if switch_to_host { | ||
| HOST_CTX.with(|host_ctx| unsafe { | ||
| Context::set_from_signal(&*host_ctx.get()) | ||
| .expect("can successfully switch back to the host context"); | ||
| }); | ||
| unreachable!() | ||
| // Switch to host by preparing the context to switch when we return from the signal andler. | ||
| // We must return from the signal handler for POSIX reasons, so instead prepare the context | ||
| // that the signal handler will resume the program as if a call were made. First, by | ||
| // pointing the instruction pointer at `lucet_context_set`, then by preparing the argument | ||
| // that `lucet_context_set` should read from `rdi` - the context to switch to. | ||
| // | ||
| // NOTE: it is absolutely critical that `lucet_context_set` does not use the guest stack! | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. full disclosure: I left most of the branch unchanged while adjusting the commits, but this |
||
| // If it did, and the signal being handled were a segfault from reaching the guard page, | ||
| // there would be no stack available for the function we return to. By not using stack | ||
| // space, `lucet_context_set` is safe for use even in handling guard page faults. | ||
| // | ||
| // TODO: `rdi` is only correct for SysV (unixy) calling conventions! For Windows x86_64 this | ||
| // would be `rcx`, with other architectures being their own question. | ||
| ctx.set_ip(crate::context::lucet_context_set as *const c_void); | ||
| HOST_CTX.with(|host_ctx| { | ||
| ctx.set_rdi(host_ctx.get() as u64); | ||
| }) | ||
| } | ||
| } | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 22 additions & 16 deletions
38
lucet-runtime/lucet-runtime-internals/src/sysdeps/linux.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,50 +1,56 @@ | ||
| use libc::{c_void, ucontext_t, REG_RIP}; | ||
| use libc::{c_void, ucontext_t, REG_RDI, REG_RIP}; | ||
|
|
||
| #[derive(Clone, Copy, Debug)] | ||
| pub struct UContextPtr(*const ucontext_t); | ||
| pub struct UContextPtr(*mut ucontext_t); | ||
|
|
||
| impl UContextPtr { | ||
| #[inline] | ||
| pub fn new(ptr: *const c_void) -> Self { | ||
| pub fn new(ptr: *mut c_void) -> Self { | ||
| assert!(!ptr.is_null(), "non-null context"); | ||
| UContextPtr(ptr as *const ucontext_t) | ||
| UContextPtr(ptr as *mut ucontext_t) | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn get_ip(self) -> *const c_void { | ||
| let mcontext = &unsafe { *(self.0) }.uc_mcontext; | ||
| let mcontext = &unsafe { self.0.as_ref().unwrap() }.uc_mcontext; | ||
| mcontext.gregs[REG_RIP as usize] as *const _ | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn set_ip(self, new_ip: *const c_void) { | ||
| let mut mcontext = &mut unsafe { self.0.as_mut().unwrap() }.uc_mcontext; | ||
| mcontext.gregs[REG_RIP as usize] = new_ip as i64; | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn set_rdi(self, new_rdi: u64) { | ||
| let mut mcontext = &mut unsafe { self.0.as_mut().unwrap() }.uc_mcontext; | ||
| mcontext.gregs[REG_RDI as usize] = new_rdi as i64; | ||
| } | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| #[derive(Clone, Copy)] | ||
| pub struct UContext { | ||
| context: ucontext_t, | ||
| context: *mut ucontext_t, | ||
| } | ||
|
|
||
| impl UContext { | ||
| #[inline] | ||
| pub fn new(ptr: *const c_void) -> Self { | ||
| pub fn new(ptr: *mut c_void) -> Self { | ||
| UContext { | ||
| context: *unsafe { | ||
| (ptr as *const ucontext_t) | ||
| .as_ref() | ||
| .expect("non-null context") | ||
| }, | ||
| context: unsafe { (ptr as *mut ucontext_t).as_mut().expect("non-null context") }, | ||
| } | ||
| } | ||
|
|
||
| pub fn as_ptr(&mut self) -> UContextPtr { | ||
| UContextPtr::new(&self.context as *const _ as *const _) | ||
| UContextPtr::new(self.context as *mut _ as *mut _) | ||
| } | ||
| } | ||
|
|
||
| impl Into<UContext> for UContextPtr { | ||
| #[inline] | ||
| fn into(self) -> UContext { | ||
| UContext { | ||
| context: unsafe { *(self.0) }, | ||
| } | ||
| UContext { context: self.0 } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.