Skip to content

Commit

Permalink
aarch64: Consolidate NPTL/non versions of vfork
Browse files Browse the repository at this point in the history
At the same time, incorporate the 0 -> 0x80000000 mapping
of the pid expected by raise.c.
  • Loading branch information
Richard Henderson committed Jun 3, 2014
1 parent 111cc71 commit 89b4bd6
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 44 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
2014-06-03 Richard Henderson <rth@redhat.com>

* sysdeps/unix/sysv/linux/aarch64/pt-vfork.c: New file.
* sysdeps/unix/sysv/linux/aarch64/nptl/pt-vfork.S: Remove file.
* sysdeps/unix/sysv/linux/aarch64/vfork.S (__vfork): Incorporate
SAVE_PID and RESTORE_PID blocks from pt-vfork.S. Map 0 to INT_MIN
in the SAVE_PID block.
(__libc_vfork): New alias.

* sysdeps/unix/sysv/linux/aarch64/clone.S (__clone): Save args for
child in registers, not on the stack. Remove RESET_PID conditionals.
* sysdeps/unix/sysv/linux/aarch64/nptl/clone.S: Remove file.
Expand Down
35 changes: 0 additions & 35 deletions sysdeps/unix/sysv/linux/aarch64/nptl/pt-vfork.S

This file was deleted.

54 changes: 54 additions & 0 deletions sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* vfork ABI-compatibility entry points for libpthread.
Copyright (C) 2014 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
<http://www.gnu.org/licenses/>. */

#include <shlib-compat.h>

/* libpthread used to have its own vfork implementation that differed
from libc's only in having a pointless micro-optimization. There
is no longer any use to having a separate copy in libpthread, but
the historical ABI requires it. For static linking, there is no
need to provide anything here--the libc version will be linked in.
For shared library ABI compatibility, there must be __vfork and
vfork symbols in libpthread.so. */

#if HAVE_IFUNC
# include <nptl/pt-vfork.c>
#elif (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
|| SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20))

/* Thankfully, on AArch64 we can rely on the compiler generating
a tail call here. */

extern void __libc_vfork (void);

void
vfork_compat (void)
{
__libc_vfork ();
}

# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
compat_symbol (libpthread, vfork_compat, vfork, GLIBC_2_0);
# endif

# if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
strong_alias (vfork_compat, vfork_compat2)
compat_symbol (libpthread, vfork_compat2, __vfork, GLIBC_2_1_2);
# endif

#endif
29 changes: 20 additions & 9 deletions sysdeps/unix/sysv/linux/aarch64/vfork.S
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,33 @@

ENTRY (__vfork)

#ifdef SAVE_PID
SAVE_PID
#endif
/* Save the TCB-cached PID away in w3, and then negate the TCB
field. But if it's zero, set it to 0x80000000 instead. See
raise.c for the logic that relies on this value. */
mrs x2, tpidr_el0
sub x2, x2, #PTHREAD_SIZEOF
ldr w3, [x2, #PTHREAD_PID_OFFSET]
mov w1, #0x80000000
negs w0, w3
csel w0, w1, w0, eq
str w0, [x2, #PTHREAD_PID_OFFSET]

mov x0, #0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */
mov x1, sp
DO_CALL (clone, 2)
#ifdef RESTORE_PID
RESTORE_PID
#endif

/* Restore the original value of the TCB cache of the PID, if we're
the parent. But in the child (syscall return value equals zero),
leave things as they are. */
cbz x0, 1f
str w3, [x2, #PTHREAD_PID_OFFSET]
1:
cmn x0, #4095
b.cs 1f
b.cs .Lsyscall_error
RET
1:
b SYSCALL_ERROR

PSEUDO_END (__vfork)
libc_hidden_def (__vfork)

weak_alias (__vfork, vfork)
strong_alias (__vfork, __libc_vfork)

0 comments on commit 89b4bd6

Please sign in to comment.