Use unsafe blocks in redox-rt

This commit is contained in:
sourceturner
2026-01-21 22:41:46 +01:00
parent ac7b3c2b74
commit e6ce5628da
5 changed files with 74 additions and 59 deletions
+22 -17
View File
@@ -94,14 +94,16 @@ unsafe extern "C" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) -> usiz
unsafe extern "C" fn child_hook(scratchpad: &ForkScratchpad) {
//let _ = syscall::write(1, alloc::format!("CUR{cur_filetable_fd}PROC{new_proc_fd}THR{new_thr_fd}\n").as_bytes());
let _ = syscall::close(scratchpad.cur_filetable_fd);
crate::child_hook_common(crate::ChildHookCommonArgs {
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
None
} else {
Some(FdGuard::new(scratchpad.new_proc_fd))
},
});
unsafe {
crate::child_hook_common(crate::ChildHookCommonArgs {
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
None
} else {
Some(FdGuard::new(scratchpad.new_proc_fd))
},
})
};
}
asmfunction!(__relibc_internal_fork_wrapper (usize) -> usize: ["
@@ -449,19 +451,22 @@ pub fn current_sp() -> usize {
}
pub unsafe fn manually_enter_trampoline() {
let ctl = &Tcb::current().unwrap().os_specific.control;
let ctl = unsafe { &Tcb::current().unwrap().os_specific.control };
ctl.saved_archdep_reg.set(0);
let ip_location = &ctl.saved_ip as *const _ as usize;
core::arch::asm!("
bl 2f
b 3f
2:
str lr, [x0]
b __relibc_internal_sigentry
3:
", inout("x0") ip_location => _, out("lr") _);
unsafe {
core::arch::asm!("
bl 2f
b 3f
2:
str lr, [x0]
b __relibc_internal_sigentry
3:
",
inout("x0") ip_location => _, out("lr") _);
}
}
pub unsafe fn arch_pre(stack: &mut SigStack, os: &mut SigArea) -> PosixStackt {
+26 -22
View File
@@ -78,14 +78,16 @@ unsafe extern "fastcall" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize)
// TODO: duplicate code with x86_64
unsafe extern "cdecl" fn child_hook(scratchpad: ForkScratchpad) {
let _ = syscall::close(scratchpad.cur_filetable_fd);
crate::child_hook_common(crate::ChildHookCommonArgs {
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
None
} else {
Some(FdGuard::new(scratchpad.new_proc_fd))
},
});
unsafe {
crate::child_hook_common(crate::ChildHookCommonArgs {
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
None
} else {
Some(FdGuard::new(scratchpad.new_proc_fd))
},
})
};
}
asmfunction!(__relibc_internal_fork_wrapper (usize) -> usize: ["
@@ -356,8 +358,8 @@ unsafe extern "C" {
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt {
if stack.regs.eip == __relibc_internal_sigentry_crit_first as usize {
let stack_ptr = stack.regs.esp as *const usize;
stack.regs.esp = stack_ptr.read();
stack.regs.eip = stack_ptr.sub(1).read();
stack.regs.esp = unsafe { stack_ptr.read() };
stack.regs.eip = unsafe { stack_ptr.sub(1).read() };
} else if stack.regs.eip == __relibc_internal_sigentry_crit_second as usize
|| stack.regs.eip == __relibc_internal_sigentry_crit_third as usize
{
@@ -371,24 +373,26 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt
}
#[unsafe(no_mangle)]
pub unsafe fn manually_enter_trampoline() {
let c = &crate::Tcb::current().unwrap().os_specific.control;
let c = unsafe { &crate::Tcb::current().unwrap().os_specific.control };
c.control_flags.store(
c.control_flags.load(Ordering::Relaxed) | syscall::flag::INHIBIT_DELIVERY.bits(),
Ordering::Release,
);
c.saved_archdep_reg.set(0); // TODO: Just reset DF on x86?
core::arch::asm!("
call 2f
jmp 3f
2:
pop dword ptr gs:[{tcb_sc_off} + {sc_saved_eip}]
jmp __relibc_internal_sigentry
3:
",
tcb_sc_off = const offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, control),
sc_saved_eip = const offset_of!(Sigcontrol, saved_ip),
);
unsafe {
core::arch::asm!("
call 2f
jmp 3f
2:
pop dword ptr gs:[{tcb_sc_off} + {sc_saved_eip}]
jmp __relibc_internal_sigentry
3:
",
tcb_sc_off = const offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, control),
sc_saved_eip = const offset_of!(Sigcontrol, saved_ip),
);
}
}
/// Get current stack pointer, weak granularity guarantees.
pub fn current_sp() -> usize {
+24 -19
View File
@@ -69,14 +69,16 @@ unsafe extern "C" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) -> usiz
unsafe extern "C" fn child_hook(scratchpad: &ForkScratchpad) {
let _ = syscall::close(scratchpad.cur_filetable_fd);
crate::child_hook_common(crate::ChildHookCommonArgs {
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
None
} else {
Some(FdGuard::new(scratchpad.new_proc_fd))
},
});
unsafe {
crate::child_hook_common(crate::ChildHookCommonArgs {
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
None
} else {
Some(FdGuard::new(scratchpad.new_proc_fd))
},
})
};
}
asmfunction!(__relibc_internal_fork_wrapper (usize) -> usize: ["
@@ -578,7 +580,7 @@ pub fn current_sp() -> usize {
}
pub unsafe fn manually_enter_trampoline() {
let ctl = &Tcb::current().unwrap().os_specific.control;
let ctl = unsafe { &Tcb::current().unwrap().os_specific.control };
ctl.control_flags.store(
ctl.control_flags.load(Ordering::Relaxed) | syscall::flag::INHIBIT_DELIVERY.bits(),
@@ -587,15 +589,18 @@ pub unsafe fn manually_enter_trampoline() {
ctl.saved_archdep_reg.set(0);
let ip_location = &ctl.saved_ip as *const _ as usize;
core::arch::asm!("
jal 2f
j 3f
2:
sd ra, 0(t0)
la t0, __relibc_internal_sigentry
jalr x0, t0
3:
", inout("t0") ip_location => _, out("ra") _);
unsafe {
core::arch::asm!("
jal 2f
j 3f
2:
sd ra, 0(t0)
la t0, __relibc_internal_sigentry
jalr x0, t0
3:
",
inout("t0") ip_location => _, out("ra") _);
}
}
unsafe extern "C" {
@@ -614,7 +619,7 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt
if stack.regs.pc == __relibc_internal_sigentry_crit_first as u64 {
// Reexecute 'ld sp, (1 * 8)(sp)'
let stack_ptr = stack.regs.int_regs[1] as *const u64; // x2
stack.regs.int_regs[1] = stack_ptr.add(1).read();
stack.regs.int_regs[1] = unsafe { stack_ptr.add(1).read() };
// and 'jr gp' steps.
stack.regs.pc = stack.regs.int_regs[2];
} else if stack.regs.pc == __relibc_internal_sigentry_crit_second as u64
+1
View File
@@ -1,5 +1,6 @@
#![no_std]
#![allow(internal_features)]
#![deny(unsafe_op_in_unsafe_fn)]
#![feature(core_intrinsics, int_roundings, slice_ptr_get, sync_unsafe_cell)]
#![forbid(unreachable_patterns)]
+1 -1
View File
@@ -274,7 +274,7 @@ pub(crate) unsafe extern "C" fn inner_c(stack: usize) {
}
#[cfg(target_arch = "x86")]
pub(crate) unsafe extern "fastcall" fn inner_fastcall(stack: usize) {
inner(&mut *(stack as *mut SigStack))
unsafe { inner(&mut *(stack as *mut SigStack)) }
}
pub fn get_sigmask() -> Result<u64> {