1 1.14 skrll /* $NetBSD: __clone.S,v 1.14 2021/06/30 21:20:30 skrll Exp $ */ 2 1.1 chris 3 1.1 chris /* 4 1.1 chris * Copyright (c) 2001 Christopher Gilbert 5 1.1 chris * All rights reserved. 6 1.1 chris * 7 1.1 chris * 1. Redistributions of source code must retain the above copyright 8 1.1 chris * notice, this list of conditions and the following disclaimer. 9 1.1 chris * 2. Redistributions in binary form must reproduce the above copyright 10 1.1 chris * notice, this list of conditions and the following disclaimer in the 11 1.1 chris * documentation and/or other materials provided with the distribution. 12 1.1 chris * 3. The name of the company nor the name of the author may be used to 13 1.1 chris * endorse or promote products derived from this software without specific 14 1.1 chris * prior written permission. 15 1.1 chris * 16 1.1 chris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 1.1 chris * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 1.1 chris * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 chris * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 1.1 chris * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 1.1 chris * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 1.1 chris * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 chris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 chris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 chris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 chris * SUCH DAMAGE. 27 1.1 chris */ 28 1.1 chris 29 1.8 matt #include "SYS.h" 30 1.1 chris #include <sys/errno.h> 31 1.1 chris 32 1.1 chris #ifdef WEAK_ALIAS 33 1.1 chris WEAK_ALIAS(clone, __clone) 34 1.1 chris #endif 35 1.1 chris 36 1.1 chris /* 37 1.1 chris * int __clone(int (*fn)(void *), void *stack, int flags, void *arg); 38 1.1 chris */ 39 1.1 chris ENTRY(__clone) 40 1.1 chris 41 1.1 chris /* test stack and function are not null */ 42 1.8 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2) 43 1.8 matt cbz r0, .Leinval 44 1.8 matt cbz r1, .Leinval 45 1.8 matt #elif !defined(__thumb__) 46 1.8 matt cmp r0, #0x00 47 1.8 matt cmpne r1, #0x00 48 1.8 matt beq .Leinval 49 1.8 matt #else 50 1.8 matt cmp r0, #0x00 51 1.8 matt beq .Leinval 52 1.8 matt cmp r1, #0x00 53 1.2 thorpej beq .Leinval 54 1.8 matt #endif 55 1.1 chris 56 1.6 snj /* place the func and its arg onto the child's stack */ 57 1.8 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 58 1.12 skrll stmfd r1!, {r0, r3} 59 1.8 matt #else 60 1.8 matt subs r1, r1, #8 61 1.12 skrll stmia r1!, {r0, r3} 62 1.8 matt #endif 63 1.12 skrll 64 1.1 chris /* syscall expects (flags, stack) */ 65 1.1 chris mov r0, r2 66 1.1 chris 67 1.1 chris SYSTRAP(__clone) 68 1.8 matt _INVOKE_CERROR() 69 1.1 chris 70 1.1 chris /* 71 1.1 chris * r1 and r0 are the same as from fork: 72 1.1 chris * r1 == 0 in parent process, r1 == 1 in child process. 73 1.1 chris * r0 == pid of child in parent, r0 == pid of parent in child. 74 1.1 chris */ 75 1.1 chris /* if this is the parent then just return the pid */ 76 1.8 matt #if defined(__thumb__) 77 1.8 matt #if defined(_ARM_ARCH_T2) 78 1.8 matt cbz r1, 1f 79 1.8 matt #else 80 1.8 matt cmp r1, #0x00 81 1.8 matt bne 1f 82 1.8 matt #endif 83 1.8 matt RET 84 1.8 matt 1: 85 1.8 matt #else 86 1.8 matt cmp r1, #0x00 87 1.5 rearnsha RETc(eq) 88 1.8 matt #endif 89 1.8 matt 90 1.1 chris /* 91 1.1 chris * This is the child 92 1.1 chris * load the function and arg off the stack 93 1.1 chris */ 94 1.8 matt pop {r1, r2} 95 1.1 chris 96 1.1 chris /* place arg in r0 */ 97 1.1 chris mov r0, r2 98 1.1 chris 99 1.1 chris /* call the function */ 100 1.8 matt #ifdef _ARM_ARCH_5T 101 1.8 matt blx r1 102 1.5 rearnsha #else 103 1.8 matt /* setup return address */ 104 1.8 matt mov lr, pc 105 1.8 matt RETr(r1) 106 1.5 rearnsha #endif 107 1.1 chris /* call _exit with the returned value */ 108 1.9 joerg bl PLT_SYM(_C_LABEL(_exit)) 109 1.1 chris 110 1.1 chris /* NOTREACHED */ 111 1.1 chris 112 1.1 chris /* error handler if func or stack is NULL */ 113 1.8 matt .align 0 114 1.2 thorpej .Leinval: 115 1.8 matt movs r0, #EINVAL 116 1.8 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 117 1.7 matt b CERROR 118 1.8 matt #else 119 1.8 matt .Lcerror: 120 1.14 skrll push {r3, lr} 121 1.8 matt bl CERROR 122 1.14 skrll pop {r3, pc} 123 1.8 matt #endif 124 1.8 matt END(__clone) 125