about summary refs log tree commit diff
path: root/src/thread/x86_64
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-09-18 10:14:37 -0400
committerRich Felker <dalias@aerifal.cx>2011-09-18 10:14:37 -0400
commit3f72cdac73030761120cf32aeef44e7d03e2f1fa (patch)
treed52dde9adbb8386100d98371d4e954fb88af2c41 /src/thread/x86_64
parent455fc98389fac09d8cf7ec4cde310a5b7ca47485 (diff)
downloadmusl-3f72cdac73030761120cf32aeef44e7d03e2f1fa.tar.gz
musl-3f72cdac73030761120cf32aeef44e7d03e2f1fa.tar.xz
musl-3f72cdac73030761120cf32aeef44e7d03e2f1fa.zip
overhaul clone syscall wrapping
several things are changed. first, i have removed the old __uniclone
function signature and replaced it with the "standard" linux
__clone/clone signature. this was necessary to expose clone to
applications anyway, and it makes it easier to port __clone to new
archs, since it's now testable independently of pthread_create.

secondly, i have removed all references to the ugly ldt descriptor
structure (i386 only) from the c code and pthread structure. in places
where it is needed, it is now created on the stack just when it's
needed, in assembly code. thus, the i386 __clone function takes the
desired thread pointer as its argument, rather than an ldt descriptor
pointer, just like on all other sane archs. this should not affect
applications since there is really no way an application can use clone
with threads/tls in a way that doesn't horribly conflict with and
clobber the underlying implementation's use. applications are expected
to use clone only for creating actual processes, possibly with new
namespace features and whatnot.
Diffstat (limited to 'src/thread/x86_64')
-rw-r--r--src/thread/x86_64/clone.s49
1 files changed, 29 insertions, 20 deletions
diff --git a/src/thread/x86_64/clone.s b/src/thread/x86_64/clone.s
index bf128a47..4db081cd 100644
--- a/src/thread/x86_64/clone.s
+++ b/src/thread/x86_64/clone.s
@@ -1,21 +1,30 @@
-/* Copyright 2011 Nicholas J. Kain, licensed GNU LGPL 2.1 or later */
 .text
-.global __uniclone
-.type   __uniclone,@function
-/* rdi = child_stack, rsi = start, rdx = pthread_struct */
-__uniclone:
-        subq    $8,%rsp         /* pad parent stack to prevent branch later */
-        subq    $24,%rdi        /* grow child_stack */
-        mov     %rsi,8(%rdi)    /* push start onto child_stack as return ptr */
-        mov     %rdx,0(%rdi)    /* push pthread_struct onto child_stack */
-        mov     %rdx,%r8        /* r8 = tls */
-        mov     %rdi,%rsi       /* rsi = child_stack */
-        leaq    40(%rdx),%r10   /* r10 = child_id */
-        movl    $56,%eax        /* clone syscall number */
-        movl    $0x7d0f00,%edi  /* rdi = flags */
-        mov     %r10,%rdx       /* rdx = parent_id */
-        syscall                 /* clone(flags, child_stack, parent_id,
-                                 *       child_id, tls) */
-        pop     %rdi            /* child stack: restore pthread_struct
-                                 * parent stack: undo rsp displacement */
-        ret
+.global __clone
+.weak clone
+.type   __clone,@function
+.type   clone,@function
+__clone:
+clone:
+	xor %eax,%eax
+	mov $56,%al
+	mov %rdi,%r11
+	mov %rdx,%rdi
+	mov %r8,%rdx
+	mov %r9,%r8
+	mov 8(%rsp),%r10
+	mov %r11,%r9
+	and $-16,%rsi
+	sub $8,%rsi
+	mov %rcx,(%rsi)
+	syscall
+	test %eax,%eax
+	jnz 1f
+	xor %ebp,%ebp
+	pop %rdi
+	call *%r9
+	mov %eax,%edi
+	xor %eax,%eax
+	mov $60,%al
+	syscall
+	hlt
+1:	ret