This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] Fix ppc64 cancel handling
- From: Steven Munroe <sjmunroe at us dot ibm dot com>
- To: libc-alpha at sources dot redhat dot com
- Date: Fri, 10 Jan 2003 17:19:47 -0600
- Subject: [PATCH] Fix ppc64 cancel handling
- Organization: IBM Linux Developement
- Reply-to: sjmunroe at vnet dot ibm dot com
The attached patch brings powerpc64 upto date with cvs head as 01/08/03.
It runs build and runs make check.
Thanks to Franz for leading the way.
2003-01-10 Steven Munroe <sjmunroe@us.ibm.com>
* linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile:
Moved to ...
* linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile: Here.
*
linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h:
New File.
* sysdeps/powerpc/powerpc64/sysdep.h (PSEUDO_RET): Add branch hit.
* sysdeps/unix/sysv/linux/powerpc/bits/stat.h (STAT_VER_LINUX):
Fix type. Move definition out of #if.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S: Add cancellation
support.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: Remove
ftruncate64, pread64, pwrite64, truncate64 entries.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
(INLINE_SYSCALL): New version that supports function call like
syscalls.
Add __builtin_expect.
(LOADARGS_n): Add argument size safety checks.
(INTERNAL_SYSCALL): New Macro.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c: New file.
* sysdeps/unix/sysv/linux/powerpc/sys/procfs.h <__PPC_ELF_H>: Avoid
redefinition of elf_fpreg_t and elf_fpregset_t.
--
Steven Munroe
sjmunroe@us.ibm.com
Linux on PowerPC-64 Development
GLIBC for PowerPC-64 Development
diff -rupPN libc23-cvstip-20030108/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile
--- libc23-cvstip-20030108/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile Wed Dec 31 18:00:00 1969
+++ libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile Wed Jan 8 00:44:05 2003
@@ -0,0 +1,2 @@
+# pull in __syscall_error routine
+libpthread-routines += sysdep
diff -rupPN libc23-cvstip-20030108/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile
--- libc23-cvstip-20030108/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile Wed Jan 8 00:44:05 2003
+++ libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile Wed Dec 31 18:00:00 1969
@@ -1,2 +0,0 @@
-# pull in __syscall_error routine
-libpthread-routines += sysdep
diff -rupPN libc23-cvs/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
--- libc23-cvs/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h Wed Dec 31 18:00:00 1969
+++ libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h Wed Jan 8 16:43:31 2003
@@ -0,0 +1,102 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
+
+ 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>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ SINGLE_THREAD_P; \
+ bne- .Lpseudo_cancel; \
+ DO_CALL (SYS_ify (syscall_name)); \
+ PSEUDO_RET; \
+ .Lpseudo_cancel: \
+ stdu 1,-128(1); \
+ mflr 9; \
+ std 9,128+16(1); \
+ DOCARGS_##args; /* save syscall args around CENABLE. */ \
+ CENABLE; \
+ std 3,72(1); /* store CENABLE return value (MASK). */ \
+ UNDOCARGS_##args; /* restore syscall args. */ \
+ DO_CALL (SYS_ify (syscall_name)); \
+ mfcr 0; /* save CR/R3 around CDISABLE. */ \
+ std 3,64(1); \
+ std 0,8(1); \
+ ld 3,72(1); /* pass MASK to CDISABLE. */ \
+ CDISABLE; \
+ ld 9,128+16(1); \
+ ld 0,8(1); /* restore CR/R3. */ \
+ ld 3,64(1); \
+ mtlr 9; \
+ mtcr 0; \
+ addi 1,1,128;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1 std 3,80(1); DOCARGS_0
+# define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
+
+# define DOCARGS_2 std 4,88(1); DOCARGS_1
+# define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
+
+# define DOCARGS_3 std 5,96(1); DOCARGS_2
+# define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
+
+# define DOCARGS_4 std 6,104(1); DOCARGS_3
+# define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
+
+# define DOCARGS_5 std 7,112(1); DOCARGS_4
+# define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
+
+# define DOCARGS_6 std 8,120(1); DOCARGS_5
+# define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
+# define __local_multiple_threads __pthread_multiple_threads
+# else
+# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
+# define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ ld 10,__local_multiple_threads@got(2); \
+ ld 10,0(10); \
+ cmpdi 10,0
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow. */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff -rupPN libc23-cvs/sysdeps/powerpc/powerpc64/sysdep.h libc23/sysdeps/powerpc/powerpc64/sysdep.h
--- libc23-cvs/sysdeps/powerpc/powerpc64/sysdep.h Fri Sep 20 18:45:50 2002
+++ libc23/sysdeps/powerpc/powerpc64/sysdep.h Thu Jan 9 09:02:31 2003
@@ -215,7 +215,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
DO_CALL (SYS_ify (syscall_name));
#define PSEUDO_RET \
- bnslr; \
+ bnslr+; \
b JUMPTARGET(__syscall_error)
#define ret PSEUDO_RET
diff -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/bits/stat.h libc23/sysdeps/unix/sysv/linux/powerpc/bits/stat.h
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/bits/stat.h Tue Dec 31 07:24:34 2002
+++ libc23/sysdeps/unix/sysv/linux/powerpc/bits/stat.h Wed Jan 8 15:04:39 2003
@@ -27,11 +27,11 @@
#define _STAT_VER_LINUX_OLD 1
#define _STAT_VER_KERNEL 1
#define _STAT_VER_SVR4 2
+#define _STAT_VER_LINUX 3
#if __WORDSIZE == 32
-# define _STAT_VER_LINUX 3
-# define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
+# define _STAT_VER _STAT_VER_LINUX
#else
-# define _STAT_VER _STAT_VER_KERNEL /* The one defined below. */
+# define _STAT_VER _STAT_VER_KERNEL
#endif
/* Versions of the `xmknod' interface. */
diff -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c Wed Dec 31 18:00:00 1969
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c Fri Jan 10 14:03:56 2003
@@ -0,0 +1,75 @@
+/* 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
+ int result = INLINE_SYSCALL (ftruncate64, 2, fd, 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 -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c Wed Dec 31 18:00:00 1969
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c Fri Jan 10 13:57:01 2003
@@ -0,0 +1,85 @@
+/* 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)
+ {
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ 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 ();
+
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ 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 -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c Wed Dec 31 18:00:00 1969
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c Fri Jan 10 13:56:38 2003
@@ -0,0 +1,84 @@
+/* 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)
+ {
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ 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 ();
+
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ 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 -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c Wed Dec 31 18:00:00 1969
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c Fri Jan 10 13:55:19 2003
@@ -0,0 +1,85 @@
+/* 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)
+ {
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ 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 ();
+
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ 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 -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c Wed Dec 31 18:00:00 1969
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c Fri Jan 10 13:56:09 2003
@@ -0,0 +1,85 @@
+/* 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)
+ {
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ 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 ();
+
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ 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 -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S Tue Sep 17 18:50:03 2002
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S Thu Jan 9 15:40:06 2003
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1999, 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
@@ -39,7 +39,7 @@
#define NARGS 3
#endif
-#define stackblock 48 /* offset to parm save area */
+#define stackblock 80 /* offset to socket parm area. */
#ifndef socket
/* If this is just socket.S leave it alone! */
@@ -51,7 +51,7 @@
.text
ENTRY(__socket)
- stdu r1,-112(r1)
+ stdu r1,-144(r1)
#if NARGS >= 1
std r3,stackblock(r1)
#endif
@@ -79,11 +79,40 @@ ENTRY(__socket)
#if NARGS >= 9
#error too many arguments!
#endif
- li r3,P(SOCKOP_,socket)
+
+#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,144
+ PSEUDO_RET
+
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+ mflr r9
+ std r9,144+16(r1)
+ CENABLE
+ std r3,72(r1)
+ li r3,P(SOCKOP_,socket)
addi r4,r1,stackblock
DO_CALL(SYS_ify(socketcall))
- addi r1,r1,112
+ mfcr r0
+ std r3,64(r1)
+ std r0,8(r1)
+ ld r3,72(r1)
+ CDISABLE
+ ld r4,144+16(r1)
+ ld r0,8(r1)
+ ld r3,64(r1)
+ mtlr r4
+ mtcr r0
+ addi r1,r1,144
PSEUDO_RET
+#endif
PSEUDO_END (__socket)
weak_alias (__socket, socket)
diff -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list Thu Dec 5 17:46:40 2002
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list Fri Jan 10 09:00:38 2003
@@ -16,7 +16,6 @@ rt_sigtimedwait - rt_sigtimedwait i:pppi
s_fcntl fcntl fcntl i:iiF __syscall_fcntl
s_fcntl64 fcntl64 fcntl64 i:iiF __syscall_fcntl64
s_fstat64 fxstat64 fstat64 i:ip __syscall_fstat64
-s_ftruncate64 ftruncate64 ftruncate64 i:iii __syscall_ftruncate64
s_getcwd getcwd getcwd i:pi __syscall_getcwd
s_getdents getdents getdents i:ipi __syscall_getdents
s_getdents64 getdents getdents64 i:ipi __syscall_getdents64
@@ -26,10 +25,8 @@ s_getrlimit getrlimit getrlimit i:ip __s
s_lstat64 lxstat64 lstat64 i:sp __syscall_lstat64
s_mmap2 mmap64 mmap2 b:aniiii __syscall_mmap2
s_poll poll poll i:pii __syscall_poll
-s_pread64 pread64 pread i:ibnii __syscall_pread
s_ptrace ptrace ptrace i:iipp __syscall_ptrace
s_putpmsg putpmsg putpmsg i:ippii __syscall_putpmsg
-s_pwrite64 pwrite64 pwrite i:ibnii __syscall_pwrite
s_reboot reboot reboot i:iii __syscall_reboot
s_setrlimit setrlimit setrlimit i:ip __syscall_setrlimit
s_sigaction sigaction sigaction i:ipp __syscall_sigaction
@@ -38,7 +35,6 @@ s_sigprocmask sigprocmask sigprocmask i:
s_sigsuspend sigsuspend sigsuspend i:iii __syscall_sigsuspend
s_stat64 xstat64 stat64 i:sp __syscall_stat64
s_sysctl sysctl _sysctl i:p __syscall__sysctl
-s_truncate64 truncate64 truncate64 i:sii __syscall_truncate64
s_ugetrlimit getrlimit ugetrlimit i:ip __syscall_ugetrlimit
s_ustat ustat ustat i:ip __syscall_ustat
s_vfork vfork vfork i: __syscall_vfork
diff -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h Tue Nov 5 13:55:10 2002
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h Thu Jan 9 09:46:05 2003
@@ -69,65 +69,7 @@
#endif /* __ASSEMBLER__ */
#undef INLINE_SYSCALL
-#if 1
-#define INLINE_SYSCALL(name, nr, args...) \
- ({ \
- DECLARGS_##nr; \
- long ret, err; \
- LOADARGS_##nr(name, args); \
- __asm __volatile ("sc\n\t" \
- "mfcr %1\n\t" \
- : "=r" (r3), "=r" (err) \
- : ASM_INPUT_##nr \
- : "cc", "memory"); \
- ret = r3; \
- if (err & 1 << 28) \
- { \
- __set_errno (ret); \
- ret = -1L; \
- } \
- ret; \
- })
-
-#define DECLARGS_0 register long r0 __asm__ ("r0"); \
- register long r3 __asm__ ("r3")
-#define DECLARGS_1 DECLARGS_0
-#define DECLARGS_2 DECLARGS_1; register long r4 __asm__ ("r4")
-#define DECLARGS_3 DECLARGS_2; register long r5 __asm__ ("r5")
-#define DECLARGS_4 DECLARGS_3; register long r6 __asm__ ("r6")
-#define DECLARGS_5 DECLARGS_4; register long r7 __asm__ ("r7")
-#define DECLARGS_6 DECLARGS_5; register long r8 __asm__ ("r8")
-#define LOADARGS_0(name) \
- r0 = __NR_##name
-#define LOADARGS_1(name, arg1) \
- LOADARGS_0(name); \
- r3 = (long) (arg1)
-#define LOADARGS_2(name, arg1, arg2) \
- LOADARGS_1(name, arg1); \
- r4 = (long) (arg2)
-#define LOADARGS_3(name, arg1, arg2, arg3) \
- LOADARGS_2(name, arg1, arg2); \
- r5 = (long) (arg3)
-#define LOADARGS_4(name, arg1, arg2, arg3, arg4) \
- LOADARGS_3(name, arg1, arg2, arg3); \
- r6 = (long) (arg4)
-#define LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
- LOADARGS_4(name, arg1, arg2, arg3, arg4); \
- r7 = (long) (arg5)
-#define LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
- LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
- r8 = (long) (arg6)
-
-#define ASM_INPUT_0 "r" (r0)
-#define ASM_INPUT_1 ASM_INPUT_0, "0" (r3)
-#define ASM_INPUT_2 ASM_INPUT_1, "r" (r4)
-#define ASM_INPUT_3 ASM_INPUT_2, "r" (r5)
-#define ASM_INPUT_4 ASM_INPUT_3, "r" (r6)
-#define ASM_INPUT_5 ASM_INPUT_4, "r" (r7)
-#define ASM_INPUT_6 ASM_INPUT_5, "r" (r8)
-
-#else
/* This version is for kernels that implement system calls that
behave like function calls as far as register saving. */
#define INLINE_SYSCALL(name, nr, args...) \
@@ -149,40 +91,89 @@
: 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"); \
+ "fr4", "fr5", "fr6", "fr7", \
+ "fr8", "fr9", "fr10", "fr11", \
+ "fr12", "fr13", \
+ "ctr", "lr", \
+ "cr0", "cr1", "cr5", "cr6", "cr7", \
+ "memory"); \
ret = r3; \
- if (err & 1 << 28) \
+ if (__builtin_expect ((err & (1 << 28)), 0)) \
{ \
- __set_errno (ret); \
- ret = -1L; \
+ __set_errno (ret); \
+ ret = -1L; \
} \
ret; \
})
-#define LOADARGS_0(name) \
+/* 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. */
+
+# undef INTERNAL_SYSCALL
+# define INTERNAL_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"); \
+ LOADARGS_##nr(name, args); \
+ __asm__ __volatile__ \
+ ("sc\n\t" \
+ "bns+ 0f\n\t" \
+ "neg %1,%1\n" \
+ "0:" \
+ : "=&r" (r0), \
+ "=&r" (r3), "=&r" (r4), "=&r" (r5), \
+ "=&r" (r6), "=&r" (r7), "=&r" (r8) \
+ : ASM_INPUT_##nr \
+ : "r9", "r10", "r11", "r12", \
+ "cr0", "ctr", "memory"); \
+ (int) r3; \
+ })
+
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= 0xfffffffffffff001u)
+
+# 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); \
+ LOADARGS_0(name, 0); \
+ extern void __illegally_sized_syscall_##name##_arg1 (void); \
+ if (sizeof (arg1) > 8) __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) > 8) __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) > 8) __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) > 8) __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) > 8) __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) > 8) __illegally_sized_syscall_##name##_arg6 (); \
r8 = (long) (arg6)
#define ASM_INPUT_0 "0" (r0)
@@ -192,7 +183,5 @@
#define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
#define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
#define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
-
-#endif
#endif /* linux/powerpc/powerpc64/sysdep.h */
diff -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c Wed Dec 31 18:00:00 1969
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c Fri Jan 10 14:11:43 2003
@@ -0,0 +1,76 @@
+/* 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
+ int result = INLINE_SYSCALL (truncate64, 2, CHECK_STRING (path),
+ 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
diff -rupPN libc23-cvs/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h libc23/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h
--- libc23-cvs/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h Thu Jan 17 11:33:40 2002
+++ libc23/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h Fri Jan 10 09:59:04 2003
@@ -32,6 +32,10 @@
__BEGIN_DECLS
+/* These definitions are normally provided by ucontext.h via
+ asm/sigcontext.h, asm/ptrace.h, and asm/elf.h. Otherwise we define
+ them here. */
+#ifndef __PPC64_ELF_H
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
#define ELF_NFPREG 33 /* includes fpscr */
#define ELF_NVRREG 33 /* includes vscr */
@@ -41,6 +45,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
typedef double elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+#endif
/* gcc 3.1 and newer support __uint128_t. */
#if !__GNUC_PREREQ(3,1)