[v3,1/5] y2038: Introduce __ASSUME_TIME64_SYSCALLS define

Message ID 20190507131848.30980-2-lukma@denx.de
State Superseded
Headers

Commit Message

Lukasz Majewski May 7, 2019, 1:18 p.m. UTC
  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

Joseph Myers May 7, 2019, 4:04 p.m. UTC | #1
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.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index bc5c959f58..d2ed6f5679 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -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
diff --git a/sysdeps/unix/sysv/linux/x86_64/kernel-features.h b/sysdeps/unix/sysv/linux/x86_64/kernel-features.h
index 26280f57ec..e1e923f497 100644
--- a/sysdeps/unix/sysv/linux/x86_64/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/x86_64/kernel-features.h
@@ -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