Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 31 additions & 46 deletions core/src/coroutine/korosensei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ pub struct Coroutine<'c, Param, Yield, Return> {
impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
cfg_if::cfg_if! {
if #[cfg(unix)] {
#[allow(
clippy::cast_possible_truncation,
clippy::too_many_lines,
clippy::cast_sign_loss,
clippy::cast_possible_wrap
)]
#[allow(clippy::too_many_lines)]
extern "C" fn trap_handler(
_signum: libc::c_int,
_siginfo: *mut libc::siginfo_t,
Expand All @@ -56,43 +51,40 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
any(target_os = "linux", target_os = "android"),
target_arch = "x86_64",
))] {
let sp = context.uc_mcontext.gregs[libc::REG_RSP as usize] as usize;
let sp = u64::try_from(context.uc_mcontext.gregs[usize::try_from(libc::REG_RSP).expect("overflow")]).expect("overflow");
} else if #[cfg(all(
any(target_os = "linux", target_os = "android"),
target_arch = "x86",
))] {
let sp = context.uc_mcontext.gregs[libc::REG_ESP as usize] as usize;
let sp = u64::from(std::mem::transmute::<_, std::ffi::c_uint>(context.uc_mcontext.gregs[usize::try_from(libc::REG_ESP).expect("overflow")]));
} else if #[cfg(all(target_vendor = "apple", target_arch = "x86_64"))] {
let sp = (*context.uc_mcontext).__ss.__rsp as usize;
let sp = u64::try_from((*context.uc_mcontext).__ss.__rsp).expect("overflow");
} else if #[cfg(all(
any(target_os = "linux", target_os = "android"),
target_arch = "aarch64",
))] {
let sp = context.uc_mcontext.sp as usize;
let sp = u64::try_from(context.uc_mcontext.sp).expect("overflow");
} else if #[cfg(all(
any(target_os = "linux", target_os = "android"),
target_arch = "arm",
))] {
let sp = context.uc_mcontext.arm_sp as usize;
let sp = u64::try_from(context.uc_mcontext.arm_sp).expect("overflow");
} else if #[cfg(all(
any(target_os = "linux", target_os = "android"),
any(target_arch = "riscv64", target_arch = "riscv32"),
))] {
let sp = context.uc_mcontext.__gregs[libc::REG_SP] as usize;
let sp = u64::try_from(context.uc_mcontext.__gregs[libc::REG_SP]).expect("overflow");
} else if #[cfg(all(target_vendor = "apple", target_arch = "aarch64"))] {
let sp = (*context.uc_mcontext).__ss.__sp as usize;
let sp = (*context.uc_mcontext).__ss.__sp;
} else if #[cfg(all(target_os = "linux", target_arch = "loongarch64"))] {
let sp = context.uc_mcontext.__gregs[3] as usize;
let sp = u64::try_from(context.uc_mcontext.__gregs[3]).expect("overflow");
} else {
compile_error!("Unsupported platform");
}
}
if let Some(co) = Self::current() {
let handler = co.inner.trap_handler();
// assert!(handler.stack_ptr_in_bounds(sp), "coroutine {} stack overflow !", co.get_name());
// let regs = handler.setup_trap_handler(|| Err("invalid memory reference"));
let stack_ptr_in_bounds = handler.stack_ptr_in_bounds(sp);
let regs = handler.setup_trap_handler(move || {
let stack_ptr_in_bounds = co.stack_ptr_in_bounds(sp);
let regs = co.inner.trap_handler().setup_trap_handler(move || {
Err(if stack_ptr_in_bounds {
"invalid memory reference"
} else {
Expand All @@ -105,21 +97,21 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
target_arch = "x86_64",
))] {
let TrapHandlerRegs { rip, rsp, rbp, rdi, rsi } = regs;
context.uc_mcontext.gregs[libc::REG_RIP as usize] = rip as i64;
context.uc_mcontext.gregs[libc::REG_RSP as usize] = rsp as i64;
context.uc_mcontext.gregs[libc::REG_RBP as usize] = rbp as i64;
context.uc_mcontext.gregs[libc::REG_RDI as usize] = rdi as i64;
context.uc_mcontext.gregs[libc::REG_RSI as usize] = rsi as i64;
context.uc_mcontext.gregs[usize::try_from(libc::REG_RIP).expect("overflow")] = std::ffi::c_longlong::try_from(rip).expect("overflow");
context.uc_mcontext.gregs[usize::try_from(libc::REG_RSP).expect("overflow")] = std::ffi::c_longlong::try_from(rsp).expect("overflow");
context.uc_mcontext.gregs[usize::try_from(libc::REG_RBP).expect("overflow")] = std::ffi::c_longlong::try_from(rbp).expect("overflow");
context.uc_mcontext.gregs[usize::try_from(libc::REG_RDI).expect("overflow")] = std::ffi::c_longlong::try_from(rdi).expect("overflow");
context.uc_mcontext.gregs[usize::try_from(libc::REG_RSI).expect("overflow")] = std::ffi::c_longlong::try_from(rsi).expect("overflow");
} else if #[cfg(all(
any(target_os = "linux", target_os = "android"),
target_arch = "x86",
))] {
let TrapHandlerRegs { eip, esp, ebp, ecx, edx } = regs;
context.uc_mcontext.gregs[libc::REG_EIP as usize] = eip as i32;
context.uc_mcontext.gregs[libc::REG_ESP as usize] = esp as i32;
context.uc_mcontext.gregs[libc::REG_EBP as usize] = ebp as i32;
context.uc_mcontext.gregs[libc::REG_ECX as usize] = ecx as i32;
context.uc_mcontext.gregs[libc::REG_EDX as usize] = edx as i32;
context.uc_mcontext.gregs[usize::try_from(libc::REG_EIP).expect("overflow")] = std::mem::transmute(eip);
context.uc_mcontext.gregs[usize::try_from(libc::REG_ESP).expect("overflow")] = std::mem::transmute(esp);
context.uc_mcontext.gregs[usize::try_from(libc::REG_EBP).expect("overflow")] = std::mem::transmute(ebp);
context.uc_mcontext.gregs[usize::try_from(libc::REG_ECX).expect("overflow")] = std::mem::transmute(ecx);
context.uc_mcontext.gregs[usize::try_from(libc::REG_EDX).expect("overflow")] = std::mem::transmute(edx);
} else if #[cfg(all(target_vendor = "apple", target_arch = "x86_64"))] {
let TrapHandlerRegs { rip, rsp, rbp, rdi, rsi } = regs;
(*context.uc_mcontext).__ss.__rip = rip;
Expand Down Expand Up @@ -175,12 +167,12 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
any(target_arch = "riscv64", target_arch = "riscv32"),
))] {
let TrapHandlerRegs { pc, ra, sp, a0, a1, s0 } = regs;
context.uc_mcontext.__gregs[libc::REG_PC] = pc as libc::c_ulong;
context.uc_mcontext.__gregs[libc::REG_RA] = ra as libc::c_ulong;
context.uc_mcontext.__gregs[libc::REG_SP] = sp as libc::c_ulong;
context.uc_mcontext.__gregs[libc::REG_A0] = a0 as libc::c_ulong;
context.uc_mcontext.__gregs[libc::REG_A0 + 1] = a1 as libc::c_ulong;
context.uc_mcontext.__gregs[libc::REG_S0] = s0 as libc::c_ulong;
context.uc_mcontext.__gregs[libc::REG_PC] = std::ffi::c_ulong::try_from(pc).expect("overflow");
context.uc_mcontext.__gregs[libc::REG_RA] = std::ffi::c_ulong::try_from(ra).expect("overflow");
context.uc_mcontext.__gregs[libc::REG_SP] = std::ffi::c_ulong::try_from(sp).expect("overflow");
context.uc_mcontext.__gregs[libc::REG_A0] = std::ffi::c_ulong::try_from(a0).expect("overflow");
context.uc_mcontext.__gregs[libc::REG_A0 + 1] = std::ffi::c_ulong::try_from(a1).expect("overflow");
context.uc_mcontext.__gregs[libc::REG_S0] = std::ffi::c_ulong::try_from(s0).expect("overflow");
} else if #[cfg(all(target_vendor = "apple", target_arch = "aarch64"))] {
let TrapHandlerRegs { pc, sp, x0, x1, x29, lr } = regs;
(*context.uc_mcontext).__ss.__pc = pc;
Expand Down Expand Up @@ -214,23 +206,16 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
if let Some(co) = Self::current() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "x86_64")] {
let sp = usize::try_from((*(*exception_info).ContextRecord).Rsp).expect("parse RSP failed");
let sp = (*(*exception_info).ContextRecord).Rsp;
} else if #[cfg(target_arch = "x86")] {
let sp = (*(*exception_info).ContextRecord).Esp as usize;
let sp = u64::from((*(*exception_info).ContextRecord).Esp);
} else {
compile_error!("Unsupported platform");
}
}

