[PATCH] arm: add RESET_PID in the clone impl
Carmelo Amoroso
carmelo73 at gmail.com
Wed Sep 3 20:44:40 UTC 2014
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 <wangyufen at huawei.com> ha scritto:
> From: Wang Yufen <wangyufen at 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 <wangyufen at 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 at uclibc.org
> http://lists.busybox.net/mailman/listinfo/uclibc
More information about the uClibc
mailing list