Hi,
I don't think clone on arm is missing RESET_PID if you use the correct implementation from libpthread/nptl/sysdeps/unix/sysv/linux/arm/clone.S.

Cheers
Carmelo

Inviato con AquaMail per Android
http://www.aqua-mail.com


Il 02 settembre 2014 14:12:24 Wangyufen <wangyu...@huawei.com> ha scritto:

From: Wang Yufen <wangyu...@huawei.com>

Called getpid() When creating a new process with clone(), getpid() returns
the father_process's value. It should be child_process's value.
The reason is missing a RESET_PID in the arm clone impl.

Signed-off-by: Wang Yufen <wangyu...@huawei.com>
---
 libc/sysdeps/linux/arm/clone.S  |   61 ++++++++++++++++++++++++++++++---------
 libc/sysdeps/linux/arm/sysdep.h |   45 ++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+), 14 deletions(-)

diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S
index 03cd10e..29045ef 100644
--- a/libc/sysdeps/linux/arm/clone.S
+++ b/libc/sysdeps/linux/arm/clone.S
@@ -19,12 +19,17 @@
 /* clone() is even more special than fork() as it mucks with stacks
    and invokes a function in the right context after its all over.  */

+#include <sysdep.h>
 #define _ERRNO_H
 #include <features.h>
 #include <bits/errno.h>
 #include <sys/syscall.h>
 #include <bits/arm_asm.h>
 #include <bits/arm_bx.h>
+#include <sysdep-cancel.h>
+
+#define CLONE_VM      0x00000100
+#define CLONE_THREAD  0x00010000

 #if defined(__NR_clone)
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
@@ -87,6 +92,8 @@ __error:
 .pool
 #else
 __clone:
+.fnstart
+.cantunwind
        @ sanity check args
        cmp     r0, #0
        IT(te, ne)
@@ -95,32 +102,58 @@ __clone:
        beq     __error

        @ insert the args onto the new stack
-       sub     r1, r1, #8
-       str     r3, [r1, #4]
-       @ save the function pointer as the 0th element
-       str     r0, [r1]
+       str     r3, [r1, #-4]!
+       str     r0, [r1, #-4]!

        @ do the system call
        @ get flags
        mov     r0, r2
+#ifdef RESET_PID
+       mov     ip, r2
+#endif
        @ new sp is already in r1
-       @ load remaining arguments off the stack
-       stmfd   sp!, {r4}
-       ldr     r2, [sp, #4]
-       ldr     r3, [sp, #8]
-       ldr     r4, [sp, #12]
-       DO_CALL (clone)
-       movs    a1, a1
-       IT(t, ne)
-       ldmnefd sp!, {r4}
+       push    {r4, r7}
+       cfi_adjust_cfa_offset (8)
+       cfi_rel_offset (r4, 0)
+       cfi_rel_offset (r7, 4)
+       ldr     r2, [sp, #8]
+       ldr     r3, [sp, #12]
+       ldr     r4, [sp, #16]
+       ldr     r7, =SYS_ify(clone)
+       swi     0x0
+       cfi_endproc
+       cmp     r0, #0
+       beq     1f
+       pop     {r4, r7}
        blt     __error
-       IT(t, ne)
 #if defined(__USE_BX__)
        bxne    lr
 #else
        movne   pc, lr
 #endif

+       cfi_startproc
+.fnend
+PSEUDO_END (__clone)
+
+1:
+       .fnstart
+       .cantunwind
+#ifdef RESET_PID
+       tst     ip, #CLONE_THREAD
+       bne     3f
+       GET_TLS (lr)
+       mov     r1, r0
+       tst     ip, #CLONE_VM
+       ldr     r7, =SYS_ify(getpid)
+       ite     ne
+       movne   r0, #-1
+       swieq   0x0
+       NEGOFF_ADJ_BASE (r1, TID_OFFSET)
+       str     r0, NEGOFF_OFF1 (r1, TID_OFFSET)
+       str     r0, NEGOFF_OFF2 (r1, PID_OFFSET, TID_OFFSET)
+3:
+#endif
        @ pick the function arg and call address off the stack and execute
        ldr     r0, [sp, #4]
        mov     lr, pc
diff --git a/libc/sysdeps/linux/arm/sysdep.h b/libc/sysdeps/linux/arm/sysdep.h
index 64f4040..38a131d 100644
--- a/libc/sysdeps/linux/arm/sysdep.h
+++ b/libc/sysdeps/linux/arm/sysdep.h
@@ -213,6 +213,51 @@ __local_syscall_error:                                     
        \
    sees the right arguments.

 */
+#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
+# define ARCH_HAS_BX
+#endif
+#if __ARM_ARCH > 4
+# define ARCH_HAS_BLX
+#endif
+#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
+# define ARCH_HAS_HARD_TP
+#endif
+#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6T2__)
+# define ARCH_HAS_T2
+#endif
+
+# ifdef __thumb2__
+#  define NEGOFF_ADJ_BASE(R, OFF)      add R, R, $OFF
+#  define NEGOFF_ADJ_BASE2(D, S, OFF)  add D, S, $OFF
+#  define NEGOFF_OFF1(R, OFF)          [R]
+#  define NEGOFF_OFF2(R, OFFA, OFFB)   [R, $((OFFA) - (OFFB))]
+# else
+#  define NEGOFF_ADJ_BASE(R, OFF)
+#  define NEGOFF_ADJ_BASE2(D, S, OFF)  mov D, S
+#  define NEGOFF_OFF1(R, OFF)          [R, $OFF]
+#  define NEGOFF_OFF2(R, OFFA, OFFB)   [R, $OFFA]
+# endif
+
+# ifdef ARCH_HAS_HARD_TP
+/* If the cpu has cp15 available, use it.  */
+#  define GET_TLS(TMP)         mrc p15, 0, r0, c13, c0, 3
+# else
+/* At this generic level we have no tricks to pull.  Call the ABI routine.  */
+#  define GET_TLS(TMP)                                 \
+       push    { r1, r2, r3, lr };                     \
+       cfi_remember_state;                             \
+       cfi_adjust_cfa_offset (16);                     \
+       cfi_rel_offset (r1, 0);                         \
+       cfi_rel_offset (r2, 4);                         \
+       cfi_rel_offset (r3, 8);                         \
+       cfi_rel_offset (lr, 12);                        \
+       bl      __aeabi_read_tp;                        \
+       pop     { r1, r2, r3, lr };                     \
+       cfi_restore_state
+# endif /* ARCH_HAS_HARD_TP */
+
+
+

 #undef DO_CALL
 #if defined(__ARM_EABI__)
--
1.7.1


_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to