diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-01-07 00:42:43 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-01-07 00:42:43 +0000 |
commit | 52f3d213311e34285c4809f043a5cf3a5876b897 (patch) | |
tree | b785902a0af0ab92aabf9e3f155ca1728a607fac /sysdeps | |
parent | a841816e175f7f7faeb5a019578b6b536ea336b6 (diff) | |
download | glibc-52f3d213311e34285c4809f043a5cf3a5876b897.tar.gz |
Update.
2003-01-06 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* sysdeps/powerpc/powerpc32/sysdep.h (PSEUDO_RET): Add branch hint.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S: Add cancellation
support.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list: Remove
ftruncate64, truncate64, pread64 and pwrite64 entries.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
(INLINE_SYSCALL): Add __builtin_expect.
(LOADARGS_n): Add argument size safety checks.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c: New file.
2003-01-06 Jakub Jelinek <jakub@redhat.com>
* sysdeps/generic/sysdep-cancel.h (LIBC_CANCEL_HANDLED): Define.
* sysdeps/generic/creat.c: Include sysdep-cancel.h.
(LIBC_CANCEL_HANDLED): Add.
* sysdeps/unix/sysv/linux/alpha/sysdep.h
(inline_syscall_r0_constraint): Rename to...
(inline_syscall_r0_out_constraint): ... this. Add =.
(inline_syscall[0-6]): Use inline_syscall_r0_out_constraint.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/creat.c | 6 | ||||
-rw-r--r-- | sysdeps/generic/sysdep-cancel.h | 1 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/sysdep.h | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/sysdep.h | 23 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c | 78 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c | 87 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c | 88 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c | 87 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c | 89 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S | 32 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h | 24 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c | 78 |
13 files changed, 575 insertions, 26 deletions
diff --git a/sysdeps/generic/creat.c b/sysdeps/generic/creat.c index 3b1e93c409..462882415c 100644 --- a/sysdeps/generic/creat.c +++ b/sysdeps/generic/creat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1996, 1997, 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 @@ -18,6 +18,7 @@ #include <fcntl.h> #include <sys/types.h> +#include <sysdep-cancel.h> #undef creat @@ -30,3 +31,6 @@ __libc_creat (file, mode) return __open (file, O_WRONLY|O_CREAT|O_TRUNC, mode); } weak_alias (__libc_creat, creat) + +/* __open handles cancellation. */ +LIBC_CANCEL_HANDLED (); diff --git a/sysdeps/generic/sysdep-cancel.h b/sysdeps/generic/sysdep-cancel.h index 8422482819..f07b784f2e 100644 --- a/sysdeps/generic/sysdep-cancel.h +++ b/sysdeps/generic/sysdep-cancel.h @@ -4,3 +4,4 @@ #define SINGLE_THREAD_P (1) #define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */ #define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */ +#define LIBC_CANCEL_HANDLED() /* Nothing. */ diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 9179746790..169abf72bf 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -116,7 +116,7 @@ DO_CALL (SYS_ify (syscall_name)); #define PSEUDO_RET \ - bnslr; \ + bnslr+; \ b JUMPTARGET(__syscall_error) #define ret PSEUDO_RET diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h index 60b6eda4d3..53af4b7349 100644 --- a/sysdeps/unix/sysv/linux/alpha/sysdep.h +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1992, 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1992, 1993, 1995, 1996, 1997, 2002, 2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995. @@ -100,10 +101,10 @@ #ifdef USE_TLS #define inline_syscall_r0_asm -#define inline_syscall_r0_constraint "v" +#define inline_syscall_r0_out_constraint "=v" #else -#define inline_syscall_r0_asm __asm__("$0") -#define inline_syscall_r0_constraint "r" +#define inline_syscall_r0_asm __asm__("$0") +#define inline_syscall_r0_out_constraint "=r" #endif /* It is moderately important optimization-wise to limit the lifetime @@ -117,7 +118,7 @@ \ _sc_0 = __NR_##name; \ __asm__("callsys # %0 %1 <= %2" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19) \ : "0"(_sc_0) \ : inline_syscall_clobbers, \ @@ -134,7 +135,7 @@ _sc_0 = __NR_##name; \ _sc_16 = (long) (arg1); \ __asm__("callsys # %0 %1 <= %2 %3" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19), "=r"(_sc_16) \ : "0"(_sc_0), "2"(_sc_16) \ : inline_syscall_clobbers, \ @@ -153,7 +154,7 @@ _sc_16 = (long) (arg1); \ _sc_17 = (long) (arg2); \ __asm__("callsys # %0 %1 <= %2 %3 %4" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17) \ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17) \ : inline_syscall_clobbers, \ @@ -174,7 +175,7 @@ _sc_17 = (long) (arg2); \ _sc_18 = (long) (arg3); \ __asm__("callsys # %0 %1 <= %2 %3 %4 %5" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \ "=r"(_sc_18) \ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \ @@ -197,7 +198,7 @@ _sc_18 = (long) (arg3); \ _sc_19 = (long) (arg4); \ __asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \ "=r"(_sc_18) \ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \ @@ -222,7 +223,7 @@ _sc_19 = (long) (arg4); \ _sc_20 = (long) (arg5); \ __asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \ "=r"(_sc_18), "=r"(_sc_20) \ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \ @@ -249,7 +250,7 @@ _sc_20 = (long) (arg5); \ _sc_21 = (long) (arg6); \ __asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7 %8" \ - : "=" inline_syscall_r0_constraint (_sc_0), \ + : inline_syscall_r0_out_constraint (_sc_0), \ "=r"(_sc_19) "=r"(_sc_16), "=r"(_sc_17), \ "=r"(_sc_18), "=r"(_sc_20), "=r"(_sc_21) \ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c new file mode 100644 index 0000000000..e79d74cb75 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1997,1998,1999,2000,2001,2002 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 <sys/types.h> +#include <errno.h> +#include <unistd.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include "kernel-features.h" + +#ifdef __NR_ftruncate64 +#ifndef __ASSUME_TRUNCATE64_SYSCALL +/* The variable is shared between all wrappers around *truncate64 calls. */ +extern int have_no_truncate64; +#endif + + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +__ftruncate64 (fd, length) + int fd; + off64_t length; +{ +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (! have_no_truncate64) +#endif + { +#ifndef __ASSUME_TRUNCATE64_SYSCALL + int saved_errno = errno; +#endif + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + int result = INLINE_SYSCALL (ftruncate64, 4, fd, 0, + (long) (length >> 32), + (long) length); + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + __set_errno (saved_errno); + have_no_truncate64 = 1; +#endif + } + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if ((off_t) length != length) + { + __set_errno (EINVAL); + return -1; + } + return __ftruncate (fd, (off_t) length); +#endif +} +weak_alias (__ftruncate64, ftruncate64) + +#else +/* Use the generic implementation. */ +# include <sysdeps/generic/ftruncate64.c> +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c new file mode 100644 index 0000000000..495c98ab97 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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 <assert.h> +#include <errno.h> +#include <unistd.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include "kernel-features.h" + +#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0 + +# if __ASSUME_PREAD_SYSCALL == 0 +static ssize_t __emulate_pread (int fd, void *buf, size_t count, + off_t offset) internal_function; +# endif + + +ssize_t +__libc_pread (fd, buf, count, offset) + int fd; + void *buf; + size_t count; + off_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, + 0, offset >> 31, offset); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread (fd, buf, count, offset); +# endif + + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, + 0, offset >> 31, offset); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +strong_alias (__libc_pread, __pread) +weak_alias (__libc_pread, pread) + +# define __libc_pread(fd, buf, count, offset) \ + static internal_function __emulate_pread (fd, buf, count, offset) +#endif + +#if __ASSUME_PREAD_SYSCALL == 0 +# include <sysdeps/posix/pread.c> +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c new file mode 100644 index 0000000000..d4fe1eea2d --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c @@ -0,0 +1,88 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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 <errno.h> +#include <unistd.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include "kernel-features.h" + +#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0 + +# if __ASSUME_PREAD_SYSCALL == 0 +static ssize_t __emulate_pread64 (int fd, void *buf, size_t count, + off64_t offset) internal_function; +# endif + + +ssize_t +__libc_pread64 (fd, buf, count, offset) + int fd; + void *buf; + size_t count; + off64_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, + 0, (long) (offset >> 32), + (long) offset); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread64 (fd, buf, count, offset); +# endif + + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, + 0, (long) (offset >> 32), + (long) offset); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread64 (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +weak_alias (__libc_pread64, __pread64) +weak_alias (__libc_pread64, pread64) + +# define __libc_pread64(fd, buf, count, offset) \ + static internal_function __emulate_pread64 (fd, buf, count, offset) +#endif + +# if __ASSUME_PREAD_SYSCALL == 0 +# include <sysdeps/posix/pread64.c> +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c new file mode 100644 index 0000000000..3727fa7a42 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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 <assert.h> +#include <errno.h> +#include <unistd.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include "kernel-features.h" + +#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0 + +# if __ASSUME_PWRITE_SYSCALL == 0 +static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count, + off_t offset) internal_function; +# endif + + +ssize_t +__libc_pwrite (fd, buf, count, offset) + int fd; + const void *buf; + size_t count; + off_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, + 0, offset >> 31, offset); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite (fd, buf, count, offset); +# endif + + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, + 0, offset >> 31, offset); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +strong_alias (__libc_pwrite, __pwrite) +weak_alias (__libc_pwrite, pwrite) + +# define __libc_pwrite(fd, buf, count, offset) \ + static internal_function __emulate_pwrite (fd, buf, count, offset) +#endif + +#if __ASSUME_PWRITE_SYSCALL == 0 +# include <sysdeps/posix/pwrite.c> +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c new file mode 100644 index 0000000000..080c88cf29 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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 <errno.h> +#include <unistd.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include "kernel-features.h" + +#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0 + +# if __ASSUME_PWRITE_SYSCALL == 0 +static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count, + off64_t offset) internal_function; +# endif + + +ssize_t +__libc_pwrite64 (fd, buf, count, offset) + int fd; + const void *buf; + size_t count; + off64_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, + 0, (long) (offset >> 32), + (long) offset); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite64 (fd, buf, count, offset); +# endif + + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, + 0, (long) (offset >> 32), + (long) offset); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite64 (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +weak_alias (__libc_pwrite64, __pwrite64) +libc_hidden_weak (__pwrite64) +weak_alias (__libc_pwrite64, pwrite64) + +# define __libc_pwrite64(fd, buf, count, offset) \ + static internal_function __emulate_pwrite64 (fd, buf, count, offset) +#endif + +#if __ASSUME_PWRITE_SYSCALL == 0 +# include <sysdeps/posix/pwrite64.c> +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S index dbdccefe4c..d406f08fdb 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S @@ -16,7 +16,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <sysdep.h> +#include <sysdep-cancel.h> #include <socketcall.h> #define P(a, b) P2(a, b) @@ -75,11 +75,41 @@ ENTRY(__socket) #if NARGS >= 9 #error too many arguments! #endif + +#if defined NEED_CANCELLATION && defined CENABLE + SINGLE_THREAD_P + bne- .Lsocket_cancel +#endif + li r3,P(SOCKOP_,socket) addi r4,r1,stackblock DO_CALL(SYS_ify(socketcall)) addi r1,r1,48 PSEUDO_RET + +#if defined NEED_CANCELLATION && defined CENABLE +.Lsocket_cancel: + mflr r9 + stw r9,52(r1) + CENABLE + stw r3,16(r1) + li r3,P(SOCKOP_,socket) + addi r4,r1,stackblock + DO_CALL(SYS_ify(socketcall)) + mfcr r0 + stw r3,8(r1) + stw r0,12(r1) + lwz r3,16(r1) + CDISABLE + lwz r4,52(r1) + lwz r0,12(r1) + lwz r3,8(r1) + mtlr r4 + mtcr r0 + addi r1,r1,48 + PSEUDO_RET +#endif + PSEUDO_END (__socket) weak_alias (__socket, socket) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list index cfefbf0ece..13f0e9bba9 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list @@ -9,9 +9,3 @@ rt_sigsuspend - rt_sigsuspend i:pi __syscall_rt_sigsuspend rt_sigtimedwait - rt_sigtimedwait i:pppi __syscall_rt_sigtimedwait oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 - -# System calls with 64bit args -s_ftruncate64 ftruncate64 ftruncate64 i:iii __syscall_ftruncate64 -s_pread64 pread64 pread Ci:ibnii __syscall_pread -s_pwrite64 pwrite64 pwrite Ci:ibnii __syscall_pwrite -s_truncate64 truncate64 truncate64 i:sii __syscall_truncate64 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index d2cee1ffc7..2b3dd03b8d 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -85,7 +85,7 @@ : "cr0", "ctr", "memory"); \ err = r0; \ ret = r3; \ - if (err & (1 << 28)) \ + if (__builtin_expect (err & (1 << 28), 0)) \ { \ __set_errno (ret); \ ret = -1L; \ @@ -99,7 +99,7 @@ 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. */ -#undef INTERNAL_SYSCALL +# undef INTERNAL_SYSCALL # define INTERNAL_SYSCALL(name, nr, args...) \ ({ \ register long r0 __asm__ ("r0"); \ @@ -127,31 +127,43 @@ (int) r3; \ }) -#undef INTERNAL_SYSCALL_ERROR_P -#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095U) +# undef INTERNAL_SYSCALL_ERROR_P +# define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= 0xfffff001u) -#undef INTERNAL_SYSCALL_ERRNO -#define INTERNAL_SYSCALL_ERRNO(val) (-(val)) +# undef INTERNAL_SYSCALL_ERRNO +# define INTERNAL_SYSCALL_ERRNO(val) (-(val)) # define LOADARGS_0(name, dummy) \ r0 = __NR_##name # define LOADARGS_1(name, arg1) \ LOADARGS_0(name, 0); \ + extern void __illegally_sized_syscall_##name##_arg1 (void); \ + if (sizeof (arg1) > 4) __illegally_sized_syscall_##name##_arg1 (); \ r3 = (long) (arg1) # define LOADARGS_2(name, arg1, arg2) \ LOADARGS_1(name, arg1); \ + extern void __illegally_sized_syscall_##name##_arg2 (void); \ + if (sizeof (arg2) > 4) __illegally_sized_syscall_##name##_arg2 (); \ r4 = (long) (arg2) # define LOADARGS_3(name, arg1, arg2, arg3) \ LOADARGS_2(name, arg1, arg2); \ + extern void __illegally_sized_syscall_##name##_arg3 (void); \ + if (sizeof (arg3) > 4) __illegally_sized_syscall_##name##_arg3 (); \ r5 = (long) (arg3) # define LOADARGS_4(name, arg1, arg2, arg3, arg4) \ LOADARGS_3(name, arg1, arg2, arg3); \ + extern void __illegally_sized_syscall_##name##_arg4 (void); \ + if (sizeof (arg4) > 4) __illegally_sized_syscall_##name##_arg4 (); \ r6 = (long) (arg4) # define LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ LOADARGS_4(name, arg1, arg2, arg3, arg4); \ + extern void __illegally_sized_syscall_##name##_arg5 (void); \ + if (sizeof (arg5) > 4) __illegally_sized_syscall_##name##_arg5 (); \ r7 = (long) (arg5) # define LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ + extern void __illegally_sized_syscall_##name##_arg6 (void); \ + if (sizeof (arg6) > 4) __illegally_sized_syscall_##name##_arg6 (); \ r8 = (long) (arg6) # define ASM_INPUT_0 "0" (r0) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c new file mode 100644 index 0000000000..ce8ebc2a97 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2002 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 <sys/types.h> +#include <errno.h> +#include <unistd.h> + +#include <sysdep.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include "kernel-features.h" + +#ifdef __NR_truncate64 +#ifndef __ASSUME_TRUNCATE64_SYSCALL +/* The variable is shared between all wrappers around *truncate64 calls. */ +int have_no_truncate64; +#endif + + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +truncate64 (path, length) + const char *path; + off64_t length; +{ +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (! have_no_truncate64) +#endif + { +#ifndef __ASSUME_TRUNCATE64_SYSCALL + int saved_errno = errno; +#endif + /* On PPC32 64bit values are aligned in odd/even register pairs. */ + int result = INLINE_SYSCALL (truncate64, 4, CHECK_STRING (path), 0, + (long) (length >> 32), + (long) length); + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if (result != -1 || errno != ENOSYS) +#endif + return result; + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + __set_errno (saved_errno); + have_no_truncate64 = 1; +#endif + } + +#ifndef __ASSUME_TRUNCATE64_SYSCALL + if ((off_t) length != length) + { + __set_errno (EINVAL); + return -1; + } + return truncate (path, (off_t) length); +#endif +} + +#else +/* Use the generic implementation. */ +# include <sysdeps/generic/truncate64.c> +#endif |