1b2b3ffcdSSimon Schubert/*- 2b2b3ffcdSSimon Schubert * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 3b2b3ffcdSSimon Schubert * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> 4b2b3ffcdSSimon Schubert * All rights reserved. 5b2b3ffcdSSimon Schubert * 6b2b3ffcdSSimon Schubert * Redistribution and use in source and binary forms, with or without 7b2b3ffcdSSimon Schubert * modification, are permitted provided that the following conditions 8b2b3ffcdSSimon Schubert * are met: 9b2b3ffcdSSimon Schubert * 1. Redistributions of source code must retain the above copyright 10b2b3ffcdSSimon Schubert * notice, this list of conditions and the following disclaimer. 11b2b3ffcdSSimon Schubert * 2. Redistributions in binary form must reproduce the above copyright 12b2b3ffcdSSimon Schubert * notice, this list of conditions and the following disclaimer in the 13b2b3ffcdSSimon Schubert * documentation and/or other materials provided with the distribution. 14b2b3ffcdSSimon Schubert * 15b2b3ffcdSSimon Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16b2b3ffcdSSimon Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17b2b3ffcdSSimon Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18b2b3ffcdSSimon Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19b2b3ffcdSSimon Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20b2b3ffcdSSimon Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21b2b3ffcdSSimon Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22b2b3ffcdSSimon Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23b2b3ffcdSSimon Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24b2b3ffcdSSimon Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25b2b3ffcdSSimon Schubert * SUCH DAMAGE. 26b2b3ffcdSSimon Schubert * 27b2b3ffcdSSimon Schubert * $FreeBSD: src/lib/libc/amd64/gen/rfork_thread.S,v 1.2 2008/11/02 01:10:54 peter Exp $ 28b2b3ffcdSSimon Schubert */ 29b2b3ffcdSSimon Schubert 30b2b3ffcdSSimon Schubert#include <machine/asm.h> 31b2b3ffcdSSimon Schubert 32b2b3ffcdSSimon Schubert/* 33b2b3ffcdSSimon Schubert * With thanks to John Dyson for the original version of this. 34b2b3ffcdSSimon Schubert */ 35b2b3ffcdSSimon Schubert 36b2b3ffcdSSimon Schubert#include <SYS.h> 37b2b3ffcdSSimon Schubert 38b2b3ffcdSSimon Schubert/* 39b2b3ffcdSSimon Schubert * %edi %rsi %rdx %rcx 40b2b3ffcdSSimon Schubert * rfork_thread(flags, stack_addr, start_fnc, start_arg); 41b2b3ffcdSSimon Schubert * 42b2b3ffcdSSimon Schubert * flags: Flags to rfork system call. See rfork(2). 43b2b3ffcdSSimon Schubert * stack_addr: Top of stack for thread. 44b2b3ffcdSSimon Schubert * start_fnc: Address of thread function to call in child. 45b2b3ffcdSSimon Schubert * start_arg: Argument to pass to the thread function in child. 46b2b3ffcdSSimon Schubert */ 47b2b3ffcdSSimon Schubert 48b2b3ffcdSSimon SchubertENTRY(rfork_thread) 49b2b3ffcdSSimon Schubert pushq %rbx 50b2b3ffcdSSimon Schubert pushq %r12 51b2b3ffcdSSimon Schubert movq %rdx, %rbx 52b2b3ffcdSSimon Schubert movq %rcx, %r12 53b2b3ffcdSSimon Schubert 54b2b3ffcdSSimon Schubert /* 55b2b3ffcdSSimon Schubert * Prepare and execute the thread creation syscall 56b2b3ffcdSSimon Schubert */ 57b2b3ffcdSSimon Schubert movq $SYS_rfork, %rax 58b2b3ffcdSSimon Schubert KERNCALL 59b2b3ffcdSSimon Schubert jb 2f 60b2b3ffcdSSimon Schubert 61b2b3ffcdSSimon Schubert /* 62b2b3ffcdSSimon Schubert * Check to see if we are in the parent or child 63b2b3ffcdSSimon Schubert */ 64b2b3ffcdSSimon Schubert cmpl $0, %edx 65b2b3ffcdSSimon Schubert jnz 1f 66b2b3ffcdSSimon Schubert popq %r12 67b2b3ffcdSSimon Schubert popq %rbx 68b2b3ffcdSSimon Schubert ret 69b2b3ffcdSSimon Schubert 70b2b3ffcdSSimon Schubert /* 71b2b3ffcdSSimon Schubert * If we are in the child (new thread), then 72b2b3ffcdSSimon Schubert * set-up the call to the internal subroutine. If it 73b2b3ffcdSSimon Schubert * returns, then call __exit. 74b2b3ffcdSSimon Schubert */ 75b2b3ffcdSSimon Schubert1: 76b2b3ffcdSSimon Schubert movq %rsi, %rsp 77b2b3ffcdSSimon Schubert movq %r12, %rdi 78b2b3ffcdSSimon Schubert call *%rbx 79b2b3ffcdSSimon Schubert movl %eax, %edi 80b2b3ffcdSSimon Schubert 81b2b3ffcdSSimon Schubert /* 82b2b3ffcdSSimon Schubert * Exit system call 83b2b3ffcdSSimon Schubert */ 84b2b3ffcdSSimon Schubert#ifdef SYS_exit 85b2b3ffcdSSimon Schubert movq $SYS_exit, %rax 86b2b3ffcdSSimon Schubert#else 87b2b3ffcdSSimon Schubert movq $SYS_sys_exit, %rax 88b2b3ffcdSSimon Schubert#endif 89b2b3ffcdSSimon Schubert KERNCALL 90b2b3ffcdSSimon Schubert 91b2b3ffcdSSimon Schubert /* 92b2b3ffcdSSimon Schubert * Branch here if the thread creation fails: 93b2b3ffcdSSimon Schubert */ 94b2b3ffcdSSimon Schubert2: 95b2b3ffcdSSimon Schubert popq %r12 96b2b3ffcdSSimon Schubert popq %rbx 97b2b3ffcdSSimon Schubert#ifdef PIC 98b2b3ffcdSSimon Schubert movq PIC_GOT(HIDENAME(cerror)), %rdx 99b2b3ffcdSSimon Schubert jmp *%rdx 100b2b3ffcdSSimon Schubert#else 101b2b3ffcdSSimon Schubert jmp HIDENAME(cerror) 102b2b3ffcdSSimon Schubert#endif 103b2b3ffcdSSimon SchubertEND(rfork_thread) 104*8b927cb7SJohn Marino 105*8b927cb7SJohn Marino .section .note.GNU-stack,"",%progbits 106