1/* Copyright (C) 1996-2018 Free Software Foundation, Inc. 2 Contributed by David Huggins-Daines <dhd@debian.org>, 2000. 3 Based on the Alpha version by Richard Henderson <rth@tamu.edu>, 1996. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library. If not, see 17 <http://www.gnu.org/licenses/>. */ 18 19/* clone() is even more special than fork() as it mucks with stacks 20 and invokes a function in the right context after its all over. */ 21 22#include <asm/unistd.h> 23#include <sysdep.h> 24#define _ERRNO_H 1 25#include <bits/errno.h> 26 27/* Non-thread code calls __clone with the following parameters: 28 int clone(int (*fn)(void *arg), 29 void *child_stack, 30 int flags, 31 void *arg) 32 33 NPTL Code will call __clone with the following parameters: 34 int clone(int (*fn)(void *arg), 35 void *child_stack, 36 int flags, 37 void *arg, 38 int *parent_tidptr, 39 struct user_desc *newtls, 40 int *child_pidptr) 41 42 The code should not mangle the extra input registers. 43 Syscall expects: Input to __clone: 44 4(r25) - function pointer (r26, arg0) 45 0(r25) - argument (r23, arg3) 46 r26 - clone flags. (r24, arg2) 47 r25+64 - user stack pointer. (r25, arg1) 48 r24 - parent tid pointer. (stack - 52) 49 r23 - struct user_desc newtls pointer. (stack - 56) 50 r22 - child tid pointer. (stack - 60) 51 r20 - clone syscall number (constant) 52 53 Return: 54 55 On success the thread ID of the child process is returend in 56 the callers context. 57 On error return -1, and set errno to the value returned by 58 the syscall. 59 */ 60 61 .text 62ENTRY(__clone) 63 /* Prologue */ 64 stwm %r4, 64(%sp) 65 .cfi_def_cfa_offset -64 66 .cfi_offset 4, 0 67 stw %sp, -4(%sp) 68#ifdef __PIC__ 69 stw %r19, -32(%sp) 70 .cfi_offset 19, 32 71#endif 72 73 /* Sanity check arguments. */ 74 comib,=,n 0, %arg0, .LerrorSanity /* no NULL function pointers */ 75 comib,=,n 0, %arg1, .LerrorSanity /* no NULL stack pointers */ 76 77 /* Save the function pointer, arg, and flags on the new stack. */ 78 stwm %r26, 64(%r25) 79 stw %r23, -60(%r25) 80 stw %r24, -56(%r25) 81 /* Clone arguments are (int flags, void * child_stack) */ 82 copy %r24, %r26 /* flags are first */ 83 /* User stack pointer is in the correct register already */ 84 85 /* Load args from stack... */ 86 ldw -116(%sp), %r24 /* Load parent_tidptr */ 87 ldw -120(%sp), %r23 /* Load newtls */ 88 ldw -124(%sp), %r22 /* Load child_tidptr */ 89 90 /* Save the PIC register. */ 91#ifdef __PIC__ 92 copy %r19, %r4 /* parent */ 93#endif 94 95 /* Do the system call */ 96 ble 0x100(%sr2, %r0) 97 ldi __NR_clone, %r20 98 99 ldi -4096, %r1 100 comclr,>>= %r1, %ret0, %r0 /* Note: unsigned compare. */ 101 b,n .LerrorRest 102 103 /* Restore the PIC register. */ 104#ifdef __PIC__ 105 copy %r4, %r19 /* parent */ 106#endif 107 108 comib,=,n 0, %ret0, .LthreadStart 109 110 /* Successful return from the parent 111 No need to restore the PIC register, 112 since we return immediately. */ 113 114 ldw -84(%sp), %rp 115 bv %r0(%rp) 116 ldwm -64(%sp), %r4 117 118.LerrorRest: 119 /* Something bad happened -- no child created */ 120 bl __syscall_error, %rp 121 sub %r0, %ret0, %arg0 122 ldw -84(%sp), %rp 123 /* Return after setting errno, ret0 is set to -1 by __syscall_error. */ 124 bv %r0(%rp) 125 ldwm -64(%sp), %r4 126 127.LerrorSanity: 128 /* Sanity checks failed, return -1, and set errno to EINVAL. */ 129 bl __syscall_error, %rp 130 ldi EINVAL, %arg0 131 ldw -84(%sp), %rp 132 bv %r0(%rp) 133 ldwm -64(%sp), %r4 134 135.LthreadStart: 136 /* Load up the arguments. */ 137 ldw -60(%sp), %arg0 138 ldw -64(%sp), %r22 139 140 /* $$dyncall fixes child's PIC register */ 141 142 /* Call the user's function */ 143#ifdef __PIC__ 144 copy %r19, %r4 145#endif 146 bl $$dyncall, %r31 147 copy %r31, %rp 148#ifdef __PIC__ 149 copy %r4, %r19 150#endif 151 copy %r28, %r26 152 ble 0x100(%sr2, %r0) 153 ldi __NR_exit, %r20 154 155 /* We should not return from exit. 156 We do not restore r4, or the stack state. */ 157 iitlbp %r0, (%sr0, %r0) 158 159PSEUDO_END(__clone) 160 161libc_hidden_def (__clone) 162weak_alias (__clone, clone) 163