From 3254235eccb8efa36f58f7fffd495ec5aa94c6af Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Tue, 30 Nov 1999 09:07:29 +0000 Subject: Reviewed by: Russell Carter Submitted by: "Richard Seaman, Jr." Native FreeBSD port of the linuxthreads library Includes added files and stuff you need to add to the rest of your system. This is for -current I'm sure Richard's older version might be a good place to start for a 3.x version. --- devel/linuxthreads/files/clone.S | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 devel/linuxthreads/files/clone.S (limited to 'devel/linuxthreads/files/clone.S') 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 +#include "DEFS.h" +#include "SYS.h" +#define KERNEL +#include +#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 -- cgit v1.2.3