summaryrefslogtreecommitdiff
path: root/src/thread/x86_64/clone.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread/x86_64/clone.s')
-rw-r--r--src/thread/x86_64/clone.s22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/thread/x86_64/clone.s b/src/thread/x86_64/clone.s
new file mode 100644
index 00000000..51410051
--- /dev/null
+++ b/src/thread/x86_64/clone.s
@@ -0,0 +1,22 @@
+/* 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 $16,%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) */
+ test %rax,%rax
+ jnz 1f /* if we're in the parent -> goto 1f */
+ pop %rdi /* restore pthread_struct from child stack */
+1: ret
+.size __uniclone,.-__uniclone