relibc: fix round-8 deferred stubs in linux platform
signal.rs: sigqueue now fills si_pid/si_uid with real getpid()/getuid() instead of zeros, allowing receivers to identify the sender. mod.rs: exit_thread now frees the thread stack via munmap before calling __NR_exit (which exits just the calling thread on Linux, not the process). Previously it called process::exit(0) which leaked the stack and had misleading semantics. mod.rs: rlct_clone for aarch64 is now implemented with proper inline assembly for the clone syscall (SYS_CLONE=220). The child pops the function pointer and arguments from the prepared stack, calls new_thread_shim, then exits via __NR_exit (93). Previously this was todo!() which panicked on thread creation.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
|
||||
use core::arch::asm;
|
||||
|
||||
use super::{Pal, types::*};
|
||||
@@ -165,9 +165,15 @@ impl Pal for Sys {
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
unsafe fn exit_thread(_stack_base: *mut (), _stack_size: usize) -> ! {
|
||||
// TODO
|
||||
Self::exit(0)
|
||||
unsafe fn exit_thread(stack_base: *mut (), stack_size: usize) -> ! {
|
||||
// Free the thread's stack before exiting. On Linux, __NR_exit only
|
||||
// terminates the calling thread (not the process); __NR_exit_group
|
||||
// terminates all threads. We want thread-only exit here.
|
||||
if !stack_base.is_null() && stack_size > 0 {
|
||||
let _ = e_raw(syscall!(MUNMAP, stack_base, stack_size));
|
||||
}
|
||||
unsafe { syscall!(EXIT, 0); }
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
fn fchdir(fildes: c_int) -> Result<()> {
|
||||
@@ -627,7 +633,78 @@ impl Pal for Sys {
|
||||
stack: *mut usize,
|
||||
_os_specific: &mut OsSpecific,
|
||||
) -> Result<crate::pthread::OsTid> {
|
||||
todo!("rlct_clone not implemented for aarch64 yet")
|
||||
const SYS_CLONE_AARCH64: usize = 220;
|
||||
const SYS_EXIT_AARCH64: usize = 93;
|
||||
|
||||
let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD;
|
||||
let pid;
|
||||
unsafe {
|
||||
asm!(
|
||||
"svc #0",
|
||||
|
||||
// If x0 != 0 we are the parent; jump to return.
|
||||
"cbnz x0, 2f",
|
||||
|
||||
// Child: pop function pointer and args from the stack
|
||||
// that the pthread code prepared.
|
||||
"ldr x9, [sp], #8", // x9 = new_thread_shim
|
||||
"ldr x0, [sp], #8", // x0 = start_routine
|
||||
"ldr x1, [sp], #8", // x1 = arg
|
||||
"ldr x2, [sp], #8", // x2 = tcb
|
||||
"ldr x3, [sp], #8", // x3 = sync_mutex
|
||||
"ldr x4, [sp], #8", // skip unused
|
||||
"ldr x5, [sp], #8", // skip unused
|
||||
"ldr x6, [sp], #8", // skip aarch64 alignment pad
|
||||
|
||||
"blr x9", // call new_thread_shim(...)
|
||||
|
||||
// new_thread_shim returns !, but guard just in case.
|
||||
"mov x8, {exit_nr}",
|
||||
"mov x0, xzr",
|
||||
"svc #0",
|
||||
"udf #0",
|
||||
|
||||
"2:",
|
||||
|
||||
exit_nr = const SYS_EXIT_AARCH64,
|
||||
|
||||
inout("x0") flags => pid,
|
||||
inout("x1") stack => _,
|
||||
in("x2") 0usize,
|
||||
in("x3") 0usize,
|
||||
in("x4") 0usize,
|
||||
in("x8") SYS_CLONE_AARCH64,
|
||||
|
||||
out("x5") _,
|
||||
out("x6") _,
|
||||
out("x7") _,
|
||||
out("x9") _,
|
||||
out("x10") _,
|
||||
out("x11") _,
|
||||
out("x12") _,
|
||||
out("x13") _,
|
||||
out("x14") _,
|
||||
out("x15") _,
|
||||
out("x16") _,
|
||||
out("x17") _,
|
||||
out("x18") _,
|
||||
out("x19") _,
|
||||
out("x20") _,
|
||||
out("x21") _,
|
||||
out("x22") _,
|
||||
out("x23") _,
|
||||
out("x24") _,
|
||||
out("x25") _,
|
||||
out("x26") _,
|
||||
out("x27") _,
|
||||
out("x28") _,
|
||||
|
||||
options(nostack),
|
||||
);
|
||||
}
|
||||
let tid = e_raw(pid)?;
|
||||
|
||||
Ok(crate::pthread::OsTid { thread_id: tid })
|
||||
}
|
||||
|
||||
unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<()> {
|
||||
|
||||
@@ -5,7 +5,7 @@ use core::{
|
||||
|
||||
use super::{
|
||||
super::{
|
||||
PalSignal,
|
||||
Pal, PalSignal,
|
||||
types::{c_int, pid_t},
|
||||
},
|
||||
Sys, e_raw,
|
||||
@@ -39,10 +39,10 @@ impl PalSignal for Sys {
|
||||
si_addr: core::ptr::null_mut(),
|
||||
si_code: SI_QUEUE,
|
||||
si_errno: 0,
|
||||
si_pid: 0, // TODO: GETPID?
|
||||
si_pid: Self::getpid(),
|
||||
si_signo: sig,
|
||||
si_status: 0,
|
||||
si_uid: 0, // TODO: GETUID?
|
||||
si_uid: Self::getuid(),
|
||||
si_value: val,
|
||||
};
|
||||
e_raw(unsafe { syscall!(RT_SIGQUEUEINFO, pid, sig, addr_of!(info)) }).map(|_| ())
|
||||
|
||||
Reference in New Issue
Block a user