1/* Copyright (C) 2000-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#include <tls.h> 23#define _ERRNO_H 1 24#include <bits/errno.h> 25 26/* int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, 27 pid_t *parent_tid, void *tls, pid_t *child_tid); */ 28/* sys_clone (void *child_stack, unsigned long flags, 29 pid_t *parent_tid, pid_t *child_tid, void *tls); */ 30 31 .text 32ENTRY(__clone) 33 st %r6,24(%r15) /* store %r6 to save area */ 34 cfi_offset (%r6, -72) 35 ltr %r1,%r2 /* check fn and move to %r1 */ 36 jz error /* no NULL function pointers */ 37 lhi %r0,-8 /* Align the child_stack to a ... */ 38 nr %r3,%r0 /* double word boundary and ... */ 39 jz error /* avoid NULL stack pointers. */ 40 lr %r0,%r5 /* move *arg out of the way */ 41 lr %r2,%r3 /* move child_stack to %r2 */ 42 lr %r3,%r4 /* move flags to %r3 */ 43 lr %r4,%r6 /* move parent_tid to %r4 */ 44 l %r5,100(%r15) /* load child_tid from stack */ 45 l %r6,96(%r15) /* load tls from stack */ 46 svc SYS_ify(clone) 47 ltr %r2,%r2 /* check return code */ 48 jz thread_start 49 l %r6,24(%r15) /* restore %r6 */ 50 jm SYSCALL_ERROR_LABEL 51 br %r14 52error: 53 lhi %r2,-EINVAL 54 j SYSCALL_ERROR_LABEL 55PSEUDO_END (__clone) 56 57thread_start: 58 cfi_startproc 59 /* Mark r14 as undefined in order to stop unwinding here! */ 60 cfi_undefined (r14) 61 /* fn is in gpr 1, arg in gpr 0 */ 62 lr %r2,%r0 /* set first parameter to void *arg */ 63 ahi %r15,-96 /* make room on the stack for the save area */ 64 xc 0(4,%r15),0(%r15) 65 basr %r14,%r1 /* jump to fn */ 66 DO_CALL (exit, 1) 67 cfi_endproc 68 69libc_hidden_def (__clone) 70weak_alias (__clone, clone) 71