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 <tls.h> 25 26/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, 27 void *parent_tidptr, void *tls, void *child_tidptr) */ 28 29 .text 30ENTRY (__clone) 31 32 /* Sanity check arguments. */ 33 movel #-EINVAL, %d0 34 movel 4(%sp), %a0 /* no NULL function pointers */ 35 tstl %a0 36 jeq SYSCALL_ERROR_LABEL 37 movel 8(%sp), %a1 /* no NULL stack pointers */ 38 tstl %a1 39 jeq SYSCALL_ERROR_LABEL 40 41 /* Allocate space and copy the argument onto the new stack. */ 42 movel 16(%sp), -(%a1) 43 44 /* Do the system call */ 45 movel 12+0(%sp), %d1 /* get flags */ 46 movel %d3, -(%a1) /* save %d3 and get parent_tidptr */ 47 movel %d3, -(%sp) 48 cfi_adjust_cfa_offset (4) 49 cfi_rel_offset (%d3, 0) 50 movel 20+4(%sp), %d3 51 movel %d4, -(%a1) /* save %d4 and get child_tidptr */ 52 movel %d4, -(%sp) 53 cfi_adjust_cfa_offset (4) 54 cfi_rel_offset (%d4, 0) 55 movel 28+8(%sp), %d4 56 movel %d5, -(%a1) /* save %d5 and get tls */ 57 movel %d5, -(%sp) 58 cfi_adjust_cfa_offset (4) 59 cfi_rel_offset (%d5, 0) 60 movel 24+12(%sp), %d5 61 /* save %d2 and get stack pointer */ 62#ifdef __mcoldfire__ 63 movel %d2, -(%a1) 64 movel %d2, -(%sp) 65 cfi_adjust_cfa_offset (4) 66 cfi_rel_offset (%d2, 0) 67 movel %a1, %d2 68#else 69 exg %d2, %a1 /* save %d2 and get stack pointer */ 70 cfi_register (%d2, %a1) 71#endif 72 movel #SYS_ify (clone), %d0 73 74 /* End FDE now, because in the child the unwind info will be 75 wrong. */ 76 cfi_endproc 77 78 trap #0 79#ifdef __mcoldfire__ 80 movel (%sp)+, %d2 81#else 82 exg %d2, %a1 /* restore %d2 */ 83#endif 84 movel (%sp)+, %d5 /* restore %d5, %d4 and %d3 */ 85 movel (%sp)+, %d4 86 movel (%sp)+, %d3 87 88 tstl %d0 89 jmi SYSCALL_ERROR_LABEL 90 jeq 1f 91 92 rts 93 941: 95 cfi_startproc 96 cfi_undefined (pc) /* Mark end of stack */ 97 subl %fp, %fp /* terminate the stack frame */ 98 jsr (%a0) 99 movel %d0, %d1 100 movel #SYS_ify (exit), %d0 101 trap #0 102 cfi_endproc 103 104 cfi_startproc 105PSEUDO_END (__clone) 106 107libc_hidden_def (__clone) 108weak_alias (__clone, clone) 109