Implement sigsetjmp and siglongjmp for X64
This commit is contained in:
committed by
Jeremy Soller
parent
41c88ed288
commit
35a3efd936
+2
-1
@@ -58,7 +58,8 @@ typedef unsigned long long jmp_buf[8];
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef unsigned long jmp_buf[8];
|
||||
typedef unsigned long jmp_buf[16];
|
||||
typedef jmp_buf sigjmp_buf;
|
||||
#endif
|
||||
|
||||
#ifdef __riscv
|
||||
|
||||
@@ -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
|
||||
@@ -35,6 +35,7 @@ EXPECT_NAMES=\
|
||||
sigaction \
|
||||
sigaltstack \
|
||||
signal \
|
||||
sigsetjmp \
|
||||
stdio/all \
|
||||
stdio/buffer \
|
||||
stdio/dprintf \
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Starting jump...
|
||||
Jump done.
|
||||
@@ -0,0 +1,2 @@
|
||||
Starting jump...
|
||||
Jump done.
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
int main() {
|
||||
sigjmp_buf jb;
|
||||
|
||||
if (sigsetjmp(jb, 1)) {
|
||||
printf("Jump done.\n");
|
||||
} else {
|
||||
printf ("Starting jump...\n");
|
||||
siglongjmp(jb, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user