let handler = co.inner.trap_handler();
// if !handler.stack_ptr_in_bounds(sp) {
// // EXCEPTION_CONTINUE_SEARCH
// crate::error!("coroutine {} stack overflow !", co.get_name());
// return 0;
// }
// let regs = handler.setup_trap_handler(|| Err("invalid memory reference"));
let stack_ptr_in_bounds = handler.stack_ptr_in_bounds(sp);
let regs = handler.setup_trap_handler(move || {
let stack_ptr_in_bounds = co.stack_ptr_in_bounds(sp);
let regs = co.inner.trap_handler().setup_trap_handler(move || {
Err(if stack_ptr_in_bounds {
"invalid memory reference"
} else {
Expand Down
16 changes: 16 additions & 0 deletions core/src/coroutine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
self.stack_infos.borrow().clone()
}

/// Checks whether the stack pointer at the point where a trap occurred is
/// within the coroutine that this `CoroutineTrapHandler` was produced from.
/// This check includes any guard pages on the stack and will therefore
/// still return true in the case of a stack overflow.
///
/// The result of this function is only meaningful if the coroutine has not
/// been dropped yet.
pub fn stack_ptr_in_bounds(&self, stack_ptr: u64) -> bool {
for info in self.stack_infos.borrow().iter() {
if info.stack_bottom as u64 <= stack_ptr && stack_ptr < info.stack_top as u64 {
return true;
}
}
false
}

/// Grows the call stack if necessary.
///
/// This function is intended to be called at manually instrumented points in a program where
Expand Down
52 changes: 0 additions & 52 deletions core/src/syscall/common.rs

This file was deleted.

9 changes: 8 additions & 1 deletion core/src/syscall/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
pub mod common;
macro_rules! syscall_mod {
($($mod_name: ident);*) => {
$(
pub use $mod_name::$mod_name;
mod $mod_name;
)*
}
}

#[cfg(unix)]
pub use unix::*;
Expand Down
2 changes: 1 addition & 1 deletion core/src/syscall/unix/connect.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::common::now;
use crate::net::EventLoops;
use crate::syscall::common::{is_blocking, reset_errno, send_time_limit, set_blocking, set_errno, set_non_blocking};
use crate::syscall::{is_blocking, reset_errno, send_time_limit, set_blocking, set_errno, set_non_blocking};
use libc::{sockaddr, socklen_t};
use once_cell::sync::Lazy;
use std::ffi::{c_int, c_void};
Expand Down
Loading
Loading