diff options
Diffstat (limited to 'toolchain/uclibc/patches/0.9.34-git/0006-arm-add-RESET_PID-in-the-clone-impl.patch')
-rw-r--r-- | toolchain/uclibc/patches/0.9.34-git/0006-arm-add-RESET_PID-in-the-clone-impl.patch | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/toolchain/uclibc/patches/0.9.34-git/0006-arm-add-RESET_PID-in-the-clone-impl.patch b/toolchain/uclibc/patches/0.9.34-git/0006-arm-add-RESET_PID-in-the-clone-impl.patch new file mode 100644 index 000000000..05341e7ff --- /dev/null +++ b/toolchain/uclibc/patches/0.9.34-git/0006-arm-add-RESET_PID-in-the-clone-impl.patch @@ -0,0 +1,170 @@ +From b516d8b113e479254d114c17cb51f2687098149c Mon Sep 17 00:00:00 2001 +From: Wang Yufen <wangyufen@huawei.com> +Date: Fri, 5 Sep 2014 15:19:21 +0800 +Subject: [PATCH 6/6] arm: add RESET_PID in the clone impl + +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@huawei.com> +Signed-off-by: Waldemar Brodkorb <wbx@openadk.org> +--- + libc/sysdeps/linux/arm/clone.S | 61 +++++++++++++++++++++++++++++++---------- + libc/sysdeps/linux/arm/sysdep.h | 36 ++++++++++++++++++++++++ + 2 files changed, 83 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..2d0a9cc 100644 +--- a/libc/sysdeps/linux/arm/sysdep.h ++++ b/libc/sysdeps/linux/arm/sysdep.h +@@ -213,6 +213,42 @@ __local_syscall_error: \ + sees the right arguments. + + */ ++#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__) ++# define ARCH_HAS_HARD_TP ++#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.8.5.2 (Apple Git-48) + |