summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/arc/clone.S
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2014-07-25 17:39:08 +0530
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2014-08-18 11:52:35 +0200
commit99ac739b20856adf7085c524bb3e60987d97a45e (patch)
tree27c5a7f99e18b675892cd047819d95b6966b99e2 /libc/sysdeps/linux/arc/clone.S
parentfd4a5861e29ddc4d77bb9a14d48f5c8969fb80a3 (diff)
ARC/NPTL: clone to set TP if CLONE_SETTLS
Typically kernel would set the TP register of newly created thread in clone syscall with CLONE_SETTLS. However this implies that: * kernel knows of the exact TP register (which is already different for ARCompact and ARCv2) and is a detail which becomes part of the ABI * kernel also needs to handle the unlikely but possible case of !TLS userspace (e.g. Android libc) case where TP reg is not reserved and thus need not be mucked with (using ELF personality based detection) It is better to confine this detail to userspace runtime and set TP reg right after clone syscall returns. Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc/sysdeps/linux/arc/clone.S')
-rw-r--r--libc/sysdeps/linux/arc/clone.S12
1 files changed, 11 insertions, 1 deletions
diff --git a/libc/sysdeps/linux/arc/clone.S b/libc/sysdeps/linux/arc/clone.S
index db5000caf..3c1388ec7 100644
--- a/libc/sysdeps/linux/arc/clone.S
+++ b/libc/sysdeps/linux/arc/clone.S
@@ -29,6 +29,7 @@
#define CLONE_VM 0x00000100
#define CLONE_THREAD 0x00010000
+#define CLONE_SETTLS 0x00080000
#define CLONE_THREAD_N_VM (CLONE_THREAD | CLONE_VM)
ENTRY(clone)
@@ -42,6 +43,7 @@ ENTRY(clone)
mov r10, r0 ; @fn
mov r11, r3 ; @args
mov r12, r2 ; @clone_flags
+ mov r9, r5 ; @tls
; adjust libc args for syscall
@@ -57,6 +59,14 @@ ENTRY(clone)
jnz [blink] ; Parent returns
; ----- child starts here ---------
+
+#if defined(__UCLIBC_HAS_TLS__)
+ ; Setup TP register (since kernel doesn't do that)
+ and.f 0, r12, CLONE_SETTLS
+ bz .Lnext_clone_quirk
+ SET_TP r9
+
+.Lnext_clone_quirk:
#ifdef RESET_PID
mov_s r2, CLONE_THREAD_N_VM
and_s r2, r2, r12
@@ -70,7 +80,7 @@ ENTRY(clone)
.Lgo_thread:
#endif
-
+#endif
; child jumps off to @fn with @arg as argument, and returns here
jl.d [r10]
mov r0, r11