[v3,1/5] y2038: Introduce __ASSUME_TIME64_SYSCALLS define
Commit Message
This define indicates if the Linux kernel (5.1+) provides 64 bit versions
of time related syscalls (e.g. clock_settime64).
Those syscalls are now (starting from Linux 5.1) available on actively
supported Linux architectures: arm, arm64 (compat mode), m68k, microblaze,
mips, parisc, powerpc, s390, sh, sparc, x86, xtensa.
For x32 this flag is explicitly undefined as this architecture uses time
related syscalls from x86_64 (as if it were __WORDSIZE==64 && __TIMESIZE==64).
* sysdeps/unix/sysv/linux/kernel-features.h: (__ASSUME_TIME64_SYSCALLS):
[__LINUX_KERNEL_VERSION >= 0x050100]: Define.
* sysdeps/unix/sysv/linux/x86_64/kernel-features.h (__ASSUME_TIME64_SYSCALLS):
#undef the __ASSUME_TIME64_SYSCALLS for x32 architecture
---
Changes for v3:
- Provide more detailed and verbose description
- Change name to __ASSUME_TIME64_SYSCALLS
- Undefine __ASSUME_TIME64_SYSCALLS on x32
Changes for v2:
- New patch
---
sysdeps/unix/sysv/linux/kernel-features.h | 38 ++++++++++++++++++++++++
sysdeps/unix/sysv/linux/x86_64/kernel-features.h | 9 ++++++
2 files changed, 47 insertions(+)
Comments
On Tue, 7 May 2019, Lukasz Majewski wrote:
> +/* Support for 64 bit version of time related Linux syscalls.
There are several issues with this comment.
(a) It's no longer listing or more precisely describing the syscalls in
question. "64 bit version of time related Linux syscalls" is not adequate
because of the likelihood of having more than one such set in future, with
different conditions for being present in the kernel.
(b) The several variants described in the comment are variants at the
wrong logical level for describing __ASSUME_TIME64_SYSCALLS - they are
different kinds of glibc configurations (with regard to all aspects of how
time is handled in glibc), not different kinds of syscall ABI.
__ASSUME_TIME64_SYSCALLS is a property of the Linux kernel syscall ABI.
The comment should describe its semantics in those terms (in terms of the
syscall ABI's "long"), without confusing it with other related concepts.
If these variants are described anywhere in glibc, it should be in the
internals section of the manual.
(c) The comment should not refer to the user-level interface _TIME_BITS
either, as that's also confusing features at different levels.
@@ -143,3 +143,41 @@
*/
#define __ASSUME_CLONE_DEFAULT 1
+
+#include <bits/wordsize.h>
+#if __WORDSIZE != 64
+/* Support for 64 bit version of time related Linux syscalls.
+
+ 1. Architectures with __WORDSIZE==64 && __TIMESIZE==64 (e.g. x86_64,
+ aarch64) - this flag is never defined (as those already use 64 bit
+ syscalls to handle time).
+
+ 2. Architectures with __WORDSIZE==32 && __TIMESIZE==32 (e.g. arm, x86)
+ 2a. With Y2038 support - userspace must be compiled with
+ -D_TIME_BITS == 64 and as a result __USE_TIME_BITS64 defined
+ (time_t is an alias to time64_t in glibc's exported headers)
+
+ Those systems would use 64 bit Linux system calls to provide 64 bit
+ time support.
+
+ 2b. Without Y2038 support (-D_TIME_BITS not defined or not equal to 64)
+ Such systems would use internally (in glibc) calls to 64 bit syscalls
+ with returning overflow errors after Y2038.
+
+ 3. Architectures with __WORDSIZE==32 && __TIMESIZE==64
+ 3a. __TIMESIZE==64 due to architecture design (for now it is only 'x32')
+ This is a special case as 'x32' architecture has 64 bit size of
+ registers but longs and pointers are 32 bit.
+ It shall use the same time related syscalls as x86_64, so the flag
+ shall be explicitly undefined.
+ 3b. __TIMESIZE==64 imposed by software development (in both cases discussed
+ below the __USE_TIME_BITS64 is defined by default):
+ - For new 32 bit architectures glibc support with 64 bit time support
+ from the outset (which beforehand requires proper syscalls from
+ kernel)
+ - After the 64 bit time support conversion is finished (i.e. arm with
+ Y2038 support). */
+# if __LINUX_KERNEL_VERSION >= 0x050100
+# define __ASSUME_TIME64_SYSCALLS 1
+# endif
+#endif
@@ -24,3 +24,12 @@
#endif
#include_next <kernel-features.h>
+
+/* For x32, which is a special case in respect to 64 bit time support,
+ the __ASSUME_TIME64_SYSCALLS define needs to be explicitly undefined.
+
+ It uses Linux time related syscalls for x86_64 (in compatibility
+ mode). */
+#ifdef __ILP32__
+# undef __ASSUME_TIME64_SYSCALLS
+#endif