summaryrefslogtreecommitdiff
path: root/toolchain/uclibc/patches/0.9.34-git/0006-arm-add-RESET_PID-in-the-clone-impl.patch
blob: 1c746dd087951beee956f765f3af4412f6c404df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
From 60f9eaa155d0f7ff935da37ecdf253c5c744a3ce 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)