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