Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / hppa / clone.S
blob25525ba182a99cb7ebe522492eec99c151681fca
1 /* Copyright (C) 1996-2015 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>
27 #include <tcb-offsets.h>
29 /* Non-thread code calls __clone with the following parameters:
30    int clone(int (*fn)(void *arg),
31              void *child_stack,
32              int flags,
33              void *arg)
35    NPTL Code will call __clone with the following parameters:
36    int clone(int (*fn)(void *arg),
37              void *child_stack,
38              int flags,
39              void *arg,
40              int *parent_tidptr,
41              struct user_desc *newtls,
42              int *child_pidptr)
44    The code should not mangle the extra input registers.
45    Syscall expects:                             Input to __clone:
46         4(r25) - function pointer               (r26, arg0)
47         0(r25) - argument                       (r23, arg3)
48         r26 - clone flags.                      (r24, arg2)
49         r25+64 - user stack pointer.            (r25, arg1)
50         r24 - parent tid pointer.               (stack - 52)
51         r23 - struct user_desc newtls pointer.  (stack - 56)
52         r22 - child tid pointer.                (stack - 60)
53         r20 - clone syscall number              (constant)
55    Return:
57         On success the thread ID of the child process is returend in
58         the callers context.
59         On error return -1, and set errno to the value returned by
60         the syscall.
61  */
63         .text
64 ENTRY(__clone)
65         /* Prologue */
66         stwm    %r4, 64(%sp)
67         stw     %sp, -4(%sp)
68 #ifdef PIC
69         stw     %r19, -32(%sp)
70 #endif
72         /* Sanity check arguments.  */
73         comib,=,n  0, %arg0, .LerrorSanity        /* no NULL function pointers */
74         comib,=,n  0, %arg1, .LerrorSanity        /* no NULL stack pointers */
76         /* Save the function pointer, arg, and flags on the new stack.  */
77         stwm    %r26, 64(%r25)
78         stw     %r23, -60(%r25)
79         stw     %r24, -56(%r25)
80         /* Clone arguments are (int flags, void * child_stack) */
81         copy    %r24, %r26              /* flags are first */
82         /* User stack pointer is in the correct register already */
84         /* Load args from stack... */
85         ldw     -116(%sp), %r24         /* Load parent_tidptr */
86         ldw     -120(%sp), %r23         /* Load newtls */
87         ldw     -124(%sp), %r22         /* Load child_tidptr */
89         /* Save the PIC register. */
90 #ifdef PIC
91         copy    %r19, %r4               /* parent */
92 #endif
94         /* Do the system call */
95         ble     0x100(%sr2, %r0)
96         ldi     __NR_clone, %r20
98         ldi     -4096, %r1
99         comclr,>>= %r1, %ret0, %r0      /* Note: unsigned compare. */
100         b,n     .LerrorRest
102         /* Restore the PIC register.  */
103 #ifdef PIC
104         copy    %r4, %r19               /* parent */
105 #endif
107         comib,=,n 0, %ret0, .LthreadStart
109         /* Successful return from the parent
110            No need to restore the PIC register,
111            since we return immediately. */
113         ldw     -84(%sp), %rp
114         bv      %r0(%rp)
115         ldwm    -64(%sp), %r4
117 .LerrorRest:
118         /* Something bad happened -- no child created */
119         bl      __syscall_error, %rp
120         sub     %r0, %ret0, %arg0
121         ldw     -84(%sp), %rp
122         /* Return after setting errno, ret0 is set to -1 by __syscall_error. */
123         bv      %r0(%rp)
124         ldwm    -64(%sp), %r4
126 .LerrorSanity:
127         /* Sanity checks failed, return -1, and set errno to EINVAL. */
128         bl      __syscall_error, %rp
129         ldi     EINVAL, %arg0
130         ldw     -84(%sp), %rp
131         bv      %r0(%rp)
132         ldwm    -64(%sp), %r4
134 .LthreadStart:
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         /* Load up the arguments.  */
154         ldw     -60(%sp), %arg0
155         ldw     -64(%sp), %r22
157         /* $$dyncall fixes child's PIC register */
159         /* Call the user's function */
160 #ifdef PIC
161         copy    %r19, %r4
162 #endif
163         bl      $$dyncall, %r31
164         copy    %r31, %rp
165 #ifdef PIC
166         copy    %r4, %r19
167 #endif
168         /* The call to _exit needs saved r19.  */
169         bl      _exit, %rp
170         copy    %ret0, %arg0
172         /* We should not return from _exit.
173            We do not restore r4, or the stack state.  */
174         iitlbp  %r0, (%sr0, %r0)
176 PSEUDO_END(__clone)
178 weak_alias (__clone, clone)