Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / arm / clone.S
blob9269c687d25a7f81b92aee1cac6fc78a21aead90
1 /* Copyright (C) 1996-2015 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Pat Beirne <patb@corelcomputer.com>
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library.  If not, see
17    <http://www.gnu.org/licenses/>.  */
19 /* clone() is even more special than fork() as it mucks with stacks
20    and invokes a function in the right context after its all over.  */
22 #include <sysdep.h>
23 #include <tcb-offsets.h>
24 #define _ERRNO_H        1
25 #include <bits/errno.h>
27 #define CLONE_VM      0x00000100
28 #define CLONE_THREAD  0x00010000
30 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
31              pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
33         .text
34 ENTRY(__clone)
35         @ sanity check args
36         cmp     r0, #0
37         ite     ne
38         cmpne   r1, #0
39         moveq   r0, #-EINVAL
40         beq     PLTJMP(syscall_error)
42         @ insert the args onto the new stack
43         str     r3, [r1, #-4]!
44         str     r0, [r1, #-4]!
46         @ do the system call
47         @ get flags
48         mov     r0, r2
49         mov     ip, r2
50         @ new sp is already in r1
51         push    {r4, r7}
52         cfi_adjust_cfa_offset (8)
53         cfi_rel_offset (r4, 0)
54         cfi_rel_offset (r7, 4)
55         ldr     r2, [sp, #8]
56         ldr     r3, [sp, #12]
57         ldr     r4, [sp, #16]
58         ldr     r7, =SYS_ify(clone)
59         swi     0x0
60         cfi_endproc
61         cmp     r0, #0
62         beq     1f
63         pop     {r4, r7}
64         blt     PLTJMP(C_SYMBOL_NAME(__syscall_error))
65         RETINSTR(, lr)
67         cfi_startproc
68 PSEUDO_END (__clone)
71         .fnstart
72         .cantunwind
73         tst     ip, #CLONE_THREAD
74         bne     3f
75         GET_TLS (lr)
76         mov     r1, r0
77         tst     ip, #CLONE_VM
78         ldr     r7, =SYS_ify(getpid)
79         ite     ne
80         movne   r0, #-1
81         swieq   0x0
82         NEGOFF_ADJ_BASE (r1, TID_OFFSET)
83         str     r0, NEGOFF_OFF1 (r1, TID_OFFSET)
84         str     r0, NEGOFF_OFF2 (r1, PID_OFFSET, TID_OFFSET)
86         @ pick the function arg and call address off the stack and execute
87         ldr     r0, [sp, #4]
88         ldr     ip, [sp], #8
89         BLX (ip)
91         @ and we are done, passing the return value through r0
92         b       PLTJMP(HIDDEN_JUMPTARGET(_exit))
94         .fnend
96 weak_alias (__clone, clone)