From 6a918870bab1a55a5f57dd7954abd9a8a27c1bc2 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 5 Aug 2014 20:53:31 +0000 Subject: [PATCH] Revert "Replaces vfork() implementation with fork()" We're getting cold feet on this one... let's put it back. This reverts commit 210331d9762037afb9b5ed8413079c6f65872df9. Change-Id: I6b0d3c2b1dbf7f1dc9566979a91b7504c2189269 --- libc/SYSCALLS.TXT | 1 + libc/arch-arm/syscalls/vfork.S | 14 ++++ libc/arch-arm64/arm64.mk | 1 + libc/arch-arm64/bionic/vfork.S | 48 +++++++++++++ libc/arch-mips/bionic/vfork.S | 58 +++++++++++++++ libc/arch-mips/mips.mk | 1 + libc/arch-mips64/bionic/vfork.S | 71 +++++++++++++++++++ libc/arch-mips64/mips64.mk | 1 + libc/arch-x86/bionic/vfork.S | 44 ++++++++++++ libc/arch-x86/x86.mk | 1 + .../vfork.cpp => arch-x86_64/bionic/vfork.S} | 24 +++++-- libc/arch-x86_64/x86_64.mk | 1 + 12 files changed, 258 insertions(+), 7 deletions(-) create mode 100644 libc/arch-arm/syscalls/vfork.S create mode 100644 libc/arch-arm64/bionic/vfork.S create mode 100644 libc/arch-mips/bionic/vfork.S create mode 100644 libc/arch-mips64/bionic/vfork.S create mode 100644 libc/arch-x86/bionic/vfork.S rename libc/{bionic/vfork.cpp => arch-x86_64/bionic/vfork.S} (76%) diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 128ec6bd0..38ae8310a 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -77,6 +77,7 @@ int prlimit64(pid_t, int, struct rlimit64*, const struct rlimit64*) arm,mips,x8 int setgroups:setgroups32(int, const gid_t*) arm,x86 int setgroups:setgroups(int, const gid_t*) arm64,mips,mips64,x86_64 int setpgid(pid_t, pid_t) all +pid_t vfork(void) arm int setregid:setregid32(gid_t, gid_t) arm,x86 int setregid:setregid(gid_t, gid_t) arm64,mips,mips64,x86_64 int chroot(const char*) all diff --git a/libc/arch-arm/syscalls/vfork.S b/libc/arch-arm/syscalls/vfork.S new file mode 100644 index 000000000..e12fba55a --- /dev/null +++ b/libc/arch-arm/syscalls/vfork.S @@ -0,0 +1,14 @@ +/* Generated by gensyscalls.py. Do not edit. */ + +#include + +ENTRY(vfork) + mov ip, r7 + ldr r7, =__NR_vfork + swi #0 + mov r7, ip + cmn r0, #(MAX_ERRNO + 1) + bxls lr + neg r0, r0 + b __set_errno +END(vfork) diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk index 314358e1f..ed991ce60 100644 --- a/libc/arch-arm64/arm64.mk +++ b/libc/arch-arm64/arm64.mk @@ -36,6 +36,7 @@ libc_bionic_src_files_arm64 := \ arch-arm64/bionic/__set_tls.c \ arch-arm64/bionic/sigsetjmp.S \ arch-arm64/bionic/syscall.S \ + arch-arm64/bionic/vfork.S \ libc_crt_target_cflags_arm64 := \ diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S new file mode 100644 index 000000000..c70062317 --- /dev/null +++ b/libc/arch-arm64/bionic/vfork.S @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +ENTRY(vfork) + mov x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD) + mov x1, xzr + mov x2, xzr + mov x3, xzr + mov x4, xzr + + mov x8, __NR_clone + svc #0 + + cmn x0, #(MAX_ERRNO + 1) + cneg x0, x0, hi + b.hi __set_errno + + ret +END(vfork) diff --git a/libc/arch-mips/bionic/vfork.S b/libc/arch-mips/bionic/vfork.S new file mode 100644 index 000000000..96de69e20 --- /dev/null +++ b/libc/arch-mips/bionic/vfork.S @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +// TODO: mips' uapi signal.h is missing #ifndef __ASSEMBLY__. +// #include +#define SIGCHLD 18 + +ENTRY(vfork) + .set noreorder + .cpload t9 + + li a0, (CLONE_VM | CLONE_VFORK | SIGCHLD) + li a1, 0 + li a2, 0 + li a3, 0 + subu sp, 8 + sw $0, 16(sp) + li v0, __NR_clone + syscall + addu sp, 8 + bnez a3, 1f + move a0, v0 + + j ra + nop +1: + la t9, __set_errno + j t9 + nop +END(vfork) diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk index bf3b8ae00..8e415f957 100644 --- a/libc/arch-mips/mips.mk +++ b/libc/arch-mips/mips.mk @@ -59,6 +59,7 @@ libc_bionic_src_files_mips += \ arch-mips/bionic/setjmp.S \ arch-mips/bionic/sigsetjmp.S \ arch-mips/bionic/syscall.S \ + arch-mips/bionic/vfork.S \ ifndef ARCH_MIPS_REV6 libc_bionic_src_files_mips += \ diff --git a/libc/arch-mips64/bionic/vfork.S b/libc/arch-mips64/bionic/vfork.S new file mode 100644 index 000000000..911a264f2 --- /dev/null +++ b/libc/arch-mips64/bionic/vfork.S @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +// TODO: mips' uapi signal.h is missing #ifndef __ASSEMBLY__. +// #include +#define SIGCHLD 18 + + .text + +#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32) +FRAMESZ = MKFSIZ(5,0) +#else +FRAMESZ = MKFSIZ(0,0) +#endif + +LEAF(vfork,FRAMESZ) +#if FRAMESZ!=0 + PTR_SUBU sp, FRAMESZ +#endif + SETUP_GP64(a5, vfork) + LI a0, (CLONE_VM | CLONE_VFORK | SIGCHLD) + move a1, $0 + move a2, $0 + move a3, $0 +#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32) + REG_S $0, 4*REGSZ(sp) +#else + move a4, $0 +#endif + LI v0, __NR_clone + syscall +#if FRAMESZ!=0 + PTR_ADDU sp,FRAMESZ +#endif + move a0, v0 + bnez a3, 1f + RESTORE_GP64 + j ra +1: + LA t9,__set_errno + RESTORE_GP64 + j t9 + END(vfork) diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk index 6f7a928b1..230cb26c5 100644 --- a/libc/arch-mips64/mips64.mk +++ b/libc/arch-mips64/mips64.mk @@ -46,6 +46,7 @@ libc_bionic_src_files_mips64 := \ arch-mips64/bionic/setjmp.S \ arch-mips64/bionic/sigsetjmp.S \ arch-mips64/bionic/syscall.S \ + arch-mips64/bionic/vfork.S \ # FIXME TODO ## libc_bionic_src_files_mips64 += arch-mips64/string/memcpy.S diff --git a/libc/arch-x86/bionic/vfork.S b/libc/arch-x86/bionic/vfork.S new file mode 100644 index 000000000..ffa6b16aa --- /dev/null +++ b/libc/arch-x86/bionic/vfork.S @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +// This custom code preserves the return address across the system call. + +ENTRY(vfork) + popl %ecx // Grab the return address. + movl $__NR_vfork, %eax + int $0x80 + cmpl $-MAX_ERRNO, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno +1: + jmp *%ecx // Jump to the stored return address. +END(vfork) diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk index 8aa2645d3..019dc8e81 100644 --- a/libc/arch-x86/x86.mk +++ b/libc/arch-x86/x86.mk @@ -31,6 +31,7 @@ libc_bionic_src_files_x86 += \ arch-x86/bionic/__set_tls.c \ arch-x86/bionic/sigsetjmp.S \ arch-x86/bionic/syscall.S \ + arch-x86/bionic/vfork.S \ ## ARCH variant specific source files arch_variant_mk := $(LOCAL_PATH)/arch-x86/$(TARGET_ARCH_VARIANT)/$(TARGET_ARCH_VARIANT).mk diff --git a/libc/bionic/vfork.cpp b/libc/arch-x86_64/bionic/vfork.S similarity index 76% rename from libc/bionic/vfork.cpp rename to libc/arch-x86_64/bionic/vfork.S index b706a7f7d..7c14cc0d9 100644 --- a/libc/bionic/vfork.cpp +++ b/libc/arch-x86_64/bionic/vfork.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,10 +26,20 @@ * SUCH DAMAGE. */ -#include +#include -// vfork(2) was removed from POSIX 2008, but it's common enough that we can't -// actually remove it entirely. -extern "C" pid_t vfork(void) { - return fork(); -} +// This custom code preserves the return address across the system call. + +ENTRY(vfork) + popq %rdi // Grab the return address. + movl $__NR_vfork, %eax + syscall + pushq %rdi // Restore the return address. + cmpq $-MAX_ERRNO, %rax + jb 1f + negl %eax + movl %eax, %edi + call __set_errno +1: + ret +END(vfork) diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk index 234cf6703..7887c519e 100644 --- a/libc/arch-x86_64/x86_64.mk +++ b/libc/arch-x86_64/x86_64.mk @@ -37,6 +37,7 @@ libc_bionic_src_files_x86_64 := \ arch-x86_64/bionic/__set_tls.c \ arch-x86_64/bionic/sigsetjmp.S \ arch-x86_64/bionic/syscall.S \ + arch-x86_64/bionic/vfork.S \ libc_bionic_src_files_x86_64 += \ arch-x86_64/string/sse2-memcpy-slm.S \