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)
|