rfork_thread.S revision 217106
1239310Sdim/*- 2239310Sdim * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 3239310Sdim * All rights reserved. 4239310Sdim * 5239310Sdim * Redistribution and use in source and binary forms, with or without 6239310Sdim * modification, are permitted provided that the following conditions 7239310Sdim * are met: 8239310Sdim * 1. Redistributions of source code must retain the above copyright 9239310Sdim * notice, this list of conditions and the following disclaimer. 10239310Sdim * 2. Redistributions in binary form must reproduce the above copyright 11239310Sdim * notice, this list of conditions and the following disclaimer in the 12239310Sdim * documentation and/or other materials provided with the distribution. 13239310Sdim * 14239310Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15239310Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16239310Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17239310Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18239310Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19239310Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20249423Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21249423Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22239310Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23263508Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24239310Sdim * SUCH DAMAGE. 25239310Sdim */ 26239310Sdim 27239310Sdim#include <machine/asm.h> 28239310Sdim__FBSDID("$FreeBSD: head/lib/libc/i386/gen/rfork_thread.S 217106 2011-01-07 16:08:40Z kib $"); 29249423Sdim 30239310Sdim/* 31239310Sdim * With thanks to John Dyson for the original version of this. 32239310Sdim */ 33239310Sdim 34239310Sdim#include <SYS.h> 35239310Sdim 36239310Sdim/* 37239310Sdim * 8 12 16 20 38239310Sdim * rfork_thread(flags, stack_addr, start_fnc, start_arg); 39239310Sdim * 40263508Sdim * flags: Flags to rfork system call. See rfork(2). 41263508Sdim * stack_addr: Top of stack for thread. 42263508Sdim * start_fnc: Address of thread function to call in child. 43263508Sdim * start_arg: Argument to pass to the thread function in child. 44263508Sdim */ 45263508Sdim 46263508SdimENTRY(rfork_thread) 47263508Sdim pushl %ebp 48263508Sdim movl %esp, %ebp 49263508Sdim pushl %esi 50263508Sdim 51249423Sdim /* 52263508Sdim * Push thread info onto the new thread's stack 53263508Sdim */ 54263508Sdim movl 12(%ebp), %esi # get stack addr 55263508Sdim 56263508Sdim subl $4, %esi 57263508Sdim movl 20(%ebp), %eax # get start argument 58239310Sdim movl %eax, (%esi) 59239310Sdim 60239310Sdim subl $4, %esi 61239310Sdim movl 16(%ebp), %eax # get start thread address 62239310Sdim movl %eax, (%esi) 63249423Sdim 64249423Sdim /* 65249423Sdim * Prepare and execute the thread creation syscall 66249423Sdim */ 67249423Sdim pushl 8(%ebp) 68249423Sdim pushl $0 69249423Sdim movl $SYS_rfork, %eax 70249423Sdim KERNCALL 71249423Sdim jb 2f 72249423Sdim 73239310Sdim /* 74 * Check to see if we are in the parent or child 75 */ 76 cmpl $0, %edx 77 jnz 1f 78 addl $8, %esp 79 popl %esi 80 movl %ebp, %esp 81 popl %ebp 82 ret 83 .p2align 2 84 85 /* 86 * If we are in the child (new thread), then 87 * set-up the call to the internal subroutine. If it 88 * returns, then call __exit. 89 */ 901: 91 movl %esi,%esp 92 popl %eax 93 call *%eax 94 addl $4, %esp 95 96 /* 97 * Exit system call 98 */ 99 pushl %eax 100 pushl $0 101#ifdef SYS_exit 102 movl $SYS_exit, %eax 103#else 104 movl $SYS_sys_exit, %eax 105#endif 106 KERNCALL 107 108 /* 109 * Branch here if the thread creation fails: 110 */ 1112: 112 addl $8, %esp 113 popl %esi 114 movl %ebp, %esp 115 popl %ebp 116 PIC_PROLOGUE 117 jmp PIC_PLT(HIDENAME(cerror)) 118END(rfork_thread) 119 120 .section .note.GNU-stack,"",%progbits 121