aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-01-07 00:42:43 +0000
committerUlrich Drepper <drepper@redhat.com>2003-01-07 00:42:43 +0000
commit52f3d213311e34285c4809f043a5cf3a5876b897 (patch)
treeb785902a0af0ab92aabf9e3f155ca1728a607fac /sysdeps
parenta841816e175f7f7faeb5a019578b6b536ea336b6 (diff)
downloadglibc-52f3d213311e34285c4809f043a5cf3a5876b897.tar
glibc-52f3d213311e34285c4809f043a5cf3a5876b897.tar.gz
glibc-52f3d213311e34285c4809f043a5cf3a5876b897.tar.bz2
glibc-52f3d213311e34285c4809f043a5cf3a5876b897.zip
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.c6
-rw-r--r--sysdeps/generic/sysdep-cancel.h1
-rw-r--r--sysdeps/powerpc/powerpc32/sysdep.h2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sysdep.h23
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c78
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c87
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c88
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c87
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c89
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S32
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list6
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h24
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c78
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