Linux: make generic xstatver.h the default one
[glibc.git] / sysdeps / unix / sysv / linux / hppa / clone.S
blob65d16fd893bb310c20840f5e6e145ecc39d8cb3d
1 /* Copyright (C) 1996-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library.  If not, see
16    <https://www.gnu.org/licenses/>.  */
18 /* clone() is even more special than fork() as it mucks with stacks
19    and invokes a function in the right context after its all over.  */
21 #include <sysdep.h>
22 #define _ERRNO_H        1
23 #include <bits/errno.h>
24 #include <tcb-offsets.h>
26 /* Non-thread code calls __clone with the following parameters:
27    int clone(int (*fn)(void *arg),
28              void *child_stack,
29              int flags,
30              void *arg)
32    NPTL Code will call __clone with the following parameters:
33    int clone(int (*fn)(void *arg),
34              void *child_stack,
35              int flags,
36              void *arg,
37              int *parent_tidptr,
38              struct user_desc *newtls,
39              int *child_pidptr)
41    The code should not mangle the extra input registers.
42    Syscall expects:                             Input to __clone:
43         4(r25) - function pointer               (r26, arg0)
44         0(r25) - argument                       (r23, arg3)
45         r26 - clone flags.                      (r24, arg2)
46         r25+64 - user stack pointer.            (r25, arg1)
47         r24 - parent tid pointer.               (stack - 52)
48         r23 - struct user_desc newtls pointer.  (stack - 56)
49         r22 - child tid pointer.                (stack - 60)
50         r20 - clone syscall number              (constant)
52    Return:
54         On success the thread ID of the child process is returend in
55         the callers context.
56         On error return -1, and set errno to the value returned by
57         the syscall.
58  */
60         .text
61 ENTRY(__clone)
62         /* Prologue */
63         stwm    %r4, 64(%sp)
64         .cfi_def_cfa_offset -64
65         .cfi_offset 4, 0
66         stw     %sp, -4(%sp)
67 #ifdef PIC
68         stw     %r19, -32(%sp)
69         .cfi_offset 19, 32
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         /* Ensure stack argument is 8-byte aligned.  */
77         ldo             7(%r25),%r25
78         depi            0,31,3,%r25
80         /* Save the function pointer, arg, and flags on the new stack.  */
81         stwm    %r26, 64(%r25)
82         stw     %r23, -60(%r25)
83         stw     %r24, -56(%r25)
85         /* Clone arguments are (int flags, void * child_stack) */
86         copy    %r24, %r26              /* flags are first */
87         /* User stack pointer is in the correct register already */
89         /* Load args from stack... */
90         ldw     -116(%sp), %r24         /* Load parent_tidptr */
91         ldw     -120(%sp), %r23         /* Load newtls */
92         ldw     -124(%sp), %r22         /* Load child_tidptr */
94         /* Save the PIC register. */
95 #ifdef PIC
96         copy    %r19, %r4               /* parent */
97 #endif
99         /* Do the system call */
100         ble     0x100(%sr2, %r0)
101         ldi     __NR_clone, %r20
103         ldi     -4096, %r1
104         comclr,>>= %r1, %ret0, %r0      /* Note: unsigned compare. */
105         b,n     .LerrorRest
107         /* Restore the PIC register.  */
108 #ifdef PIC
109         copy    %r4, %r19               /* parent */
110 #endif
112         comib,=,n 0, %ret0, .LthreadStart
114         /* Successful return from the parent
115            No need to restore the PIC register,
116            since we return immediately. */
118         ldw     -84(%sp), %rp
119         bv      %r0(%rp)
120         ldwm    -64(%sp), %r4
122 .LerrorRest:
123         /* Something bad happened -- no child created */
124         bl      __syscall_error, %rp
125         sub     %r0, %ret0, %arg0
126         ldw     -84(%sp), %rp
127         /* Return after setting errno, ret0 is set to -1 by __syscall_error. */
128         bv      %r0(%rp)
129         ldwm    -64(%sp), %r4
131 .LerrorSanity:
132         /* Sanity checks failed, return -1, and set errno to EINVAL. */
133         bl      __syscall_error, %rp
134         ldi     EINVAL, %arg0
135         ldw     -84(%sp), %rp
136         bv      %r0(%rp)
137         ldwm    -64(%sp), %r4
139 .LthreadStart:
140         /* Load up the arguments.  */
141         ldw     -60(%sp), %arg0
142         ldw     -64(%sp), %r22
144         /* $$dyncall fixes child's PIC register */
146         /* Call the user's function */
147 #ifdef PIC
148         copy    %r19, %r4
149 #endif
150         bl      $$dyncall, %r31
151         copy    %r31, %rp
152 #ifdef PIC
153         copy    %r4, %r19
154 #endif
155         copy    %r28, %r26
156         ble     0x100(%sr2, %r0)
157         ldi     __NR_exit, %r20
159         /* We should not return from exit.
160            We do not restore r4, or the stack state.  */
161         iitlbp  %r0, (%sr0, %r0)
163 PSEUDO_END(__clone)
165 libc_hidden_def (__clone)
166 weak_alias (__clone, clone)