@@ -15,7 +15,10 @@ use linux_raw_sys::general::{__NR_mprotect, PROT_READ};
1515#[ cfg( feature = "thread" ) ]
1616use {
1717 core:: ffi:: c_void,
18- linux_raw_sys:: general:: { __NR_clone, __NR_exit, __NR_munmap, __NR_set_thread_area} ,
18+ linux_raw_sys:: general:: {
19+ __NR_clone, __NR_exit, __NR_munmap, __NR_set_thread_area, CLONE_CHILD_CLEARTID ,
20+ CLONE_CHILD_SETTID ,
21+ } ,
1922 rustix:: thread:: RawPid ,
2023} ;
2124
@@ -256,23 +259,32 @@ pub(super) unsafe fn relocation_mprotect_readonly(ptr: usize, len: usize) {
256259#[ cfg( feature = "thread" ) ]
257260pub ( super ) const STACK_ALIGNMENT : usize = 8 ;
258261
259- /// A wrapper around the Linux `clone` system call.
262+ // MIPS errno value for "operation not supported" (different from x86's 95).
263+ #[ cfg( feature = "take-charge" ) ]
264+ #[ cfg( feature = "thread" ) ]
265+ const EOPNOTSUPP : i32 = 122 ;
266+
267+ /// Linux `clone` syscall wrapper. Inline asm required because child resumes
268+ /// at same point as parent and must jump to our thread entrypoint.
260269///
261- /// This can't be implemented in `rustix` because the child starts executing at
262- /// the same point as the parent and we need to use inline asm to have the
263- /// child jump to our new-thread entrypoint.
270+ /// CLONE_CHILD_CLEARTID/SETTID unsupported (O32 ABI needs child_tid on stack).
264271#[ cfg( feature = "take-charge" ) ]
265272#[ cfg( feature = "thread" ) ]
266273#[ inline]
267274pub ( super ) unsafe fn clone (
268275 flags : u32 ,
269276 child_stack : * mut c_void ,
270277 parent_tid : * mut RawPid ,
271- child_tid : * mut RawPid ,
278+ _child_tid : * mut RawPid , // unused: O32 ABI needs stack passing, not implemented
272279 newtls : * mut c_void ,
273280 fn_ : extern "C" fn ( ) ,
274281 num_args : usize ,
275282) -> isize {
283+ // Fail explicitly for flags that require child_tid, which we don't pass.
284+ if flags & ( CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID ) != 0 {
285+ return -( EOPNOTSUPP as isize ) ;
286+ }
287+
276288 unsafe {
277289 let r0;
278290 asm ! (
@@ -318,9 +330,6 @@ pub(super) unsafe fn clone(
318330 lateout( "$t9" ) _,
319331 options( nostack)
320332 ) ;
321- // Note: child_tid handling is simplified here; full implementation would
322- // need to push it to the stack frame per O32 calling convention.
323- let _ = child_tid;
324333 r0
325334 }
326335}
0 commit comments