Update copyright notices with scripts/update-copyrights
[glibc.git] / ports / sysdeps / unix / sysv / linux / hppa / clone.S
blob1a3c6c800d5b421d3b2cb0ae392432b9f3a1325b
1 /* Copyright (C) 1996-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by David Huggins-Daines <dhd@debian.org>, 2000.
4    Based on the Alpha version by Richard Henderson <rth@tamu.edu>, 1996.
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library.  If not, see
18    <http://www.gnu.org/licenses/>.  */
20 /* clone() is even more special than fork() as it mucks with stacks
21    and invokes a function in the right context after its all over.  */
23 #include <asm/unistd.h>
24 #include <sysdep.h>
25 #define _ERRNO_H        1
26 #include <bits/errno.h>
28 /* Non-thread code calls __clone with the following parameters:
29    int clone(int (*fn)(void *arg),
30              void *child_stack,
31              int flags,
32              void *arg)
34    NPTL Code will call __clone with the following parameters:
35    int clone(int (*fn)(void *arg),
36              void *child_stack,
37              int flags,
38              void *arg,
39              int *parent_tidptr,
40              struct user_desc *newtls,
41              int *child_pidptr)
43    The code should not mangle the extra input registers.
44    Syscall expects:                             Input to __clone:
45         4(r25) - function pointer               (r26, arg0)
46         0(r25) - argument                       (r23, arg3)
47         r26 - clone flags.                      (r24, arg2)
48         r25+64 - user stack pointer.            (r25, arg1)
49         r24 - parent tid pointer.               (stack - 52)
50         r23 - struct user_desc newtls pointer.  (stack - 56)
51         r22 - child tid pointer.                (stack - 60)
52         r20 - clone syscall number              (constant)
54    Return:
56         On success the thread ID of the child process is returend in
57         the callers context.
58         On error return -1, and set errno to the value returned by
59         the syscall.
60  */
62         .text
63 ENTRY(__clone)
64         /* Prologue */
65         stwm    %r4, 64(%sp)
66         stw     %sp, -4(%sp)
67 #ifdef PIC
68         stw     %r19, -32(%sp)
69 #endif
71         /* Sanity check arguments.  */
72         comib,=,n  0, %arg0, .LerrorSanity        /* no NULL function pointers */
73         comib,=,n  0, %arg1, .LerrorSanity        /* no NULL stack pointers */
75         /* Save the function pointer, arg, and flags on the new stack.  */
76         stwm    %r26, 64(%r25)
77         stw     %r23, -60(%r25)
78         stw     %r24, -56(%r25)
79         /* Clone arguments are (int flags, void * child_stack) */
80         copy    %r24, %r26              /* flags are first */
81         /* User stack pointer is in the correct register already */
83         /* Load args from stack... */
84         ldw     -116(%sp), %r24         /* Load parent_tidptr */
85         ldw     -120(%sp), %r23         /* Load newtls */
86         ldw     -124(%sp), %r22         /* Load child_tidptr */
88         /* Save the PIC register. */
89 #ifdef PIC
90         copy    %r19, %r4               /* parent */
91 #endif
93         /* Do the system call */
94         ble     0x100(%sr2, %r0)
95         ldi     __NR_clone, %r20
97         ldi     -4096, %r1
98         comclr,>>= %r1, %ret0, %r0      /* Note: unsigned compare. */
99         b,n     .LerrorRest
101         /* Restore the PIC register.  */
102 #ifdef PIC
103         copy    %r4, %r19               /* parent */
104 #endif
106         comib,=,n 0, %ret0, .LthreadStart
108         /* Successful return from the parent
109            No need to restore the PIC register,
110            since we return immediately. */
112         ldw     -84(%sp), %rp
113         bv      %r0(%rp)
114         ldwm    -64(%sp), %r4
116 .LerrorRest:
117         /* Something bad happened -- no child created */
118         bl      __syscall_error, %rp
119         sub     %r0, %ret0, %arg0
120         ldw     -84(%sp), %rp
121         /* Return after setting errno, ret0 is set to -1 by __syscall_error. */
122         bv      %r0(%rp)
123         ldwm    -64(%sp), %r4
125 .LerrorSanity:
126         /* Sanity checks failed, return -1, and set errno to EINVAL. */
127         bl      __syscall_error, %rp
128         ldi     EINVAL, %arg0
129         ldw     -84(%sp), %rp
130         bv      %r0(%rp)
131         ldwm    -64(%sp), %r4
133 .LthreadStart:
134 #ifdef RESET_PID
135 # define CLONE_VM_BIT           23      /* 0x00000100  */
136 # define CLONE_THREAD_BIT       15      /* 0x00010000  */
137         /* Load original clone flags.
138            If CLONE_THREAD was passed, don't reset the PID/TID.
139            If CLONE_VM was passed, we need to store -1 to PID/TID.
140            If CLONE_VM and CLONE_THREAD were not set store the result
141            of getpid to PID/TID.  */
142         ldw     -56(%sp), %r26
143         bb,<,n  %r26, CLONE_THREAD_BIT, 1f
144         bb,<    %r26, CLONE_VM_BIT, 2f
145         ldi     -1, %ret0
146         ble     0x100(%sr2, %r0)
147         ldi     __NR_getpid, %r20
149         mfctl   %cr27, %r26
150         stw     %ret0, PID_THREAD_OFFSET(%r26)
151         stw     %ret0, TID_THREAD_OFFSET(%r26)
153 #endif
154         /* Load up the arguments.  */
155         ldw     -60(%sp), %arg0
156         ldw     -64(%sp), %r22
158         /* $$dyncall fixes child's PIC register */
160         /* Call the user's function */
161 #ifdef PIC
162         copy    %r19, %r4
163 #endif
164         bl      $$dyncall, %r31
165         copy    %r31, %rp
166 #ifdef PIC
167         copy    %r4, %r19
168 #endif
169         /* The call to _exit needs saved r19.  */
170         bl      _exit, %rp
171         copy    %ret0, %arg0
173         /* We should not return from _exit.
174            We do not restore r4, or the stack state.  */
175         iitlbp  %r0, (%sr0, %r0)
177 PSEUDO_END(__clone)
179 weak_alias (__clone, clone)