Implement sigsetjmp and siglongjmp for X64

This commit is contained in:
Bendeguz Pisch
2025-01-04 00:29:19 +00:00
committed by Jeremy Soller
parent 41c88ed288
commit 35a3efd936
11 changed files with 98 additions and 3 deletions
+2 -1
View File
@@ -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
+6
View File
@@ -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);
}
+39 -2
View File
@@ -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()
+5
View File
@@ -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
+1
View File
@@ -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.
+15
View File
@@ -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;
}