1*83762a71Sderaadt/* $OpenBSD: tfork_thread.S,v 1.11 2023/12/10 16:45:51 deraadt Exp $ */ 2c6f64c6fSguenther/*- 3c6f64c6fSguenther * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 4c6f64c6fSguenther * All rights reserved. 5c6f64c6fSguenther * 6c6f64c6fSguenther * Redistribution and use in source and binary forms, with or without 7c6f64c6fSguenther * modification, are permitted provided that the following conditions 8c6f64c6fSguenther * are met: 9c6f64c6fSguenther * 1. Redistributions of source code must retain the above copyright 10c6f64c6fSguenther * notice, this list of conditions and the following disclaimer. 11c6f64c6fSguenther * 2. Redistributions in binary form must reproduce the above copyright 12c6f64c6fSguenther * notice, this list of conditions and the following disclaimer in the 13c6f64c6fSguenther * documentation and/or other materials provided with the distribution. 14c6f64c6fSguenther * 15c6f64c6fSguenther * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16c6f64c6fSguenther * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17c6f64c6fSguenther * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18c6f64c6fSguenther * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19c6f64c6fSguenther * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20c6f64c6fSguenther * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21c6f64c6fSguenther * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c6f64c6fSguenther * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23c6f64c6fSguenther * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24c6f64c6fSguenther * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25c6f64c6fSguenther * SUCH DAMAGE. 26c6f64c6fSguenther */ 27c6f64c6fSguenther 28c6f64c6fSguenther#include <machine/asm.h> 29c6f64c6fSguenther 30c6f64c6fSguenther/* 31c6f64c6fSguenther * With thanks to John Dyson for the original version of this. 32c6f64c6fSguenther */ 33c6f64c6fSguenther 34c6f64c6fSguenther#include "SYS.h" 35c6f64c6fSguenther 36c6f64c6fSguenther/* 37c6f64c6fSguenther * 8 12 16 20 3816b62b6aSguenther * __tfork_thread(param, psize, start_fnc, start_arg); 39c6f64c6fSguenther * 40c6f64c6fSguenther * param: Arguments to actual system call. 4116b62b6aSguenther * psize: Other argument to pass to the actual kernel call. 42c6f64c6fSguenther * start_fnc: Address of thread function to call in child. 43c6f64c6fSguenther * start_arg: Argument to pass to the thread function in child. 44c6f64c6fSguenther */ 45c6f64c6fSguenther 46c6f64c6fSguentherENTRY(__tfork_thread) 47c6f64c6fSguenther pushl %ebp 48c6f64c6fSguenther movl %esp, %ebp 49c6f64c6fSguenther pushl %esi 5016b62b6aSguenther pushl %edi 51c6f64c6fSguenther 52c6f64c6fSguenther /* 5316b62b6aSguenther * Save the thread info in esi and ebx 54c6f64c6fSguenther */ 5516b62b6aSguenther movl 16(%ebp), %esi # get start thread address 5616b62b6aSguenther movl 20(%ebp), %edi # get start argument 57c6f64c6fSguenther 58c6f64c6fSguenther /* 59c6f64c6fSguenther * Prepare and execute the thread creation syscall 60c6f64c6fSguenther */ 6116b62b6aSguenther pushl 12(%ebp) # push psize 6216b62b6aSguenther pushl 8(%ebp) # push param 6316b62b6aSguenther pushl $0 # slot for return address, ignored by kernel 64c6f64c6fSguenther movl $SYS___tfork, %eax 65*83762a71Sderaadt99: int $0x80 66*83762a71Sderaadt PINSYSCALL(SYS___tfork, 99b) 67c6f64c6fSguenther jb 2f 68c6f64c6fSguenther 69c6f64c6fSguenther /* 70c6f64c6fSguenther * Check to see if we are in the parent or child 71c6f64c6fSguenther */ 7211225f07Sguenther cmpl $0, %eax 7311225f07Sguenther jz 1f 7416b62b6aSguenther addl $12, %esp 7516b62b6aSguenther popl %edi 76c6f64c6fSguenther popl %esi 77c6f64c6fSguenther movl %ebp, %esp 78c6f64c6fSguenther popl %ebp 79c6f64c6fSguenther ret 80c6f64c6fSguenther .p2align 2 81c6f64c6fSguenther 82c6f64c6fSguenther /* 83c6f64c6fSguenther * If we are in the child (new thread), then 84c6f64c6fSguenther * set-up the call to the internal subroutine. If it 8516b62b6aSguenther * returns, then call __threxit. 86c6f64c6fSguenther */ 87c6f64c6fSguenther1: 886df0f8ceSkettenis xorl %ebp, %ebp # mark outermost frame 8989245e66Skettenis subl $4, %esp # align stack 9089245e66Skettenis andl $~15, %esp 9189245e66Skettenis addl $4, %esp 9216b62b6aSguenther pushl %edi # push start argument 9316b62b6aSguenther call *%esi 94c6f64c6fSguenther addl $4, %esp 95c6f64c6fSguenther 96c6f64c6fSguenther /* 97c6f64c6fSguenther * Exit system call 98c6f64c6fSguenther */ 9916b62b6aSguenther pushl $0 # NULL pointer argument to __threxit 10016b62b6aSguenther pushl $0 # slot for return address, ignored by kernel 101c6f64c6fSguenther movl $SYS___threxit, %eax 102*83762a71Sderaadt98: int $0x80 103*83762a71Sderaadt PINSYSCALL(SYS___threxit, 98b) 10413df6982Sderaadt int3 105c6f64c6fSguenther 106c6f64c6fSguenther /* 107c6f64c6fSguenther * Branch here if the thread creation fails: 108c6f64c6fSguenther */ 109c6f64c6fSguenther2: 11016b62b6aSguenther addl $12, %esp 11116b62b6aSguenther popl %edi 112c6f64c6fSguenther popl %esi 113c6f64c6fSguenther movl %ebp, %esp 114c6f64c6fSguenther popl %ebp 115fe38b55cSguenther HANDLE_ERRNO() 116fe38b55cSguenther ret 117aa797096SguentherEND(__tfork_thread) 118