From 574b892ef1054ea999a136b3cb2321a65e3f1a17 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 15 Jan 2003 01:23:02 +0000 Subject: Update. 2003-01-14 Guido Guenther * sysdeps/unix/sysv/linux/mips/sysdep.h (INTERNAL_SYSCALL, INTERNAL_SYSCALL_DECL, INTERNAL_SYSCALL_ERRNO, INTERNAL_SYSCALL_ERROR_P, INLINE_SYSCALL): Define. 2003-01-14 Steven Munroe * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h (INTERNAL_SYSCALL): Make use of ERR parameter. (INTERNAL_SYSCALL_DECL, INTERNAL_SYSCALL_ERRNO, INTERNAL_SYSCALL_ERROR_P): Adjust accordingly. (INLINE_SYSCALL): Make use of INTERNAL_SYSCALL. * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S: New file. Patch by Denis Zaitsev . that %eax is modified. Reported by Denis Zaitsev . --- sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | 56 ++++++++-------------- sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S | 56 ++++++++++++++++++++++ 2 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S (limited to 'sysdeps/unix/sysv/linux/powerpc') diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index d37be2ef4f..c215398995 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -74,36 +74,14 @@ behave like function calls as far as register saving. */ #define INLINE_SYSCALL(name, nr, args...) \ ({ \ - register long r0 __asm__ ("r0"); \ - register long r3 __asm__ ("r3"); \ - register long r4 __asm__ ("r4"); \ - register long r5 __asm__ ("r5"); \ - register long r6 __asm__ ("r6"); \ - register long r7 __asm__ ("r7"); \ - register long r8 __asm__ ("r8"); \ - long ret, err; \ - LOADARGS_##nr(name, args); \ - __asm __volatile ("sc\n\t" \ - "mfcr %7\n\t" \ - : "=r" (r0), "=r" (r3), "=r" (r4), \ - "=r" (r5), "=r" (r6), "=r" (r7), \ - "=r" (r8), "=r" (err) \ - : ASM_INPUT_##nr \ - : "r9", "r10", "r11", "r12", \ - "fr0", "fr1", "fr2", "fr3", \ - "fr4", "fr5", "fr6", "fr7", \ - "fr8", "fr9", "fr10", "fr11", \ - "fr12", "fr13", \ - "ctr", "lr", \ - "cr0", "cr1", "cr5", "cr6", "cr7", \ - "memory"); \ - ret = r3; \ - if (__builtin_expect ((err & (1 << 28)), 0)) \ - { \ - __set_errno (ret); \ - ret = -1L; \ - } \ - ret; \ + INTERNAL_SYSCALL_DECL (sc_err); \ + long sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \ + if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \ + sc_ret = -1L; \ + } \ + sc_ret; \ }) /* Define a macro which expands inline into the wrapper code for a system @@ -113,7 +91,7 @@ the negation of the return value in the kernel gets reverted. */ # undef INTERNAL_SYSCALL -# define INTERNAL_SYSCALL(name, nr, args...) \ +# define INTERNAL_SYSCALL(name, err, nr, args...) \ ({ \ register long r0 __asm__ ("r0"); \ register long r3 __asm__ ("r3"); \ @@ -125,8 +103,7 @@ LOADARGS_##nr(name, args); \ __asm__ __volatile__ \ ("sc\n\t" \ - "bns+ 0f\n\t" \ - "neg %1,%1\n" \ + "mfcr %0\n\t" \ "0:" \ : "=&r" (r0), \ "=&r" (r3), "=&r" (r4), "=&r" (r5), \ @@ -134,14 +111,19 @@ : ASM_INPUT_##nr \ : "r9", "r10", "r11", "r12", \ "cr0", "ctr", "memory"); \ - (int) r3; \ + err = r0; \ + (int) r3; \ }) + +# undef INTERNAL_SYSCALL_DECL +# define INTERNAL_SYSCALL_DECL(err) long err # undef INTERNAL_SYSCALL_ERROR_P -# define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= 0xfffffffffffff001u) - +# define INTERNAL_SYSCALL_ERROR_P(val, err) \ + (__builtin_expect (err & (1 << 28), 0)) + # undef INTERNAL_SYSCALL_ERRNO -# define INTERNAL_SYSCALL_ERRNO(val) (-(val)) +# define INTERNAL_SYSCALL_ERRNO(val, err) (val) #define LOADARGS_0(name, dummy) \ r0 = __NR_##name diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S new file mode 100644 index 0000000000..d36b917e1c --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S @@ -0,0 +1,56 @@ +/* Copyright (C) 2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#define _ERRNO_H 1 +#include +#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) + +#ifdef __NR_vfork + + DO_CALL (SYS_ify (vfork)) + +# ifdef __ASSUME_VFORK_SYSCALL + PSEUDO_RET +# else + bnslr+ + /* Check if vfork syscall is known at all. */ + cmpdi r3,ENOSYS + bne JUMPTARGET(__syscall_error) + +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL + /* If we don't have vfork, fork is close enough. */ + + DO_CALL (SYS_ify (fork)) + PSEUDO_RET +#endif + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) -- cgit v1.2.3