summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-06-05 07:21:44 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-06-05 07:21:57 -0700
commitd8a7d10324d9765fa62f42c1d94c5bf36b60d558 (patch)
treeb5b327952195b4aafa8a96a8a3fc83dbe4432333 /sysdeps
parentc4c96f92f76dbc03a04a0e5005bf0be6f8dd4138 (diff)
downloadglibc-d8a7d10324d9765fa62f42c1d94c5bf36b60d558.tar.gz
glibc-d8a7d10324d9765fa62f42c1d94c5bf36b60d558.tar.xz
glibc-d8a7d10324d9765fa62f42c1d94c5bf36b60d558.zip
x86-64: Update LO_HI_LONG for p{readv,writev}{64}v2
The kernel interface for p{readv,writev}{64}v is

(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
 unsigned long pos_l, unsigned long pos_h)

Except for targets which define __ARCH_WANT_COMPAT_SYS_PREADV64 and
__ARCH_WANT_COMPAT_SYS_PWRITEV64,

(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
 off64_t pos)

is used for p{readv,writev}{64}v.  X32 is the only such target.  The
LO_HI_LONG macro is used to pass offset to the pos_l and pos_h pair.
Since pos_h is ignored when size of offset == sizeof of pos_l, x86-64
has

 #define LO_HI_LONG(val) (val)

But the kernel interface for p{readv,writev}{64}v2 is

(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
 unsigned long pos_l, unsigned long pos_h, int flags)

Except for targets which define __ARCH_WANT_COMPAT_SYS_PREADV64V2 and
__ARCH_WANT_COMPAT_SYS_PWRITEV64V2,

(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
 off64_t pos, int flags)

is used for p{readv,writev}{64}v2.  X32 is the only such target.  Update
x86-64 LO_HI_LONG to pass 0 as the high part of the offset argument for
p{readv,writev}{64}v2 and define a different LO_HI_LONG for x32 to only
pass one argument for offset.

Tested on x32 and x86-64.

	* sysdeps/unix/sysv/linux/x86_64/sysdep.h (LO_HI_LONG): Pass
	0 as the high part of offset.
	* sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h (LO_HI_LONG): New.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sysdep.h2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h4
2 files changed, 5 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 7b8bd795b7..880e496880 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -387,6 +387,6 @@
 
 /* How to pass the off{64}_t argument on p{readv,writev}{64}.  */
 #undef LO_HI_LONG
-#define LO_HI_LONG(val) (val)
+#define LO_HI_LONG(val) (val), 0
 
 #endif /* linux/x86_64/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
index f90fcfaeef..04c73a2bc1 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
@@ -22,4 +22,8 @@
 #include <sysdeps/unix/sysv/linux/x86_64/sysdep.h>
 #include <sysdeps/x86_64/x32/sysdep.h>
 
+/* How to pass the off{64}_t argument on p{readv,writev}{64}.  */
+#undef LO_HI_LONG
+#define LO_HI_LONG(val) (val)
+
 #endif /* linux/x86_64/x32/sysdep.h */