This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Use SYSCALL_LL[64] to pass 64-bit value [BZ #20349]
On Mon, Jul 11, 2016 at 2:04 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Jul 11, 2016 at 1:36 PM, Chris Metcalf <cmetcalf@mellanox.com> wrote:
>> On 7/11/2016 3:26 PM, H.J. Lu wrote:
>>>
>>> SYSCALL_LL/SYSCALL_LL64 should be used to pass 64-bit value to system
>>> calls.
>>
>>
>> What problem are you trying to solve?
>>
>> SYSCALL_LL and LO_HI_LONG are different on big-endian systems. In this
>> case, LO_HI_LONG is correct, since the kernel API is "unsigned long pos_l,
>> unsigned long pos_h". SYSCALL_LL won't do the right thing.
>>
>> __ALIGNMENT_ARG introduces an extra dummy arguments to be inserted before
>> a 64-bit value split into two 32-bit registers, if required by the platform.
>> Since preadv/pwritev explicitly use split arguments to construct a 64-bit
>> loff_t, __ALIGNMENT_ARG will just add a random inappropriate dummy arg
>> to an API that doesn't need one.
>>
>> I reviewed the casting for LO_HI_LONG and it looks OK; I initially was
>> wondering whether losing the "val >> 31, val" semantics from SYSCALL_LL()
>> might have been problematic, but it seems like LO_HI_LONG should generate
>> the same results.
>>
>
> /* Provide a macro to pass the off{64}_t argument on p{readv,writev}{64}. */
> #define LO_HI_LONG(val) \
> (long) (val), \
> (long) (((uint64_t) (val)) >> 32)
>
> is wrong for __ASSUME_WORDSIZE64_ILP32 platform.
>
I am testing this.
--
H.J.
From 4124e3305bdf0060d3766486673ad0dd29a3a727 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 11 Jul 2016 14:56:33 -0700
Subject: [PATCH] X86-64: Define LO_HI_LONG to skip pos_h [BZ #20349]
Define LO_HI_LONG to skip pos_h since it is ignored by kernel:
static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
{
#define HALF_LONG_BITS (BITS_PER_LONG / 2)
return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
}
where size of loff_t == size of long.
[BZ #20349]
* sysdeps/unix/sysv/linux/x86_64/sysdep.h (LO_HI_LONG): New.
---
sysdeps/unix/sysv/linux/x86_64/sysdep.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index d023d68..1a671e1 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -385,4 +385,8 @@
# endif
#endif
+/* 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/sysdep.h */
--
2.7.4