diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S
index a31afea429..c18163d0f7 100644
--- a/sysdeps/unix/sysv/linux/hppa/clone.S
+++ b/sysdeps/unix/sysv/linux/hppa/clone.S
@@ -59,16 +59,6 @@
.text
ENTRY(__clone)
- /* Prologue */
- stwm %r4, 64(%sp)
- .cfi_def_cfa_offset -64
- .cfi_offset 4, 0
- stw %sp, -4(%sp)
-#ifdef PIC
- stw %r19, -32(%sp)
- .cfi_offset 19, 32
-#endif
-
/* Sanity check arguments. */
comib,=,n 0,%arg0,.LerrorSanity /* no NULL function pointers */
comib,=,n 0,%arg1,.LerrorSanity /* no NULL stack pointers */
@@ -87,54 +77,34 @@ ENTRY(__clone)
/* User stack pointer is in the correct register already */
/* Load args from stack... */
- ldw -116(%sp), %r24 /* Load parent_tidptr */
- ldw -120(%sp), %r23 /* Load newtls */
- ldw -124(%sp), %r22 /* Load child_tidptr */
-
- /* Save the PIC register. */
-#ifdef PIC
- copy %r19, %r4 /* parent */
-#endif
+ ldw -52(%sp), %r24 /* Load parent_tidptr */
+ ldw -56(%sp), %r23 /* Load newtls */
+ ldw -60(%sp), %r22 /* Load child_tidptr */
/* Do the system call */
ble 0x100(%sr2, %r0)
ldi __NR_clone, %r20
ldi -4096, %r1
- comclr,>>= %r1, %ret0, %r0 /* Note: unsigned compare. */
- b,n .LerrorRest
-
- /* Restore the PIC register. */
-#ifdef PIC
- copy %r4, %r19 /* parent */
-#endif
-
+ comb,<<,n %r1, %ret0, .LerrorRest /* Note: unsigned compare. */
comib,=,n 0, %ret0, .LthreadStart
-
- /* Successful return from the parent
- No need to restore the PIC register,
- since we return immediately. */
-
- ldw -84(%sp), %rp
- bv %r0(%rp)
- ldwm -64(%sp), %r4
+ bv,n %r0(%rp)
.LerrorRest:
- /* Something bad happened -- no child created */
+ /* Something bad happened -- no child created -- need a frame */
+ ldo 64(%sp),%sp
+ .cfi_def_cfa_offset -64
bl __syscall_error, %rp
sub %r0, %ret0, %arg0
ldw -84(%sp), %rp
/* Return after setting errno, ret0 is set to -1 by __syscall_error. */
bv %r0(%rp)
- ldwm -64(%sp), %r4
+ ldo -64(%sp), %sp
.LerrorSanity:
/* Sanity checks failed, return -1, and set errno to EINVAL. */
- bl __syscall_error, %rp
- ldi EINVAL, %arg0
- ldw -84(%sp), %rp
- bv %r0(%rp)
- ldwm -64(%sp), %r4
+ b .LerrorRest
+ ldi -EINVAL, %ret0
.LthreadStart:
/* Load up the arguments. */
@@ -144,14 +114,8 @@ ENTRY(__clone)
/* $$dyncall fixes child's PIC register */
/* Call the user's function */
-#ifdef PIC
- copy %r19, %r4
-#endif
bl $$dyncall, %r31
copy %r31, %rp
-#ifdef PIC
- copy %r4, %r19
-#endif
copy %r28, %r26
ble 0x100(%sr2, %r0)
ldi __NR_exit, %r20
diff --git a/sysdeps/unix/sysv/linux/hppa/vfork.S b/sysdeps/unix/sysv/linux/hppa/vfork.S
new file mode 100644
index 0000000000..5fd368f3cf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/vfork.S
@@ -0,0 +1,53 @@
+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ . */
+
+#include
+#define _ERRNO_H 1
+#include
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ ble 0x100(%sr2, %r0)
+ ldi __NR_vfork, %r20
+
+ ldi -4096, %r1
+ comclr,<< %r1, %ret0, %r0 /* Note: unsigned compare. */
+ bv,n %r0(%rp)
+
+ /* Something bad happened -- no child created -- we need a frame */
+ ldo 64(%sp), %sp
+ .cfi_def_cfa_offset -64
+
+ /* Set errno */
+ bl __syscall_error, %rp
+ sub %r0, %ret0, %arg0
+
+ /* ret0 is set to -1 by __syscall_error */
+ ldw -84(%sp), %rp
+ bv %r0(%rp)
+ ldo -64(%sp), %sp
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
+strong_alias (__vfork, __libc_vfork)