1/* Wrapper around clone system call. 64 bit S/390 version. 2 Copyright (C) 2001-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 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 <https://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 <sysdep.h> 23#include <tls.h> 24#define _ERRNO_H 1 25#include <bits/errno.h> 26 27/* int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, 28 pid_t *parent_tid, void *tls, pid_t *child_tid); */ 29/* sys_clone (void *child_stack, unsigned long flags, 30 pid_t *parent_tid, pid_t *child_tid, void *tls); */ 31 32 .text 33ENTRY(__clone) 34 stg %r6,48(%r15) /* store %r6 to save area */ 35 cfi_offset (%r6,-112) 36 ltgr %r1,%r2 /* check fn and move to %r1 */ 37 jz error /* no NULL function pointers */ 38 lghi %r0,-16 /* Align the child_stack to a ... */ 39 ngr %r3,%r0 /* double word boundary and ... */ 40 jz error /* avoid NULL stack pointers. */ 41 lgr %r0,%r5 /* move *arg out of the way */ 42 lgr %r2,%r3 /* move child_stack to %r2 */ 43 lgr %r3,%r4 /* move flags to %r3 */ 44 lgr %r4,%r6 /* move parent_tid to %r4 */ 45 lg %r5,168(%r15) /* load child_tid from stack */ 46 lg %r6,160(%r15) /* load tls from stack */ 47 svc SYS_ify(clone) 48 ltgr %r2,%r2 /* check return code */ 49 jz thread_start 50 lg %r6,48(%r15) /* restore %r6 */ 51 jgm SYSCALL_ERROR_LABEL 52 br %r14 53error: 54 lghi %r2,-EINVAL 55 jg SYSCALL_ERROR_LABEL 56PSEUDO_END (__clone) 57 58thread_start: 59 cfi_startproc 60 /* Mark r14 as undefined in order to stop unwinding here! */ 61 cfi_undefined (r14) 62 /* fn is in gpr 1, arg in gpr 0 */ 63 lgr %r2,%r0 /* set first parameter to void *arg */ 64 aghi %r15,-160 /* make room on the stack for the save area */ 65 xc 0(8,%r15),0(%r15) 66 basr %r14,%r1 /* jump to fn */ 67 DO_CALL (exit, 1) 68 cfi_endproc 69 70libc_hidden_def (__clone) 71weak_alias (__clone, clone) 72