summaryrefslogtreecommitdiff
path: root/devel/linuxthreads/files/clone.S
diff options
context:
space:
mode:
Diffstat (limited to 'devel/linuxthreads/files/clone.S')
-rw-r--r--devel/linuxthreads/files/clone.S128
1 files changed, 128 insertions, 0 deletions
diff --git a/devel/linuxthreads/files/clone.S b/devel/linuxthreads/files/clone.S
new file mode 100644
index 000000000000..52e80d6da646
--- /dev/null
+++ b/devel/linuxthreads/files/clone.S
@@ -0,0 +1,128 @@
+ .file "clone.S"
+#include <sys/syscall.h>
+#include "DEFS.h"
+#include "SYS.h"
+#define KERNEL
+#include <sys/errno.h>
+#undef KERNEL
+
+#undef DEBUG
+
+/*
+ * 8 12 16 20
+ * _clone (__fn, __childstack, __flags, __arg);
+ *
+ * I'm pretty shakey on assembly language, so someone else better
+ * check this! I don't even know what half this stuff means, its
+ * just copied from somewhere else (rf.S).
+ *
+ * It seems to work though.
+ *
+ * Here's the idea:
+ * __childstack is the TOS for the new rforked thread
+ * __flags are the rfork flags
+ * __fn is the userland function go be started for the new thread
+ * as in:
+ *
+ * int __fn (void * __arg)
+ *
+ */
+.stabs "clone.S",100,0,0,Ltext0
+ .text
+Ltext0:
+ .type CNAME(_clone),@function
+ .stabd 68,0,1
+ENTRY(_clone)
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+
+ /*
+ * Push thread info onto the new thread's stack
+ */
+ movl 12(%ebp), %esi / get stack addr
+
+ subl $4, %esi
+ movl 20(%ebp), %eax / get __arg
+ movl %eax, (%esi)
+
+ subl $4, %esi
+ movl 8(%ebp), %eax / get __fn
+ movl %eax, (%esi)
+
+ .stabd 68,0,2
+ /*
+ * Prepare and execute rfork
+ */
+ pushl 16(%ebp)
+ pushl %esi
+
+ leal SYS_rfork, %eax
+ KERNCALL
+ jb 2f
+
+ .stabd 68,0,3
+ /*
+ * Check to see if we are in the parent or child
+ */
+ cmpl $0, %edx
+ jnz 1f
+ addl $8, %esp
+ popl %esi
+ movl %ebp, %esp
+ popl %ebp
+ ret
+ .p2align 2
+
+ /*
+ * If we are in the child (new thread), then
+ * set-up the call to the internal subroutine. If it
+ * returns, then call _exit.
+ */
+ .stabd 68,0,4
+1:
+ movl %esi,%esp
+#ifdef DEBUG
+ movl %esp, _stackaddr
+ movl (%esp), %eax
+ movl %eax, _stack
+ movl 4(%esp), %eax
+ movl %eax,_stack+4
+ movl 8(%esp), %eax
+ movl %eax,_stack+8
+#endif
+ popl %eax
+#ifdef DEBUG
+ movl %eax,_fcn
+#endif
+ call %eax
+ addl $8, %esp
+
+ /*
+ * Exit system call
+ */
+ call PIC_PLT(_exit)
+
+ .stabd 68,0,5
+2: addl $8, %esp
+ popl %esi
+ movl %ebp, %esp
+ popl %ebp
+ jmp PIC_PLT(HIDENAME(cerror))
+
+.stabs "_clone:f67",36,0,6,CNAME(_clone)
+Lfe1:
+ .size CNAME(_clone),Lfe1-CNAME(_clone)
+
+#ifdef DEBUG
+ .data
+ .globl _stack
+_stack: .long 0
+ .long 0
+ .long 0
+ .long 0
+ .globl _stackaddr
+_stackaddr: .long 0
+ .globl _fcn
+_fcn: .long 0
+#endif