1405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* 2405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Copyright (C) 2008 The Android Open Source Project 3405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * All rights reserved. 4405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 5405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Redistribution and use in source and binary forms, with or without 6405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * modification, are permitted provided that the following conditions 7405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * are met: 8405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Redistributions of source code must retain the above copyright 9405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * notice, this list of conditions and the following disclaimer. 10405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Redistributions in binary form must reproduce the above copyright 11405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * notice, this list of conditions and the following disclaimer in 12405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * the documentation and/or other materials provided with the 13405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * distribution. 14405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 15405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * SUCH DAMAGE. 27405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham */ 2856d161bb62225cea969b49c97ae732d1845e5304Elliott Hughes 2956d161bb62225cea969b49c97ae732d1845e5304Elliott Hughes#include <asm/unistd.h> 30405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#include <linux/errno.h> 3156d161bb62225cea969b49c97ae732d1845e5304Elliott Hughes#include <linux/sched.h> 3240eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes 33405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .text 34405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .type __pthread_clone, @function 35405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .global __pthread_clone 36405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .align 4 37405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .ent __pthread_clone 3840eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes 39405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* 4040eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes * int __pthread_clone(void* (*fn)(void*), void *child_stack, 41405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * int flags, void *arg); 42405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham */ 43405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 44405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham__pthread_clone: 45405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .set noreorder 46405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .cpload $t9 47405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .set reorder 48405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 49405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # set up child stack 50405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham subu $a1,16 51405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham sw $a0,0($a1) # fn 52405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham sw $a3,4($a1) # arg 53405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham# sw $a1+16,8($a1) # tls 54405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 55405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* 56405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * int sys_clone(int flags, void *child_stack, int *parent_tidptr, 57405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * struct user_desc *newtls, int *child_tidptr); 58405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham */ 59405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 60405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham move $a0,$a2 # flags 61405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham# move $a1,$a1 # child_stack 62405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham move $a2,$0 # parent_tidptr 63405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham move $a3,$0 # user_desc 64405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham and $a0,~(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) 65405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # make sure the kernel doesn't access child_tidptr 66405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 67405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham li $v0,__NR_clone 68405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham syscall 69405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 70405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham bnez $a3,.L__error 71405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 72405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham beqz $v0,.L__thread_start 7340eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes 74405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham j $ra 75405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 76405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham.L__thread_start: 77405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham lw $a0,0($sp) # fn 78405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham lw $a1,4($sp) # arg 79405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham addu $a2,$sp,16 # tls 80405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 8140eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes # void __thread_entry(void* (*func)(void*), void *arg, void *tls) 82405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham la $t9, __thread_entry 83405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham j $t9 84405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 85405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham.L__error: 86405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham move $a0,$v0 87405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham la $t9,__set_errno 88405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham j $t9 89405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 90405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .end __pthread_clone 91405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 92405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 93405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # 94405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # This function is defined as: 95405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # 96405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # pid_t __bionic_clone( int flags, void *child_stack, 97405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # pid_t *pid, void *tls, pid_t *ctid, 98405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # int (*fn)(void *), void* arg ); 99405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # 100405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # NOTE: This is not the same signature than the GLibc 101405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # __clone function here !! Placing 'fn' and 'arg' 102405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # at the end of the parameter list makes the 103405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # implementation much simpler. 104405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # 105405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .text 106405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .type __bionic_clone, @function 107405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .global __bionic_clone 108405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .align 4 109405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .ent __bionic_clone 110405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham__bionic_clone: 111405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .set noreorder 112405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .cpload $t9 113405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .set reorder 114405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 115405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # set up child stack 116405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham subu $a1,16 117405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham lw $t0,20($sp) # fn 118405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham lw $t1,24($sp) # arg 119405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham sw $t0,0($a1) # fn 120405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham sw $t1,4($a1) # arg 121405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 122405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # remainder of arguments are correct for clone system call 123405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham li $v0,__NR_clone 124405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham syscall 125405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 126405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham bnez $a3,.L__error_bc 127405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 128405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham beqz $v0,.L__thread_start_bc 12940eabe24e4e3ae8ebe437f1f4e43cf39cbba2e9eElliott Hughes 130405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham j $ra 131405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 132405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham.L__thread_start_bc: 133405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham lw $a0,0($sp) # fn 134405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham lw $a1,4($sp) # arg 135405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 136405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham # void __bionic_clone_entry(int (*func)(void*), void *arg) 137405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham la $t9,__bionic_clone_entry 138405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham j $t9 139405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 140405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham.L__error_bc: 141405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham move $a0,$v0 142405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham la $t9,__set_errno 143405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham j $t9 144405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 145405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham .end __bionic_clone 146