summaryrefslogtreecommitdiffstats
path: root/libc/arch-arm
diff options
context:
space:
mode:
Diffstat (limited to 'libc/arch-arm')
-rw-r--r--libc/arch-arm/bionic/clone.S108
-rw-r--r--libc/arch-arm/syscalls.mk2
-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