Implement sigsetjmp and siglongjmp for X64
This commit is contained in:
committed by
Jeremy Soller
parent
41c88ed288
commit
35a3efd936
@@ -19,3 +19,9 @@ platform_specific! {
|
||||
"x86_64","x86_64","s";
|
||||
"riscv64", "riscv64", "S";
|
||||
}
|
||||
|
||||
//Each platform has different sizes for sigjmp_buf, currently only x86_64 is supported
|
||||
extern "C" {
|
||||
pub fn setjmp(jb: *mut u64) -> i32;
|
||||
pub fn longjmp(jb: *mut u64, ret: i32);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
//! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
|
||||
|
||||
use core::{mem, ptr};
|
||||
use core::{arch::global_asm, mem, ptr};
|
||||
|
||||
use cbitset::BitSet;
|
||||
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
error::{Errno, ResultExt},
|
||||
header::{errno, time::timespec},
|
||||
header::{errno, setjmp, time::timespec},
|
||||
platform::{self, types::*, Pal, PalSignal, Sys},
|
||||
};
|
||||
|
||||
@@ -86,6 +86,43 @@ pub type siginfo_t = siginfo;
|
||||
|
||||
pub type stack_t = sigaltstack;
|
||||
|
||||
// Macro based on setjmp, only x86_64 is supported at the moment
|
||||
macro_rules! sigsetjmp_platforms {
|
||||
($($rust_arch:expr,$c_arch:expr,$ext:expr;)+) => {
|
||||
$(
|
||||
#[cfg(target_arch = $rust_arch)]
|
||||
global_asm!(include_str!(concat!("sigsetjmp/", $c_arch, "/sigsetjmp.", $ext)));
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
//Insert more platforms here
|
||||
sigsetjmp_platforms! {
|
||||
"x86_64","x86_64","s";
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn sigsetjmp(jb: *mut u64, savemask: i32) -> i32;
|
||||
}
|
||||
|
||||
//NOTE for the following two functions, to see why they're implemented slightly differently from their intended behavior, read
|
||||
// https://git.musl-libc.org/cgit/musl/commit/?id=583e55122e767b1586286a0d9c35e2a4027998ab
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn __sigsetjmp_tail(jb: *mut u64, ret: i32) -> i32 {
|
||||
let set = jb.wrapping_add(9);
|
||||
if ret > 0 {
|
||||
sigprocmask(SIG_SETMASK, set, ptr::null_mut());
|
||||
} else {
|
||||
sigprocmask(SIG_SETMASK, ptr::null_mut(), set);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn siglongjmp(jb: *mut u64, ret: i32) {
|
||||
setjmp::longjmp(jb, ret);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kill(pid: pid_t, sig: c_int) -> c_int {
|
||||
Sys::kill(pid, sig).map(|()| 0).or_minus_one_errno()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# implementation of sigsetjmp
|
||||
|
||||
All code found in the subdirectories of this directory belong to [musl libc](https://musl.libc.org/). They own it. All rights go to them.
|
||||
Currently only x86_64 is supported, because I don't have access to non-x86 devices to test it properly.
|
||||
Converted to Intel assembly syntax, according to setjmp and longjmp found in setjmp header.
|
||||
@@ -0,0 +1,26 @@
|
||||
.global sigsetjmp
|
||||
.global _sigsetjmp
|
||||
.global __sigsetjmp
|
||||
.type sigsetjmp,@function
|
||||
.type _sigsetjmp,@function
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
_sigsetjmp:
|
||||
__sigsetjmp:
|
||||
test esi,esi
|
||||
jz 1f
|
||||
|
||||
pop qword ptr [rdi+64]
|
||||
mov qword ptr [rdi+80],rbx
|
||||
mov rbx,rdi
|
||||
|
||||
call setjmp
|
||||
|
||||
push qword ptr [rbx+64]
|
||||
mov rdi,rbx
|
||||
mov esi,eax
|
||||
mov rbx, qword ptr[rbx+80]
|
||||
|
||||
jmp __sigsetjmp_tail
|
||||
|
||||
1: jmp setjmp
|
||||
Reference in New Issue
Block a user