Handle PTID, TLS, and CTID arguments properly. Add RESET_PID handling.
authordrepper <drepper>
Thu, 14 Apr 2005 21:43:09 +0000 (21:43 +0000)
committerdrepper <drepper>
Thu, 14 Apr 2005 21:43:09 +0000 (21:43 +0000)
sysdeps/unix/sysv/linux/sparc/sparc64/clone.S

index a7c248b..f613459 100644 (file)
 
 #include <asm/errno.h>
 #include <asm/unistd.h>
+#include <tcb-offsets.h>
 
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
+#define CLONE_VM       0x00000100
+#define CLONE_THREAD   0x00010000
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+            pid_t *ptid, void *tls, pid_t *ctid); */
+
+       .register       %g2,#scratch
+       .register       %g3,#scratch
 
        .text
        .align  4
@@ -34,22 +42,31 @@ __clone:
        save    %sp, -192, %sp
 
        /* sanity check arguments */
-       brz,pn  %i0, 99f
-        mov    %i0, %l0                /* save fn */
-       brz,pn  %i1, 99f
-        mov    %i3, %l3                /* save arg */
+       brz,pn  %i0, 99f                /* fn non-NULL? */
+        mov    %i0, %g2
+       brz,pn  %i1, 99f                /* child_stack non-NULL? */
+        mov    %i2, %o0                /* clone flags */
+
+       /* The child_stack is the top of the stack, allocate one
+          whole stack frame from that as this is what the kernel
+          expects.  Also, subtract STACK_BIAS.  */
+       sub     %i1, 192 + 0x7ff, %o1
+       mov     %i3, %g3
+       mov     %i2, %g4
+
+       mov     %i4,%o2                 /* PTID */
+       mov     %i5,%o3                 /* TLS */
+       ldx     [%fp+0x7ff+176],%o4     /* CTID */
 
        /* Do the system call */
-       sub     %i1, 0x7ff, %o1
-       mov     %i2, %o0
        set     __NR_clone, %g1
        ta      0x6d
        bcs,pn  %xcc, 99f
         nop
        brnz,pn %o1, __thread_start
-        mov    %o0, %i0
+        nop
        ret
-        restore
+        restore %o0, %g0, %o0
 99:
 #ifndef _LIBC_REENTRANT
 #ifdef PIC
@@ -77,10 +94,22 @@ __clone:
 
        .type __thread_start,@function
 __thread_start:
+#ifdef RESET_PID
+       sethi   %hi(CLONE_THREAD), %l0
+       andcc   %g4, %l0, %g0
+       bne,pt  %icc, 1f
+        andcc  %g4, CLONE_VM, %g0
+       bne,a,pn %icc, 2f
+        mov    -1,%o0
+       set     __NR_getpid,%g1
+       ta      0x6d
+2:     st      %o0,[%g7 + PID]
+       st      %o0,[%g7 + TID]
+1:
+#endif
        mov     %g0, %fp        /* terminate backtrace */
-       sub     %sp, 6*8, %sp   /* provide arg storage */
-       call    %l0
-        mov    %l3,%o0
+       call    %g2
+        mov    %g3,%o0
        call    _exit,0
         nop
        .size __thread_start, .-__thread_start