diff options
Diffstat (limited to 'libc/arch-arm')
-rw-r--r-- | libc/arch-arm/bionic/clone.S | 108 | ||||
-rw-r--r-- | libc/arch-arm/syscalls.mk | 2 | ||||
-rw-r--r-- | libc/arch-arm/syscalls/__sys_clone.S (renamed from libc/arch-arm/syscalls/__clone.S) | 14 |
3 files changed, 90 insertions, 34 deletions
diff --git a/libc/arch-arm/bionic/clone.S b/libc/arch-arm/bionic/clone.S index 791c73d..9c25053 100644 --- a/libc/arch-arm/bionic/clone.S +++ b/libc/arch-arm/bionic/clone.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2008-2010 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,48 +27,102 @@ */ #include <sys/linux-syscalls.h> - .text - .type __pthread_clone, #function - .global __pthread_clone - .align 4 - + .text + .type __pthread_clone, #function + .global __pthread_clone + .align 4 + .fnstart + __pthread_clone: - @ insert the args onto the new stack - str r0, [r1, #-4] - str r3, [r1, #-8] + @ insert the args onto the new stack + str r0, [r1, #-4] + str r3, [r1, #-8] + + @ do the system call + @ get flags - @ do the system call - @ get flags - mov r0, r2 - + @ new sp is already in r1 #if __ARM_EABI__ stmfd sp!, {r4, r7} ldr r7, =__NR_clone - swi #0 + swi #0 #else - swi #__NR_clone + swi #__NR_clone #endif - movs r0, r0 + movs r0, r0 #if __ARM_EABI__ ldmnefd sp!, {r4, r7} #endif - blt __error - bxne lr + blt __error + bxne lr - @ pick the function arg and call address off the stack and jump - @ to the C __thread_entry function which does some setup and then - @ calls the thread's start function + @ pick the function arg and call address off the stack and jump + @ to the C __thread_entry function which does some setup and then + @ calls the thread's start function - ldr r0, [sp, #-4] - ldr r1, [sp, #-8] - mov r2, sp @ __thread_entry needs the TLS pointer - b __thread_entry + ldr r0, [sp, #-4] + ldr r1, [sp, #-8] + mov r2, sp @ __thread_entry needs the TLS pointer + b __thread_entry __error: - mov r0, #-1 - bx lr + mov r0, #-1 + bx lr + .fnend + + + # + # This function is defined as: + # + # pid_t __bionic_clone( int flags, void *child_stack, + # pid_t *pid, void *tls, pid_t *ctid, + # int (*fn)(void *), void* arg ); + # + # NOTE: This is not the same signature than the GLibc + # __clone function here !! Placing 'fn' and 'arg' + # at the end of the parameter list makes the + # implementation much simpler. + # + .type __bionic_clone, #function + .globl __bionic_clone + .align 4 + .fnstart + +__bionic_clone: + mov ip, sp + .save {r4, r5, r6, r7} + + # save registers to parent stack + stmfd sp!, {r4, r5, r6, r7} + + # load extra parameters + ldmfd ip, {r4, r5, r6} + + # store 'fn' and 'arg' to the child stack + str r5, [r1, #-4] + str r6, [r1, #-8] + + # system call + ldr r7, =__NR_clone + swi #0 + movs r0, r0 + beq 1f + + # in parent, reload saved registers + # then either exit or error + # + ldmfd sp!, {r4, r5, r6, r7} + bxne lr + b __set_syscall_errno + +1: # in the child - pick arguments + ldr r0, [sp, #-4] + ldr r1, [sp, #-8] + b __bionic_clone_entry + + .fnend diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index 706cb0c..5f416e8 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -4,7 +4,7 @@ syscall_src += arch-arm/syscalls/_exit.S syscall_src += arch-arm/syscalls/_exit_thread.S syscall_src += arch-arm/syscalls/__fork.S syscall_src += arch-arm/syscalls/waitid.S -syscall_src += arch-arm/syscalls/__clone.S +syscall_src += arch-arm/syscalls/__sys_clone.S syscall_src += arch-arm/syscalls/execve.S syscall_src += arch-arm/syscalls/setuid.S syscall_src += arch-arm/syscalls/getuid.S diff --git a/libc/arch-arm/syscalls/__clone.S b/libc/arch-arm/syscalls/__sys_clone.S index 650e2c0..9fe2641 100644 --- a/libc/arch-arm/syscalls/__clone.S +++ b/libc/arch-arm/syscalls/__sys_clone.S @@ -2,17 +2,19 @@ #include <sys/linux-syscalls.h> .text - .type __clone, #function - .globl __clone + .type __sys_clone, #function + .globl __sys_clone .align 4 .fnstart -__clone: - .save {r4, r7} - stmfd sp!, {r4, r7} +__sys_clone: + mov ip, sp + .save {r4, r5, r6, r7} + stmfd sp!, {r4, r5, r6, r7} + ldmfd ip, {r4, r5, r6} ldr r7, =__NR_clone swi #0 - ldmfd sp!, {r4, r7} + ldmfd sp!, {r4, r5, r6, r7} movs r0, r0 bxpl lr b __set_syscall_errno |