summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2013-04-07 02:19:53 -0400
committerMike Frysinger <vapier@gentoo.org>2013-04-07 02:19:53 -0400
commit458076d59ef9849f79d27e21b6094b0b3a85fbb4 (patch)
tree3de0c58727f7a445904707c53ab12f2d41bacd36 /libc
parent6264f45095de0953745b447598ab44dce5e7a322 (diff)
linux: pread/write: fix 64bit handling
The syscall on 64bit ports takes 4 args as there is no need to split up the value into two args. Add support for that to the common code. Once we fix that, the mips code can now leverage it for its 64bit and 32bit needs. However, we can't just drop it entirely yet because its n32 ABI needs special handling to treat it like a 64bit port. This does change the existing behavior which treats the n32 like a 32bit port, but we want to do this. In the future, we'll probably have to introduce a define for this as it currently affects x86_64/x32 and mips/n32. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libc')
-rw-r--r--libc/sysdeps/linux/common/pread_write.c14
-rw-r--r--libc/sysdeps/linux/mips/pread_write.c52
2 files changed, 21 insertions, 45 deletions
diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c
index fa22f82b1..4f96f681d 100644
--- a/libc/sysdeps/linux/common/pread_write.c
+++ b/libc/sysdeps/linux/common/pread_write.c
@@ -36,11 +36,16 @@ static _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf,
size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
# define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF_HI_LO(offset))
# define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF64_HI_LO(offset))
-# else
+# elif __WORDSIZE == 32
static _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
size_t, count, off_t, offset_hi, off_t, offset_lo)
# define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF_HI_LO(offset))
# define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF64_HI_LO(offset))
+# else
+static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf,
+ size_t, count, off_t, offset)
+# define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset)
+# define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset)
# endif
# endif
#endif
@@ -53,11 +58,16 @@ static _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
# define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF_HI_LO(offset))
# define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF64_HI_LO(offset))
-# else
+# elif __WORDSIZE == 32
static _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
size_t, count, off_t, offset_hi, off_t, offset_lo)
# define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF_HI_LO(offset))
# define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF64_HI_LO(offset))
+# else
+static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
+ size_t, count, off_t, offset)
+# define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset)
+# define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset)
# endif
# endif
#endif
diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
index b777dc47e..3dc97c993 100644
--- a/libc/sysdeps/linux/mips/pread_write.c
+++ b/libc/sysdeps/linux/mips/pread_write.c
@@ -10,56 +10,22 @@
#include <endian.h>
#include <sgidefs.h>
-#ifdef __NR_pread64
-# ifdef __NR_pread
-# error "__NR_pread and __NR_pread64 both defined???"
-# endif
-# define __NR_pread __NR_pread64
-#endif
-
-#ifdef __NR_pread
-# if _MIPS_SIM == _MIPS_SIM_ABI64 /* glibc uses it for N32 as well */
-# define __NR___syscall_pread __NR_pread
+/* We should generalize this for 32bit userlands w/64bit regs. This applies
+ * to the x86_64 x32 and the mips n32 ABIs. */
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR___syscall_pread __NR_pread
static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count, off_t, offset)
-# define MY_PREAD(fd, buf, count, offset) \
+# define MY_PREAD(fd, buf, count, offset) \
__syscall_pread(fd, buf, count, offset)
-# define MY_PREAD64(fd, buf, count, offset) \
+# define MY_PREAD64(fd, buf, count, offset) \
__syscall_pread(fd, buf, count, offset)
-# else /* O32 || N32 */
-# define __NR___syscall_pread __NR_pread
-static _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf,
- size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
-# define MY_PREAD(fd, buf, count, offset) \
- __syscall_pread(fd, buf, count, 0, OFF_HI_LO(offset))
-# define MY_PREAD64(fd, buf, count, offset) \
- __syscall_pread(fd, buf, count, 0, OFF64_HI_LO(offset))
-# endif
-#endif
-
-#ifdef __NR_pwrite64
-# ifdef __NR_pwrite
-# error "__NR_pwrite and __NR_pwrite64 both defined???"
-# endif
-# define __NR_pwrite __NR_pwrite64
-#endif
-#ifdef __NR_pwrite
-# if _MIPS_SIM == _MIPS_SIM_ABI64 /* glibc uses it for N32 as well */
-# define __NR___syscall_pwrite __NR_pwrite
+# define __NR___syscall_pwrite __NR_pwrite
static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset)
-# define MY_PWRITE(fd, buf, count, offset) \
+# define MY_PWRITE(fd, buf, count, offset) \
__syscall_pwrite(fd, buf, count, offset)
-# define MY_PWRITE64(fd, buf, count, offset) \
+# define MY_PWRITE64(fd, buf, count, offset) \
__syscall_pwrite(fd, buf, count, offset)
-# else /* O32 || N32 */
-# define __NR___syscall_pwrite __NR_pwrite
-static _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
- size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
-# define MY_PWRITE(fd, buf, count, offset) \
- __syscall_pwrite(fd, buf, count, 0, OFF_HI_LO(offset))
-# define MY_PWRITE64(fd, buf, count, offset) \
- __syscall_pwrite(fd, buf, count, 0, OFF64_HI_LO(offset))
-# endif
#endif
#include "../common/pread_write.c"