[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