1! Copyright (C) 2013 Imagination Technologies Ltd. 2 3! Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. 4 5! clone() is even more special than fork() as it mucks with stacks 6! and invokes a function in the right context after its all over. 7 8#include <asm/errno.h> 9#include <asm/unistd.h> 10 11#define CLONE_VM 0x00000100 12#define CLONE_THREAD 0x00010000 13 14#ifdef __PIC__ 15#define __CLONE_METAG_LOAD_TP ___metag_load_tp@PLT 16#else 17#define __CLONE_METAG_LOAD_TP ___metag_load_tp 18#endif 19 20/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, 21 pid_t *ptid, struct user_desc *tls, pid_t *ctid); */ 22 23 .text 24 .global __clone 25 .type __clone,function 26__clone: 27 ! sanity check args 28 MOV D0Re0, #-EINVAL 29 CMP D1Ar1, #0 30 BEQ ___error 31 CMP D0Ar2, #0 32 BEQ ___error 33 34 ! save function pointer 35 MOV D0FrT, D1Ar1 36 37 ! do the system call 38 MOV D1Ar1, D1Ar3 39 MOV D1Ar3, D1Ar5 40 MOV D1Ar5, D0Ar6 41 MOV D0Ar6, D0Ar4 42 GETD D0Ar4, [A0StP+#-4] 43 44 ! new sp is already in D0Ar2 45 MOV D1Re0, #__NR_clone 46 SWITCH #0x440001 47 CMP D0Re0,#0 48 ! Error on -1 49 BLT ___error 50 ! If non-zero we are the parent 51 MOVNE PC, D1RtP 52 ! BRKPNT 53 54 ! We are the child 55 ! Rearrange the function arg and call address from registers 56 MOV D0Ar2, D0FrT 57 MOV D1Ar1, D0Ar6 58 MOV D1RtP, PC 59 ADD D1RtP, D1RtP, #8 60 MOV PC, D0Ar2 61 62 ! and we are done, passing the return value D0Re0 through D1Ar1 63 MOV D1Ar1, D0Re0 64#ifdef __PIC__ 65 B _exit@PLT 66#else 67 B _exit 68#endif 69 70___error: 71 MOV D1Ar1, D0Re0 72#ifdef __PIC__ 73 B ___syscall_error@PLT 74#else 75 B ___syscall_error 76#endif 77 .size __clone, .-__clone 78 79.weak _clone 80_clone = __clone 81