[PATCH] Fix ppc32
Franz Sirl
Franz.Sirl-kernel@lauterbach.com
Mon Jan 6 19:07:00 GMT 2003
On Monday 06 January 2003 17:13, Jakub Jelinek wrote:
> On Sat, Jan 04, 2003 at 10:01:16PM +0100, Franz Sirl wrote:
> > On Saturday 04 January 2003 21:33, Jakub Jelinek wrote:
> > > On Sat, Jan 04, 2003 at 05:06:01PM +0100, Franz Sirl wrote:
> > > > *
> > > > linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.
> > > >h: New file.
> > >
> > > Thanks for working on this.
> >
> > I'm forced to, if I want to keep my system uptodate :-). Any idea about
> > the AIO problem?
>
> Actually, I have - broken pread* and pwrite*.
> The following patch (on top of the LIBC_CANCEL_HANDLED patch) should fix
> it. __syscall_pread/__syscall_pwrite uses r3,r4,r5,r7,r8 regs to pass
> arguments, so syscalls.list needs to indicate that.
> Alternatively, you could do LIBC_CANCEL_ASYNC/LIBC_CANCEL_RESET in
> sysdeps/unix/sysv/linux/powerpc/p{read,write}{,64}.c.
>
> Also, sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S needs cancellation
> support.
>
> 2003-01-06 Jakub Jelinek <jakub@redhat.com>
>
> * sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list
> (s_pread64, s_pwrite64): Add 6th argument.
> * sysdeps/unix/sysv/linux/powerpc/pread.c: Include sysdep-cancel.h,
> add LIBC_CANCEL_HANDLED.
> * sysdeps/unix/sysv/linux/powerpc/pread64.c: Likewise.
> * sysdeps/unix/sysv/linux/powerpc/pwrite.c: Likewise.
> * sysdeps/unix/sysv/linux/powerpc/pwrite64.c: Likewise.
> linuxthreads/
> * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
> (DOCARGS_6, UNDOCARGS_6): Define.
Uhm, sorry for the delay, I have a patch already for that. Your analysis for
the pread/pwrite problem is correct though, I noted this myself yesterday
morning, but the machines I have access to are quite slow...
Anyway, since I realized there is now a possible failure point with 64bit args
to syscalls and PSEUDO stubs as well, my refusal to use INLINE_SYSCALL
unfortunately has no advantage anymore (before the args argument simply
wasn't used and couldn't cause failures). The appended patch adds
*truncate64.c, pread*.c and pwrite*.c to PPC32. Would someone please so kind
and move the old files down to the powerpc64 directory?
There's also a small hunk for elf/dl-misc.c that makes it explicit that we
want the address of the IOV array. That way the sizeof safety checks I added
don't need to mess around with __builtin_classify_type.
Franz.
* elf/dl-misc.c (_dl_debug_vdprintf): Make taking address of array
explicit.
* 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.
linuxthreads:
* sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile: Remove s_pread64 and
s_pwrite64.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Add support for
syscalls with 6 arguments.
-------------- next part --------------
Index: elf/dl-misc.c
===================================================================
RCS file: /cvs/glibc/libc/elf/dl-misc.c,v
retrieving revision 1.27
diff -u -p -r1.27 dl-misc.c
--- elf/dl-misc.c 13 Dec 2002 19:42:53 -0000 1.27
+++ elf/dl-misc.c 6 Jan 2003 16:42:26 -0000
@@ -248,7 +248,7 @@ _dl_debug_vdprintf (int fd, int tag_p, c
/* Finally write the result. */
#ifdef INTERNAL_SYSCALL
- INTERNAL_SYSCALL (writev, 3, fd, iov, niov);
+ INTERNAL_SYSCALL (writev, 3, fd, &iov, niov);
#elif RTLD_PRIVATE_ERRNO
/* We have to take this lock just to be sure we don't clobber the private
errno when it's being used by another thread that cares about it.
Index: linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile
--- linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile 5 Jan 2003 10:53:51 -0000 1.1
+++ linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile 6 Jan 2003 16:42:31 -0000
@@ -1 +1,2 @@
-libpthread-routines += sysdep s_pread64 s_pwrite64
+# pull in __syscall_error routine
+libpthread-routines += sysdep
Index: linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h,v
retrieving revision 1.1
diff -u -p -r1.1 sysdep-cancel.h
--- linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h 5 Jan 2003 10:54:19 -0000 1.1
+++ linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h 6 Jan 2003 16:42:31 -0000
@@ -71,6 +71,9 @@
# define DOCARGS_5 stw 7,36(1); DOCARGS_4
# define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
+# define DOCARGS_6 stw 8,40(1); DOCARGS_5
+# define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5
+
# ifdef IS_IN_libpthread
# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
Index: sysdeps/powerpc/powerpc32/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/powerpc/powerpc32/sysdep.h,v
retrieving revision 1.1
diff -u -p -r1.1 sysdep.h
--- sysdeps/powerpc/powerpc32/sysdep.h 20 Sep 2002 23:45:49 -0000 1.1
+++ sysdeps/powerpc/powerpc32/sysdep.h 6 Jan 2003 16:42:33 -0000
@@ -116,7 +116,7 @@
DO_CALL (SYS_ify (syscall_name));
#define PSEUDO_RET \
- bnslr; \
+ bnslr+; \
b JUMPTARGET(__syscall_error)
#define ret PSEUDO_RET
Index: sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S,v
retrieving revision 1.1
diff -u -p -r1.1 socket.S
--- sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S 5 Sep 2002 09:13:44 -0000 1.1
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S 6 Jan 2003 16:42:34 -0000
@@ -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)
Index: sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list,v
retrieving revision 1.5
diff -u -p -r1.5 syscalls.list
--- sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list 5 Jan 2003 10:50:38 -0000 1.5
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list 6 Jan 2003 16:42:34 -0000
@@ -9,9 +9,3 @@ rt_sigsuspend - rt_sigsuspend i:pi __sys
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
Index: sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h,v
retrieving revision 1.6
diff -u -p -r1.6 sysdep.h
--- sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h 5 Jan 2003 10:51:04 -0000 1.6
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h 6 Jan 2003 16:42:34 -0000
@@ -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)
--- /dev/null 2002-11-11 17:51:46.000000000 -0700
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c 2003-01-05 10:48:57.000000000 -0700
@@ -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
--- /dev/null 2002-11-11 17:51:46.000000000 -0700
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c 2003-01-05 10:48:37.000000000 -0700
@@ -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
--- /dev/null 2002-11-11 17:51:46.000000000 -0700
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c 2003-01-05 10:36:10.000000000 -0700
@@ -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
--- /dev/null 2002-11-11 17:51:46.000000000 -0700
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c 2003-01-05 10:43:41.000000000 -0700
@@ -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
--- /dev/null 2002-11-11 17:51:46.000000000 -0700
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c 2003-01-05 12:39:35.000000000 -0700
@@ -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
--- /dev/null 2002-11-11 17:51:46.000000000 -0700
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c 2003-01-05 10:54:11.000000000 -0700
@@ -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
More information about the Libc-alpha
mailing list