diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | linuxthreads/ChangeLog | 4 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S | 59 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/kernel-features.h | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h | 61 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S | 56 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/syscall.S | 1 |
7 files changed, 172 insertions, 44 deletions
@@ -1,3 +1,34 @@ +2002-01-12 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> + + * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_VFORK_SYSCALL): + Define for powerpc. + * sysdeps/unix/sysv/linux/powerpc/syscall.S: Take register alignment + into account. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/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/powerpc32/vfork.S: New file. + +2002-01-09 Richard Henderson <rth@redhat.com> + + * sysdeps/alpha/dl-machine.h (elf_machine_rela): Compute + DTPREL64 and TPREL64 without loadbase applied. + +2002-01-09 Richard Henderson <rth@redhat.com> + + * sysdeps/unix/alpha/sysdep.S: Use correct definition of errno + for NOT_IN_libc. + + * sysdeps/unix/sysv/linux/alpha/sysdep.h: Move inline syscall bits... + * sysdeps/unix/alpha/sysdep.h: ... here. + (PSEUDO_LOADGP): Remove. + (PSEUDO_PROLOGUE): Load GP in non-pic case. + (SYSCALL_ERROR_LABEL): New. + (PSEUDO): Use it in error branch. + (PSEUDO_END): Add $syscall_error label. + 2003-01-12 Andreas Jaeger <aj@suse.de> * math/bits/mathcalls.h: Round is a const function. diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index de0204dc80..880b05092b 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,7 @@ +2002-01-12 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> + + * sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S: New file. + 2002-01-09 Richard Henderson <rth@redhat.com> * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Assume only diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S new file mode 100644 index 0000000000..f62d3f44c3 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -0,0 +1,59 @@ +/* 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 <sysdep-cancel.h> +#define _ERRNO_H 1 +#include <bits/errno.h> +#include <kernel-features.h> + +/* 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 + + SINGLE_THREAD_P + bne- HIDDEN_JUMPTARGET(__fork) + + DO_CALL (SYS_ify (vfork)); + +# ifdef __ASSUME_VFORK_SYSCALL + PSEUDO_RET +# else + bnslr+ + /* Check if vfork syscall is known at all. */ + cmpwi 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) diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 6b1bdf2517..3159dd1ada 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -196,9 +196,11 @@ # define __ASSUME_AT_XID 1 #endif -/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way. */ +/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way + and the vfork syscall made it into the official kernel. */ #if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ # define __ASSUME_STD_AUXV 1 +# define __ASSUME_VFORK_SYSCALL 1 #endif /* Starting with 2.4.5 kernels the mmap2 syscall made it into the official diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index e2d599c22b..b31c3db653 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -54,53 +54,29 @@ # include <errno.h> -/* On powerpc a system call basically clobbers the same registers like a - function call, with the exception of LR (which is needed for the - "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal - an error return status). */ - # undef INLINE_SYSCALL # 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"); \ - register long r9 __asm__ ("r9"); \ - register long r10 __asm__ ("r10"); \ - register long r11 __asm__ ("r11"); \ - register long r12 __asm__ ("r12"); \ - long ret, err; \ - LOADARGS_##nr(name, args); \ - __asm__ __volatile__ \ - ("sc\n\t" \ - "mfcr %0" \ - : "=&r" (r0), \ - "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \ - "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \ - : ASM_INPUT_##nr \ - : "cr0", "ctr", "memory"); \ - err = r0; \ - ret = r3; \ - if (__builtin_expect (err & (1 << 28), 0)) \ + 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 (ret); \ - ret = -1L; \ + __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \ + sc_ret = -1L; \ } \ - ret; \ + sc_ret; \ }) /* Define a macro which expands inline into the wrapper code for a system call. This use is for internal calls that do not need to handle errors - normally. It will never touch errno. This returns just what the kernel - gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set) - the negation of the return value in the kernel gets reverted. */ + normally. It will never touch errno. + On powerpc a system call basically clobbers the same registers like a + function call, with the exception of LR (which is needed for the + "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal + an error return status). */ # undef INTERNAL_SYSCALL_DECL -# define INTERNAL_SYSCALL_DECL(err) do { } while (0) +# define INTERNAL_SYSCALL_DECL(err) long err # undef INTERNAL_SYSCALL # define INTERNAL_SYSCALL(name, err, nr, args...) \ @@ -118,24 +94,23 @@ register long r12 __asm__ ("r12"); \ LOADARGS_##nr(name, args); \ __asm__ __volatile__ \ - ("sc\n\t" \ - "bns+ 0f\n\t" \ - "neg %1,%1\n" \ - "0:" \ + ("sc \n\t" \ + "mfcr %0" \ : "=&r" (r0), \ "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \ "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \ : ASM_INPUT_##nr \ : "cr0", "ctr", "memory"); \ + err = r0; \ (int) r3; \ }) # undef INTERNAL_SYSCALL_ERROR_P # define INTERNAL_SYSCALL_ERROR_P(val, err) \ - ((unsigned long) (val) >= 0xfffff001u) + (__builtin_expect (err & (1 << 28), 0)) # undef INTERNAL_SYSCALL_ERRNO -# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) +# define INTERNAL_SYSCALL_ERRNO(val, err) (val) # define LOADARGS_0(name, dummy) \ r0 = __NR_##name @@ -181,4 +156,4 @@ #endif /* __ASSEMBLER__ */ -#endif /* linux/powerpc/sysdep.h */ +#endif /* linux/powerpc/powerpc32/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S new file mode 100644 index 0000000000..9a0f53e99e --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/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 <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> +#include <kernel-features.h> + +/* 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. */ + cmpwi 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) diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S index aaff02d78a..aab3c53004 100644 --- a/sysdeps/unix/sysv/linux/powerpc/syscall.S +++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S @@ -25,6 +25,7 @@ ENTRY (syscall) mr r5,r6 mr r6,r7 mr r7,r8 + mr r8,r9 sc PSEUDO_RET PSEUDO_END (syscall) |