.file "clone.S" #include #include "DEFS.h" #include "SYS.h" #define KERNEL #define _KERNEL #include #undef _KERNEL #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