11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 297cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner * Copyright (C) 2008-2010 The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions of source code must retain the above copyright 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the documentation and/or other materials provided with the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 28f94fd3ccc66e05f53965bc14237778c0d8437bb6Elliott Hughes 29ed74484dcbc2e156a6e5fa861a62425b12e55128Elliott Hughes#include <private/bionic_asm.h> 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg); 32420878c6908cf9c2862888477ec3f424a06cf172Kenny RootENTRY(__bionic_clone) 3397cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner mov ip, sp 3497cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner # save registers to parent stack 3597cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner stmfd sp!, {r4, r5, r6, r7} 36ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_def_cfa_offset 16 37ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_rel_offset r4, 0 38ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_rel_offset r5, 4 39ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_rel_offset r6, 8 40ed45970ac5a182e512669cfa5c15b9f4fa783ad7Christopher Ferris .cfi_rel_offset r7, 12 4197cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner 4297cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner # load extra parameters 4397cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner ldmfd ip, {r4, r5, r6} 4497cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner 4597cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner # store 'fn' and 'arg' to the child stack 4697cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner str r5, [r1, #-4] 4797cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner str r6, [r1, #-8] 4897cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner 495e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes # System call 5097cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner ldr r7, =__NR_clone 5197cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner swi #0 5297cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner movs r0, r0 5397cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner beq 1f 5497cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner 559aceab50155b17741faded1fb22e2daa51a07fb1Elliott Hughes # In the parent, reload saved registers then either return or set errno. 5697cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner ldmfd sp!, {r4, r5, r6, r7} 579aceab50155b17741faded1fb22e2daa51a07fb1Elliott Hughes cmn r0, #(MAX_ERRNO + 1) 589aceab50155b17741faded1fb22e2daa51a07fb1Elliott Hughes bxls lr 599aceab50155b17741faded1fb22e2daa51a07fb1Elliott Hughes neg r0, r0 607efad83d430f4d824f2aaa75edea5106f6ff8aaeElliott Hughes b __set_errno_internal 6197cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner 625e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes1: # The child. 63ebc8cd117a562f387c52ed4e1aeba0fb21f33194Elliott Hughes # Setting lr to 0 will make the unwinder stop at __start_thread 648df0fe0c74b7af819f36e37ec9b924fdd22c8ba4Ben Cheng mov lr, #0 6597cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner ldr r0, [sp, #-4] 6697cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner ldr r1, [sp, #-8] 67ebc8cd117a562f387c52ed4e1aeba0fb21f33194Elliott Hughes b __start_thread 68420878c6908cf9c2862888477ec3f424a06cf172Kenny RootEND(__bionic_clone) 69954cf0d4e2669f91194b45f484152e47efa4f6c7Elliott Hughes.hidden __bionic_clone 70