Re: [PATCH] uapi: Make __{u,s}64 match {u,}int64_t in userspace
From: Arnd Bergmann <arnd@arndb.de>
Date: 2021-11-23 14:19:04
Also in:
linux-arch, lkml, ltp
On Tue, Nov 23, 2021 at 10:14 AM Cyril Hrubis [off-list ref] wrote:
quoted
I don't think this is correct on all 64-bit architectures, as far as I remember the definition can use either 'long' or 'long long' depending on the user space toolchain.As far as I can tell the userspace bits/types.h does exactly the same check in order to define uint64_t and int64_t, i.e.: #if __WORDSIZE == 64 typedef signed long int __int64_t; typedef unsigned long int __uint64_t; #else __extension__ typedef signed long long int __int64_t; __extension__ typedef unsigned long long int __uint64_t; #endif The macro __WORDSIZE is defined per architecture, and it looks like the defintions in glibc sources in bits/wordsize.h match the uapi asm/bitsperlong.h. But I may have missed something, the code in glibc is not exactly easy to read.
It's possible that the only difference between the two files was the '__u32'/'__s32' definition, which could be either 'int' or 'long'. We used to try matching the user space types for these, but not use 'int' everywhere in the kernel.
quoted
Out of the ten supported 64-bit architectures, there are four that already use asm-generic/int-l64.h conditionally, and six that don't, and I think at least some of those are intentional. I think it would be safer to do this one architecture at a time to make sure this doesn't regress on those that require the int-ll64.h version.I'm still trying to understand what exactly can go wrong here. As long as __BITS_PER_LONG is correctly defined the __u64 and __s64 will be correctly sized as well. The only visible change is that one 'long' is dropped from the type when it's not needed.
Correct, I'm not worried about getting incorrectly-sized types here,
but using the wrong type can cause compile-time warnings when
they are mismatched against format strings or assigning pointers
to the wrong types. With the kernel types, one would always use
%d for __u32 and %lld for __u64, while with the user space types,
one has to resort to using macros.
Arnd