diff options
Diffstat (limited to 'devel/linuxthreads/files/clone.S')
-rw-r--r-- | devel/linuxthreads/files/clone.S | 128 |
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 |