V2 [PATCH 2/3] x32: Properly pass long to syscall [BZ #25810]

Florian Weimer fw@deneb.enyo.de
Mon Apr 13 21:13:02 GMT 2020


* H. J. Lu via Libc-alpha:

>> > diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
>> > index 2b5cf0c0ea..67335c2a7f 100644
>> > --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
>> > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
>> > @@ -44,6 +44,20 @@
>> >  # define ZERO_EXTEND_5 movl %r8d, %r8d;
>> >  # undef ZERO_EXTEND_6
>> >  # define ZERO_EXTEND_6 movl %r9d, %r9d;
>> > +#else /*! __ASSEMBLER__ */
>> > +# undef ARGIFY
>> > +/* Enforce zero-extension for pointers and array system call arguments.
>> > +   For integer types, extend to int64_t (the full register) using a
>> > +   regular cast, resulting in zero or sign extension based on the
>> > +   signedness of the original type.  */
>> > +# define ARGIFY(X) \
>> > + ({                                                                  \
>> > +    _Pragma ("GCC diagnostic push");                                 \
>> > +    _Pragma ("GCC diagnostic ignored \"-Wpointer-to-int-cast\"");    \
>> > +    (__builtin_classify_type (X) == 5                                        \
>> > +     ? (uintptr_t) (X) : (int64_t) (X));                             \
>> > +    _Pragma ("GCC diagnostic pop");                                  \
>> > +  })
>> >  #endif       /* __ASSEMBLER__ */
>> >
>> >  #endif /* linux/x86_64/x32/sysdep.h */
>>
>> I face a similar issue when fixing BZ#12683 for x32, and one possible
>> solution I found was:
>>
>>   #define __SSC(__x)                                            \
>>   ({                                                            \
>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
>>       ? (unsigned long int) (uintptr_t)(__x)                    \
>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
>>     __arg;                                                      \
>>   })
>
> This is similar to what I have checked in.

I think Adhemerval specifically meant the additional cast using
__typeof__ to suppress the warning (which I did not think of).

The _Pragma construct as written is a Clang porting hazard because it
causes the statement expression to return void (which is a Clang/GCC
discrepancy).  Rather than introducing a temporary, using the
__typeof__ hack is probably the better way of fixing it.


More information about the Libc-alpha mailing list