unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
@ 2020-12-04 23:35 Lukasz Majewski
  2020-12-04 23:35 ` [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems Lukasz Majewski
                   ` (6 more replies)
  0 siblings, 7 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:35 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

This patch series is the RFC for preparing glibc to be Y2038 safe on
ports with __WORDSIZE=32 && __TIMESIZE!=64 (e.g. 32 bit ARM).

First patch provides necessary definitions and redirections to
achieve the above task.

Following patches are adjustments to glibc to provide proper handling
of 64 bit time in some exported and local structures. Those patches
shall be applied before the first one is pulled.

This patch set causes following Y2038 tests being all passed:
https://github.com/lmajewski/y2038-tests/

Those tests are run as part of meta-y2038:
https://github.com/lmajewski/meta-y2038/

Lukasz Majewski (6):
  y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit
    systems
  y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038
    systems
  y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64}
    content
  y2038: Enhance struct msqid_ds to support 64 bit time
  msqid: Provide internal copy of struct __msqid64_ds
  msg: provide glibc local copy of struct msqid_ds

 include/bits/types/struct_msqid64_ds.h        |  36 +++++
 include/features.h                            |  19 +++
 io/Versions                                   |   6 +
 io/sys/poll.h                                 |  11 ++
 io/sys/stat.h                                 | 100 +++++++++++-
 io/utime.h                                    |  15 ++
 manual/creature.texi                          |  28 ++++
 misc/Versions                                 |   5 +
 misc/sys/select.h                             |  27 ++++
 nptl/Versions                                 |  15 ++
 posix/Versions                                |   2 +
 posix/sched.h                                 |   9 ++
 posix/sys/wait.h                              |  20 +++
 resolv/Versions                               |   3 +
 resolv/netdb.h                                |  11 ++
 resource/Versions                             |   1 +
 resource/bits/types/struct_rusage.h           |   5 +
 resource/sys/resource.h                       |  10 ++
 rt/Versions                                   |   7 +
 rt/aio.h                                      |  25 ++-
 rt/mqueue.h                                   |  25 +++
 signal/Versions                               |   3 +
 signal/signal.h                               |  12 ++
 socket/sys/socket.h                           |  11 ++
 sysdeps/nptl/pthread.h                        | 117 ++++++++++++++
 sysdeps/pthread/semaphore.h                   |  23 +++
 sysdeps/pthread/threads.h                     |  33 ++++
 sysdeps/unix/sysv/linux/Makefile              |   3 +-
 sysdeps/unix/sysv/linux/Versions              |   7 +
 sysdeps/unix/sysv/linux/bits/struct_stat.h    |  17 +-
 .../linux/bits/struct_stat_time64_helper.h    |  70 +++++++++
 sysdeps/unix/sysv/linux/bits/time.h           |  10 ++
 sysdeps/unix/sysv/linux/bits/timex.h          |  31 ++++
 .../sysv/linux/bits/types/struct_msqid64_ds.h |   4 -
 .../sysv/linux/bits/types/struct_msqid_ds.h   |   8 +
 .../linux/hppa/bits/types/struct_msqid_ds.h   |   8 +
 sysdeps/unix/sysv/linux/include/sys/msg.h     |  66 +++++++-
 .../unix/sysv/linux/m68k/bits/struct_stat.h   |  16 ++
 .../sysv/linux/microblaze/bits/struct_stat.h  |  16 ++
 .../unix/sysv/linux/mips/bits/struct_stat.h   |  16 ++
 .../linux/mips/bits/types/struct_msqid_ds.h   |  12 +-
 .../sysv/linux/powerpc/bits/struct_stat.h     |  48 ++++--
 .../powerpc/bits/types/struct_msqid_ds.h      |   8 +
 .../linux/sparc/bits/types/struct_msqid_ds.h  |   8 +
 sysdeps/unix/sysv/linux/struct_stat_time64.h  |  60 ++-----
 sysdeps/unix/sysv/linux/sys/timerfd.h         |  22 +++
 sysdeps/unix/sysv/linux/sys/timex.h           |  37 ++++-
 .../unix/sysv/linux/x86/bits/struct_stat.h    |  16 ++
 sysvipc/Versions                              |   2 +
 sysvipc/sys/msg.h                             |  10 ++
 sysvipc/sys/sem.h                             |  21 +++
 sysvipc/sys/shm.h                             |  10 ++
 time/Versions                                 |  24 +++
 time/bits/types/struct_timespec.h             |  17 +-
 time/bits/types/struct_timeval.h              |   5 +
 time/bits/types/time_t.h                      |   4 +
 time/sys/time.h                               |  91 +++++++++++
 time/time.h                                   | 146 ++++++++++++++++++
 58 files changed, 1294 insertions(+), 98 deletions(-)
 create mode 100644 include/bits/types/struct_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h

-- 
2.20.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
@ 2020-12-04 23:35 ` Lukasz Majewski
  2020-12-05  0:12   ` Joseph Myers
  2020-12-04 23:36 ` [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems Lukasz Majewski
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:35 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

This change introduces new compile time, supported by glibc flag - namely
_TIME_BITS, which then is responsible for exporting __USE_TIME_BITS64 only
when:
- _TIME_BITS=64 && _FILE_OFFSET_BITS=64 are set in the compilation phase
  (via e.g. -D switch)
and
- The glibc port has __TIMESIZE != 64 && __WORDSIZE == 32 (those are
  internal glibc defines)

It shall be also emphasized that for proper support of 64 bit time on
ports with __TIMESIZE != 64 && __WORDSIZE == 32 (e.g. 32 bit ARM) the
Linux kernel shall be newer than v5.1. Otherwise, as a fallback, 32 bit
syscalls are used. Those will fail after Y2038 trigger date (19.01.2038
- 03:14:08 UTC).

Exported headers have been modified accordingly when __USE_TIME_BITS64 is
defined (this exported flag is set only when _TIME_BITS=64 and
_FILE_OFFSET_BITS=64 are set on compilation time).
To be more specific - structures' names have been kept (no new 64 bit
specific ones were exported), but were extended with 64 bit versions of
time related fields.
For example struct timespec now is modified when __USE_TIME_BITS64 is
defined to have __time64_t fields instead of __time_t, which are only
capable to hold 32 bit time.

Moreover, exported headers now have redirection for time related
functions. For example, when __USE_TIME_BIT64 is defined - calls to
clock_settime are redirected to clock_settime64, which supports setting
64 bit time in glibc ports with __WORDSIZE==32 and __TIMESIZE != 64.

This patch also converts following syscalls to support 64 bit time
(and hence being Y2038 safe):
- difftime
- mktime
- timegm
- ctime_r
- ctime
- gmtime_r
- gmtime
- clock_gettime64
- clock_settime64
- clock_getres64
- utimensat
- futimens
- clock_nanosleep_time64
- ppoll64
- timer_gettime
- timer_settime
- difftime
- timerfd_gettime
- timerfd_settime
- sched_rr_get_interval
- timespec_get
- settimeofday
- gettimeofday
- setitimer
- getitimer
- getrusage
- wait4_time64
- utimes
- utime
- mq_timedsend
- mq_timedreceive
- futimes
- lutimes
- futimesat
- semtimedop -> credits: Adhemerval Zanella
- pselect   -> credits: Adhemerval Zanella
- recvmmsg   -> credits: Adhemerval Zanella
- nanosleep  -> credits: Adhemerval Zanella
- select     -> credits: Adhemerval Zanella
- sigtimedwait -> credits: Adhemerval Zanella
- stat -> credits: Adhemerval Zanella
- fstat -> credits: Adhemerval Zanella
- lstat -> credits: Adhemerval Zanella
- fstatat -> credits: Adhemerval Zanella

- clock_adjtime64
- adjtime
- adjtimex
- ntp_gettime
- ntp_gettimex
- ntp_adjtime - just alias to ___adjtimex64 function

- wait3 -> credits: Adhemerval Zanella

- nptl (uses futex_time64):
        - pthread_timedjoin_np
        - pthread_clockjoin_np
        - pthread_cond_clockwait
        - pthread_cond_timedwait
        - sem_clockwait
        - sem_timedwait
        - pthread_rwlock_clockrdlock
        - pthread_rwlock_clockwrlock
        - pthread_rwlock_timedrdlock
        - pthread_rwlock_timedwrlock
        - pthread_mutex_clocklock
        - pthread_mutex_timedlock

- C11 threads
        - mtx_timedlock
        - cnd_timedwait
        - thrd_sleep

- time
- aio_suspend
- gai_suspend

Structures converted/exported:
-----------------------------
- struct timespec
- struct itimerspec
- struct timeval
- struct rusage
- WIP: export of struct stat{64}

TO DO:
------
- Make exportable struct __stat64_t64 and __rusage64 (to be usable when we
  redirect glibc syscalls symbols)
- Provide Y2038 support for struct msqid_ds (and msgctl() syscall in general
- Provide Y2038 support for struct semid_ds
- Port tests from y2038-tests repository to glibc -master branch

Dependencies:
-------------
This work depends on login and utmp{x} patches developed by Adhemerval
Zanella (from sourceware/azanella/y2038),which bring 64 bit support for
them.
---
 include/features.h                    |  19 ++++
 io/Versions                           |   2 +
 io/sys/poll.h                         |  11 ++
 io/sys/stat.h                         |  20 ++++
 io/utime.h                            |  15 +++
 manual/creature.texi                  |  28 +++++
 misc/Versions                         |   5 +
 misc/sys/select.h                     |  27 +++++
 nptl/Versions                         |  15 +++
 posix/Versions                        |   2 +
 posix/sched.h                         |   9 ++
 posix/sys/wait.h                      |  20 ++++
 resolv/Versions                       |   3 +
 resolv/netdb.h                        |  11 ++
 resource/Versions                     |   1 +
 resource/bits/types/struct_rusage.h   |   5 +
 resource/sys/resource.h               |  10 ++
 rt/Versions                           |   7 ++
 rt/aio.h                              |  25 ++++-
 rt/mqueue.h                           |  25 +++++
 signal/Versions                       |   3 +
 signal/signal.h                       |  12 +++
 socket/sys/socket.h                   |  11 ++
 sysdeps/nptl/pthread.h                | 117 +++++++++++++++++++++
 sysdeps/pthread/semaphore.h           |  23 ++++
 sysdeps/pthread/threads.h             |  33 ++++++
 sysdeps/unix/sysv/linux/Versions      |   7 ++
 sysdeps/unix/sysv/linux/bits/time.h   |  10 ++
 sysdeps/unix/sysv/linux/bits/timex.h  |  31 ++++++
 sysdeps/unix/sysv/linux/sys/timerfd.h |  22 ++++
 sysdeps/unix/sysv/linux/sys/timex.h   |  37 ++++++-
 sysvipc/Versions                      |   2 +
 sysvipc/sys/msg.h                     |  10 ++
 sysvipc/sys/sem.h                     |  21 ++++
 sysvipc/sys/shm.h                     |  10 ++
 time/Versions                         |  24 +++++
 time/bits/types/struct_timespec.h     |  17 +--
 time/bits/types/struct_timeval.h      |   5 +
 time/bits/types/time_t.h              |   4 +
 time/sys/time.h                       |  91 ++++++++++++++++
 time/time.h                           | 146 ++++++++++++++++++++++++++
 41 files changed, 884 insertions(+), 12 deletions(-)

diff --git a/include/features.h b/include/features.h
index f3e62d3362..c639c044b4 100644
--- a/include/features.h
+++ b/include/features.h
@@ -380,6 +380,25 @@
 # define __USE_FILE_OFFSET64	1
 #endif
 
+/* We need to know the word size in order to check the time size.  */
+#include <bits/wordsize.h>
+
+#if defined _TIME_BITS
+# if _TIME_BITS == 64
+#  if ! defined (_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
+#   error _TIME_BITS==64 is allowed only when _FILE_OFFSET_BITS==64
+#  elif __WORDSIZE == 32
+#   define __USE_TIME_BITS64	1
+#  endif
+# elif _TIME_BITS == 32
+#  if __WORDSIZE > 32
+#   error _TIME_BITS=32 is not compatible with __WORDSIZE > 32
+#  endif
+# else
+#  error Invalid _TIME_BITS value (can only be 32 or 64)
+# endif
+#endif
+
 #if defined _DEFAULT_SOURCE
 # define __USE_MISC	1
 #endif
diff --git a/io/Versions b/io/Versions
index 49c4d2d40a..15616b68f3 100644
--- a/io/Versions
+++ b/io/Versions
@@ -146,5 +146,7 @@ libc {
     __file_change_detection_for_path;
     __file_change_detection_for_fp;
     __fstat64;
+    __ppoll64;
+    __utime64;
   }
 }
diff --git a/io/sys/poll.h b/io/sys/poll.h
index 857be0f5ac..4a725ed18e 100644
--- a/io/sys/poll.h
+++ b/io/sys/poll.h
@@ -63,6 +63,17 @@ extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
 extern int ppoll (struct pollfd *__fds, nfds_t __nfds,
 		  const struct timespec *__timeout,
 		  const __sigset_t *__ss);
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (ppoll, (struct pollfd *__fds, nfds_t __nfds,
+                               const struct timespec *__timeout,
+                               const __sigset_t *__ss),
+                       __ppoll64);
+#  else
+#  define ppoll __ppoll64
+#  endif
+# endif
 #endif
 
 __END_DECLS
diff --git a/io/sys/stat.h b/io/sys/stat.h
index 58c3770622..b3f2f0da99 100644
--- a/io/sys/stat.h
+++ b/io/sys/stat.h
@@ -361,11 +361,31 @@ extern int utimensat (int __fd, const char *__path,
 		      const struct timespec __times[2],
 		      int __flags)
      __THROW __nonnull ((2));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (utimensat, (int fd, const char *__path,
+                                       const struct timespec __times[2],
+                                       int flags),
+                           __utimensat64) __nonnull ((2));
+#  else
+#  define utimensat __utimensat64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_XOPEN2K8
 /* Set file access and modification times of the file associated with FD.  */
 extern int futimens (int __fd, const struct timespec __times[2]) __THROW;
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (futimens, (int fd, const struct timespec __times[2]),
+                           __futimens64);
+#  else
+#  define futimens __futimens64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_GNU
diff --git a/io/utime.h b/io/utime.h
index 07659016ab..c3e7e5fce1 100644
--- a/io/utime.h
+++ b/io/utime.h
@@ -35,8 +35,13 @@ __BEGIN_DECLS
 /* Structure describing file times.  */
 struct utimbuf
   {
+# ifdef __USE_TIME_BITS64
+    __time64_t actime;		/* Access time.  */
+    __time64_t modtime;		/* Modification time.  */
+# else
     __time_t actime;		/* Access time.  */
     __time_t modtime;		/* Modification time.  */
+# endif
   };
 
 /* Set the access and modification times of FILE to those given in
@@ -45,6 +50,16 @@ extern int utime (const char *__file,
 		  const struct utimbuf *__file_times)
      __THROW __nonnull ((1));
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (utime, (const char *__file,
+                                   const struct utimbuf *__file_times),
+                           __utime64);
+# else
+# define utime __utime64
+# endif
+#endif
+
 __END_DECLS
 
 #endif /* utime.h */
diff --git a/manual/creature.texi b/manual/creature.texi
index be5050468b..5389fb0f34 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -165,6 +165,34 @@ This macro was introduced as part of the Large File Support extension
 (LFS).
 @end defvr
 
+@defvr Macro _TIME_BITS
+This macro determines the bit size of @code{time_t} (and therefore the
+bit size of all @code{time_t} derived types and the prototypes of all
+related functions). If @code{_TIME_BITS} is undefined, the bit size of
+time_t equals the bit size of the architecture.
+
+If @code{_TIME_BITS} is undefined, or if @code{_TIME_BITS} is defined
+to the value @code{32} and @code{__WORDSIZE} is defined to the value
+@code{32}, or or if @code{_TIME_BITS} is defined to the value @code{64}
+and @code{__WORDSIZE} is defined to the value @code{64}, nothing changes.
+
+If @code{_TIME_BITS} is defined to the value @code{64} and if
+@code{__WORDSIZE} is defined to the value @code{32}, then the @w{64 bit}
+time API and implementation are used even though the architecture word
+size is @code{32}. Also, if the kernel provides @w{64 bit} time support,
+it is used; otherwise, the @w{32 bit} kernel time support is used (with
+no provision to address kernel Y2038 shortcomings).
+
+If @code{_TIME_BITS} is defined to the value @code{32} and if
+@code{__WORDSIZE} is defined to the value @code{64}, then a compile-time
+error is emitted.
+
+If @code{_TIME_BITS} is defined to a value different from both @code{32}
+and @code{64}, then a compile-time error is emitted.
+
+This macro was introduced as part of the Y2038 support.
+@end defvr
+
 @defvr Macro _ISOC99_SOURCE
 @standards{GNU, (none)}
 If this macro is defined, features from ISO C99 are included.  Since
diff --git a/misc/Versions b/misc/Versions
index 95666f6548..fb30af2079 100644
--- a/misc/Versions
+++ b/misc/Versions
@@ -172,5 +172,10 @@ libc {
     __mmap; __munmap; __mprotect;
     __sched_get_priority_min; __sched_get_priority_max;
     __libc_allocate_once_slow;
+    __utimes64;
+    __futimes64;
+    __lutimes64;
+    __futimesat64;
+    __select64;
   }
 }
diff --git a/misc/sys/select.h b/misc/sys/select.h
index 29d011c2d5..779a6e81b6 100644
--- a/misc/sys/select.h
+++ b/misc/sys/select.h
@@ -103,6 +103,19 @@ extern int select (int __nfds, fd_set *__restrict __readfds,
 		   fd_set *__restrict __exceptfds,
 		   struct timeval *__restrict __timeout);
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (select,
+                       (int __nfds, fd_set *__restrict __readfds,
+                        fd_set *__restrict __writefds,
+                        fd_set *__restrict __exceptfds,
+                        struct timeval *__restrict __timeout),
+                       __select64);
+# else
+#  define select __select64
+# endif
+#endif
+
 #ifdef __USE_XOPEN2K
 /* Same as above only that the TIMEOUT value is given with higher
    resolution and a sigmask which is been set temporarily.  This version
@@ -115,6 +128,20 @@ extern int pselect (int __nfds, fd_set *__restrict __readfds,
 		    fd_set *__restrict __exceptfds,
 		    const struct timespec *__restrict __timeout,
 		    const __sigset_t *__restrict __sigmask);
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (pselect,
+                       (int __nfds, fd_set *__restrict __readfds,
+                        fd_set *__restrict __writefds,
+                        fd_set *__restrict __exceptfds,
+                        const struct timespec *__restrict __timeout,
+                        const __sigset_t *__restrict __sigmask),
+                       __pselect64);
+#  else
+#   define pselect __pselect64
+#  endif
+# endif
 #endif
 
 
diff --git a/nptl/Versions b/nptl/Versions
index 02650fe91c..b741ad1c77 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -305,5 +305,20 @@ libpthread {
     __futex_abstimed_wait64; __futex_abstimed_wait_cancelable64;
     __shm_directory;
     __libpthread_freeres;
+    __pthread_timedjoin_np64;
+    __pthread_clockjoin_np64;
+    __pthread_cond_timedwait64;
+    __pthread_cond_clockwait64;
+    __sem_clockwait64;
+    __sem_timedwait64;
+    __pthread_rwlock_clockrdlock64;
+    __pthread_rwlock_clockwrlock64;
+    __pthread_rwlock_timedrdlock64;
+    __pthread_rwlock_timedwrlock64;
+    __pthread_mutex_timedlock64;
+    __pthread_mutex_clocklock64;
+    __cnd_timedwait64;
+    __mtx_timedlock64;
+    __thrd_sleep64;
   }
 }
diff --git a/posix/Versions b/posix/Versions
index 7d06a6d0c0..cebbd2aeb8 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -150,5 +150,7 @@ libc {
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
+    __wait4_time64; __pselect64;
+    __nanosleep64; __wait3_time64;
   }
 }
diff --git a/posix/sched.h b/posix/sched.h
index 60c9c3c710..0d9cbc5bb2 100644
--- a/posix/sched.h
+++ b/posix/sched.h
@@ -76,6 +76,15 @@ extern int sched_get_priority_min (int __algorithm) __THROW;
 /* Get the SCHED_RR interval for the named process.  */
 extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (sched_rr_get_interval,
+                           (__pid_t __pid, struct timespec *__t),
+                           __sched_rr_get_interval64);
+# else
+# define sched_rr_get_interval __sched_rr_get_interval64
+# endif
+#endif
 
 #ifdef __USE_GNU
 /* Access macros for `cpu_set'.  */
diff --git a/posix/sys/wait.h b/posix/sys/wait.h
index a42e16c1b0..68ec036b29 100644
--- a/posix/sys/wait.h
+++ b/posix/sys/wait.h
@@ -146,12 +146,32 @@ struct rusage;
    otherwise don't.  */
 extern __pid_t wait3 (int *__stat_loc, int __options,
 		      struct rusage * __usage) __THROWNL;
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTHNL)
+extern __pid_t __REDIRECT_NTHNL (wait3, (int *__stat_loc, int __options,
+                                         struct rusage * __usage)
+                                 __wait3_time64);
+#  else
+#  define wait3 __wait3_time64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_MISC
 /* PID is like waitpid.  Other args are like wait3.  */
 extern __pid_t wait4 (__pid_t __pid, int *__stat_loc, int __options,
 		      struct rusage *__usage) __THROWNL;
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTHNL)
+extern __pid_t __REDIRECT_NTHNL (wait4, (__pid_t __pid, int *__stat_loc,
+                                         int __options, struct rusage *__usage),
+                                 __wait4_time64);
+#  else
+#  define wait4 __wait4_time64
+#  endif
+# endif
 #endif /* Use misc.  */
 
 
diff --git a/resolv/Versions b/resolv/Versions
index 9a82704af7..d38ee438f1 100644
--- a/resolv/Versions
+++ b/resolv/Versions
@@ -105,4 +105,7 @@ libanl {
   GLIBC_2.2.3 {
     gai_cancel; gai_error; gai_suspend; getaddrinfo_a;
   }
+  GLIBC_PRIVATE {
+    __gai_suspend_time64;
+  }
 }
diff --git a/resolv/netdb.h b/resolv/netdb.h
index 575e416dac..bd0832988f 100644
--- a/resolv/netdb.h
+++ b/resolv/netdb.h
@@ -701,6 +701,17 @@ extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr],
 extern int gai_suspend (const struct gaicb *const __list[], int __ent,
 			const struct timespec *__timeout);
 
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (gai_suspend, (const struct gaicb *const __list[],
+                                     int __ent,
+                                     const struct timespec *__timeout),
+                       __gai_suspend_time64);
+#  else
+#   define gai_suspend __gai_suspend_time64
+#  endif
+# endif
+
 /* Get the error status of the request REQ.  */
 extern int gai_error (struct gaicb *__req) __THROW;
 
diff --git a/resource/Versions b/resource/Versions
index d6c2ccee1b..96a757532f 100644
--- a/resource/Versions
+++ b/resource/Versions
@@ -24,5 +24,6 @@ libc {
   }
   GLIBC_PRIVATE {
     __getrlimit;
+    __getrusage64;
   }
 }
diff --git a/resource/bits/types/struct_rusage.h b/resource/bits/types/struct_rusage.h
index ba0a56871d..00f07e3ee2 100644
--- a/resource/bits/types/struct_rusage.h
+++ b/resource/bits/types/struct_rusage.h
@@ -32,10 +32,15 @@
    for little-endian ones, like x32.  */
 struct rusage
   {
+#ifdef __USE_TIME_BITS64
+    struct __timeval64 ru_utime;
+    struct __timeval64 ru_stime;
+#else
     /* Total amount of user time used.  */
     struct timeval ru_utime;
     /* Total amount of system time used.  */
     struct timeval ru_stime;
+#endif
     /* Maximum resident set size (in kilobytes).  */
     __extension__ union
       {
diff --git a/resource/sys/resource.h b/resource/sys/resource.h
index 4edafb50d5..98f05cf1c4 100644
--- a/resource/sys/resource.h
+++ b/resource/sys/resource.h
@@ -86,6 +86,16 @@ extern int setrlimit64 (__rlimit_resource_t __resource,
    and put it in *USAGE.  Returns 0 for success, -1 for failure.  */
 extern int getrusage (__rusage_who_t __who, struct rusage *__usage) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (getrusage, (__rusage_who_t __who,
+                                       struct rusage *__usage),
+                           __getrusage64);
+# else
+# define getrusage __getrusage64
+# endif
+#endif
+
 /* Return the highest priority of any process specified by WHICH and WHO
    (see above); if WHO is zero, the current process, process group, or user
    (as specified by WHO) is used.  A lower priority number means higher
diff --git a/rt/Versions b/rt/Versions
index 84d1345420..e1e00d88fa 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -1,4 +1,11 @@
 librt {
+  GLIBC_PRIVATE {
+    __timer_gettime64;
+    __timer_settime64;
+    __mq_timedsend_time64;
+    __mq_timedreceive_time64;
+    __aio_suspend_time64;
+  }
   GLIBC_2.1 {
     # AIO functions.
     aio_cancel; aio_cancel64; aio_error; aio_error64; aio_fsync; aio_fsync64;
diff --git a/rt/aio.h b/rt/aio.h
index 148d31a0af..2c35f1b04c 100644
--- a/rt/aio.h
+++ b/rt/aio.h
@@ -193,12 +193,17 @@ extern __ssize_t __REDIRECT_NTH (aio_return, (struct aiocb *__aiocbp),
 extern int __REDIRECT_NTH (aio_cancel,
 			   (int __fildes, struct aiocb *__aiocbp),
 			   aio_cancel64);
-
+#  ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTH (aio_suspend,
+			   (const struct aiocb *const __list[], int __nent,
+			    const struct timespec *__restrict __timeout),
+			   __aio_suspend_time64) __nonnull ((1));
+#  else
 extern int __REDIRECT_NTH (aio_suspend,
 			   (const struct aiocb *const __list[], int __nent,
 			    const struct timespec *__restrict __timeout),
 			   aio_suspend64) __nonnull ((1));
-
+#  endif
 extern int __REDIRECT_NTH (aio_fsync,
 			   (int __operation, struct aiocb *__aiocbp),
 			   aio_fsync64) __nonnull ((2));
@@ -210,7 +215,11 @@ extern int __REDIRECT_NTH (aio_fsync,
 #  define aio_error aio_error64
 #  define aio_return aio_return64
 #  define aio_cancel aio_cancel64
-#  define aio_suspend aio_suspend64
+#  ifdef __USE_TIME_BITS64
+#   define aio_suspend __aio_suspend_time64
+#  else
+#   define aio_suspend aio_suspend64
+#  endif
 #  define aio_fsync aio_fsync64
 # endif
 #endif
@@ -234,6 +243,16 @@ extern int aio_cancel64 (int __fildes, struct aiocb64 *__aiocbp) __THROW;
 extern int aio_suspend64 (const struct aiocb64 *const __list[], int __nent,
 			  const struct timespec *__restrict __timeout)
   __THROW __nonnull ((1));
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (aio_suspend64,
+			   (const struct aiocb *const __list[], int __nent,
+			    const struct timespec *__restrict __timeout),
+			   __aio_suspend_time64) __nonnull ((1));
+#  else
+#   define aio_suspend64 __aio_suspend_time64
+#  endif
+# endif
 
 extern int aio_fsync64 (int __operation, struct aiocb64 *__aiocbp)
   __THROW __nonnull ((2));
diff --git a/rt/mqueue.h b/rt/mqueue.h
index a2a2aa1771..e6b8641c62 100644
--- a/rt/mqueue.h
+++ b/rt/mqueue.h
@@ -79,12 +79,37 @@ extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr,
 				const struct timespec *__restrict __abs_timeout)
   __nonnull ((2, 5));
 
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (mq_timedreceive, (mqd_t __mqdes,
+                               char *__restrict __msg_ptr,
+                               size_t __msg_len,
+                               unsigned int *__restrict __msg_prio,
+                               const struct timespec *__restrict __abs_timeout),
+                       __mq_timedreceive_time64);
+#  else
+#   define mq_timedreceive __mq_timedreceive_time64
+#  endif
+# endif
+
 /* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
    on full message queue if ABS_TIMEOUT expires.  */
 extern int mq_timedsend (mqd_t __mqdes, const char *__msg_ptr,
 			 size_t __msg_len, unsigned int __msg_prio,
 			 const struct timespec *__abs_timeout)
   __nonnull ((2, 5));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (mq_timedsend, (mqd_t __mqdes,
+                       const char *__msg_ptr, size_t __msg_len,
+                       unsigned int __msg_prio,
+                       const struct timespec *__abs_timeout),
+     __mq_timedsend_time64);
+#  else
+#   define mq_timedsend __mq_timedsend_time64
+#  endif
+# endif
 #endif
 
 /* Define some inlines helping to catch common problems.  */
diff --git a/signal/Versions b/signal/Versions
index a915ef400f..d653b5de09 100644
--- a/signal/Versions
+++ b/signal/Versions
@@ -51,4 +51,7 @@ libc {
   }
   GLIBC_2.21 {
   }
+  GLIBC_PRIVATE {
+    __sigtimedwait64;
+  }
 }
diff --git a/signal/signal.h b/signal/signal.h
index effe3d698f..564820e366 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -274,6 +274,18 @@ extern int sigtimedwait (const sigset_t *__restrict __set,
 			 const struct timespec *__restrict __timeout)
      __nonnull ((1));
 
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT)
+extern int __REDIRECT (sigtimedwait,
+                       (const sigset_t *__restrict __set,
+                        siginfo_t *__restrict __info,
+                        const struct timespec *__restrict __timeout),
+                       __sigtimedwait64);
+#   else
+#    define sigtimedwait __sigtimedwait64
+#   endif
+#  endif
+
 /* Send signal SIG to the process PID.  Associate data in VAL with the
    signal.  */
 extern int sigqueue (__pid_t __pid, int __sig, const union sigval __val)
diff --git a/socket/sys/socket.h b/socket/sys/socket.h
index 7780c00ecb..2273c52cdf 100644
--- a/socket/sys/socket.h
+++ b/socket/sys/socket.h
@@ -199,6 +199,17 @@ extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags);
 extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
 		     unsigned int __vlen, int __flags,
 		     struct timespec *__tmo);
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (recvmmsg, (int __fd, struct mmsghdr *__vmessages,
+                                  unsigned int __vlen, int __flags,
+                                  struct timespec *__tmo),
+                       __recvmmsg64);
+#  else
+#   define recvmmsg __recvmmsg64
+#  endif
+# endif
 #endif
 
 
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index 3a34d82342..982ed32baa 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -230,6 +230,17 @@ extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW;
 extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
 				 const struct timespec *__abstime);
 
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (pthread_timedjoin_np,
+                       (pthread_t __th, void **__thread_return,
+                        const struct timespec *__abstime),
+                       __pthread_timedjoin_np64);
+#  else
+#  define pthread_timedjoin_np __pthread_timedjoin_np64
+#  endif
+# endif
+
 /* Make calling thread wait for termination of the thread TH, but only
    until TIMEOUT measured against the clock specified by CLOCKID.  The
    exit status of the thread is stored in *THREAD_RETURN, if
@@ -240,6 +251,18 @@ extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
 extern int pthread_clockjoin_np (pthread_t __th, void **__thread_return,
                                  clockid_t __clockid,
 				 const struct timespec *__abstime);
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (pthread_clockjoin_np,
+                       (pthread_t __th, void **__thread_return,
+                        clockid_t __clockid,
+                        const struct timespec *__abstime),
+                       __pthread_clockjoin_np64);
+#  else
+#  define pthread_clockjoin_np __pthread_clockjoin_np64
+#  endif
+# endif
 #endif
 
 /* Indicate that the thread TH is never to be joined with PTHREAD_JOIN.
@@ -776,6 +799,17 @@ extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
 extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
 				    const struct timespec *__restrict
 				    __abstime) __THROWNL __nonnull ((1, 2));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTHNL)
+extern int __REDIRECT_NTHNL (pthread_mutex_timedlock,
+                             (pthread_mutex_t *__restrict __mutex,
+                              const struct timespec *__restrict __abstime),
+                             __pthread_mutex_timedlock64);
+#  else
+#   define pthread_mutex_timedlock __pthread_mutex_timedlock64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_GNU
@@ -783,6 +817,18 @@ extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex,
 				    clockid_t __clockid,
 				    const struct timespec *__restrict
 				    __abstime) __THROWNL __nonnull ((1, 3));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTHNL)
+extern int __REDIRECT_NTHNL (pthread_mutex_clocklock,
+                             (pthread_mutex_t *__restrict __mutex,
+                              clockid_t __clockid,
+                              const struct timespec *__restrict __abstime),
+                             __pthread_mutex_clocklock64);
+#  else
+#   define pthread_mutex_clocklock __pthread_mutex_clocklock64
+#  endif
+# endif
 #endif
 
 /* Unlock a mutex.  */
@@ -922,6 +968,17 @@ extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
 extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
 				       const struct timespec *__restrict
 				       __abstime) __THROWNL __nonnull ((1, 2));
+
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT_NTHNL)
+extern int __REDIRECT_NTHNL (pthread_rwlock_timedrdlock,
+                             (pthread_rwlock_t *__restrict __rwlock,
+                              const struct timespec *__restrict __abstime),
+                             __pthread_rwlock_timedrdlock64);
+#   else
+#    define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock64
+#   endif
+#  endif
 # endif
 
 # ifdef __USE_GNU
@@ -929,6 +986,18 @@ extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock,
 				       clockid_t __clockid,
 				       const struct timespec *__restrict
 				       __abstime) __THROWNL __nonnull ((1, 3));
+
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT_NTHNL)
+extern int __REDIRECT_NTHNL (pthread_rwlock_clockrdlock,
+                             (pthread_rwlock_t *__restrict __rwlock,
+                              clockid_t __clockid,
+                              const struct timespec *__restrict __abstime),
+                             __pthread_rwlock_clockrdlock64);
+#   else
+#    define pthread_rwlock_clockrdlock __pthread_rwlock_clockrdlock64
+#   endif
+#  endif
 # endif
 
 /* Acquire write lock for RWLOCK.  */
@@ -944,6 +1013,17 @@ extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
 extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
 				       const struct timespec *__restrict
 				       __abstime) __THROWNL __nonnull ((1, 2));
+
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT_NTHNL)
+extern int __REDIRECT_NTHNL (pthread_rwlock_timedwrlock,
+                             (pthread_rwlock_t *__restrict __rwlock,
+                              const struct timespec *__restrict __abstime),
+                             __pthread_rwlock_timedwrlock64);
+#   else
+#    define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock64
+#   endif
+#  endif
 # endif
 
 # ifdef __USE_GNU
@@ -951,6 +1031,18 @@ extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock,
 				       clockid_t __clockid,
 				       const struct timespec *__restrict
 				       __abstime) __THROWNL __nonnull ((1, 3));
+
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT_NTHNL)
+extern int __REDIRECT_NTHNL (pthread_rwlock_clockwrlock,
+                             (pthread_rwlock_t *__restrict __rwlock,
+                              clockid_t __clockid,
+                              const struct timespec *__restrict __abstime),
+                             __pthread_rwlock_clockwrlock64);
+#   else
+#    define pthread_rwlock_clockwrlock __pthread_rwlock_clockwrlock64
+#   endif
+#  endif
 # endif
 
 /* Unlock RWLOCK.  */
@@ -1032,6 +1124,18 @@ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
 				   const struct timespec *__restrict __abstime)
      __nonnull ((1, 2, 3));
 
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (pthread_cond_timedwait,
+                       (pthread_cond_t *__restrict __cond,
+                        pthread_mutex_t *__restrict __mutex,
+                        const struct timespec *__restrict __abstime),
+                       __pthread_cond_timedwait64);
+#  else
+#  define pthread_cond_timedwait __pthread_cond_timedwait64
+#  endif
+# endif
+
 # ifdef __USE_GNU
 /* Wait for condition variable COND to be signaled or broadcast until
    ABSTIME measured by the specified clock. MUTEX is assumed to be
@@ -1045,6 +1149,19 @@ extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond,
 				   __clockid_t __clock_id,
 				   const struct timespec *__restrict __abstime)
      __nonnull ((1, 2, 4));
+
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT)
+extern int __REDIRECT (pthread_cond_clockwait,
+                       (pthread_cond_t *__restrict __cond,
+                        pthread_mutex_t *__restrict __mutex,
+                        __clockid_t __clock_id,
+                        const struct timespec *__restrict __abstime),
+                       __pthread_cond_clockwait64);
+#   else
+#   define pthread_cond_clockwait __pthread_cond_clockwait64
+#   endif
+#  endif
 # endif
 
 /* Functions for handling condition variable attributes.  */
diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
index 436d21cb08..6a6055fc3a 100644
--- a/sysdeps/pthread/semaphore.h
+++ b/sysdeps/pthread/semaphore.h
@@ -62,6 +62,17 @@ extern int sem_wait (sem_t *__sem) __nonnull ((1));
 extern int sem_timedwait (sem_t *__restrict __sem,
 			  const struct timespec *__restrict __abstime)
   __nonnull ((1, 2));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (sem_timedwait,
+                       (sem_t *__restrict __sem,
+                        const struct timespec *__restrict __abstime),
+                        __sem_timedwait64);
+#  else
+#   define sem_timedwait __sem_timedwait64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_GNU
@@ -69,6 +80,18 @@ extern int sem_clockwait (sem_t *__restrict __sem,
 			  clockid_t clock,
 			  const struct timespec *__restrict __abstime)
   __nonnull ((1, 3));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (sem_clockwait,
+                       (sem_t *__restrict __sem,
+                        clockid_t clock,
+                        const struct timespec *__restrict __abstime),
+                        __sem_clockwait64);
+#  else
+#   define sem_clockwait __sem_clockwait64
+#  endif
+# endif
 #endif
 
 /* Test whether SEM is posted.  */
diff --git a/sysdeps/pthread/threads.h b/sysdeps/pthread/threads.h
index 0ac489b4a1..acdc7b329a 100644
--- a/sysdeps/pthread/threads.h
+++ b/sysdeps/pthread/threads.h
@@ -91,6 +91,16 @@ extern thrd_t thrd_current (void);
 extern int thrd_sleep (const struct timespec *__time_point,
 		       struct timespec *__remaining);
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (thrd_sleep, (const struct timespec *__time_point,
+                                    struct timespec *__remaining),
+                       __thrd_sleep64);
+# else
+#  define thrd_sleep __thrd_sleep64
+# endif
+#endif
+
 /* Terminate current thread execution, cleaning up any thread local
    storage and freeing resources.  Returns the value specified in __RES.  */
 extern void thrd_exit (int __res) __attribute__ ((__noreturn__));
@@ -134,6 +144,17 @@ extern int mtx_lock (mtx_t *__mutex);
 extern int mtx_timedlock (mtx_t *__restrict __mutex,
 			  const struct timespec *__restrict __time_point);
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (mtx_timedlock, (mtx_t *__restrict __mutex,
+                                       const struct timespec *__restrict
+                                       __time_point),
+                       __mtx_timedlock64);
+# else
+#  define mtx_timedlock __mtx_timedlock64
+# endif
+#endif
+
 /* Try to lock the mutex pointed by __MUTEX without blocking.  If the mutex
    is free the current threads takes control of it, otherwise it returns
    immediately.  */
@@ -175,6 +196,18 @@ extern int cnd_timedwait (cnd_t *__restrict __cond,
 			  mtx_t *__restrict __mutex,
 			  const struct timespec *__restrict __time_point);
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (cnd_timedwait, (cnd_t *__restrict __cond,
+                                       mtx_t *__restrict __mutex,
+                                       const struct timespec *__restrict
+                                       __time_point),
+                       __cnd_timedwait64);
+# else
+#  define cnd_timedwait __cnd_timedwait64
+# endif
+#endif
+
 /* Destroy condition variable pointed by __cond and free all of its
    resources.  */
 extern void cnd_destroy (cnd_t *__COND);
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index c35f783e2a..11bdef3343 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -179,5 +179,12 @@ libc {
     __sigtimedwait;
     # functions used by nscd
     __netlink_assert_response;
+    __timerfd_gettime64;
+    __timerfd_settime64;
+    __sched_rr_get_interval64;
+    __clock_adjtime64;
+    __ntp_gettime64;
+    __ntp_gettimex64;
+    __recvmmsg64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/bits/time.h b/sysdeps/unix/sysv/linux/bits/time.h
index e0962744e1..7168ef1948 100644
--- a/sysdeps/unix/sysv/linux/bits/time.h
+++ b/sysdeps/unix/sysv/linux/bits/time.h
@@ -77,6 +77,16 @@ __BEGIN_DECLS
 /* Tune a POSIX clock.  */
 extern int clock_adjtime (__clockid_t __clock_id, struct timex *__utx) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (clock_adjtime, (__clockid_t __clock_id,
+                                           struct timex *__utx),
+                           __clock_adjtime64);
+# else
+# define clock_adjtime __clock_adjtime64
+# endif
+#endif
+
 __END_DECLS
 #endif /* use GNU */
 
diff --git a/sysdeps/unix/sysv/linux/bits/timex.h b/sysdeps/unix/sysv/linux/bits/timex.h
index 9adb0bcc60..f1d71ea9c4 100644
--- a/sysdeps/unix/sysv/linux/bits/timex.h
+++ b/sysdeps/unix/sysv/linux/bits/timex.h
@@ -25,6 +25,36 @@
 
 struct timex
 {
+# ifdef __USE_TIME_BITS64
+  unsigned int modes;          /* mode selector */
+  int :32;                     /* pad */
+  long long offset;            /* time offset (usec) */
+  long long freq;              /* frequency offset (scaled ppm) */
+  long long maxerror;          /* maximum error (usec) */
+  long long esterror;          /* estimated error (usec) */
+  int status;                  /* clock command/status */
+  int :32;                     /* pad */
+  long long constant;          /* pll time constant */
+  long long precision;         /* clock precision (usec) (read only) */
+  long long tolerance;         /* clock frequency tolerance (ppm) (ro) */
+  struct timeval time;     /* (read only, except for ADJ_SETOFFSET) */
+  long long tick;              /* (modified) usecs between clock ticks */
+  long long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
+  long long jitter;            /* pps jitter (us) (ro) */
+  int shift;                   /* interval duration (s) (shift) (ro) */
+  int :32;                     /* pad */
+  long long stabil;            /* pps stability (scaled ppm) (ro) */
+  long long jitcnt;            /* jitter limit exceeded (ro) */
+  long long calcnt;            /* calibration intervals (ro) */
+  long long errcnt;            /* calibration errors (ro) */
+  long long stbcnt;            /* stability limit exceeded (ro) */
+
+  int tai;                     /* TAI offset (ro) */
+
+  int  :32; int  :32; int  :32; int  :32;
+  int  :32; int  :32; int  :32; int  :32;
+  int  :32; int  :32; int  :32;
+# else
   unsigned int modes;		/* mode selector */
   __syscall_slong_t offset;	/* time offset (usec) */
   __syscall_slong_t freq;	/* frequency offset (scaled ppm) */
@@ -51,6 +81,7 @@ struct timex
   int  :32; int  :32; int  :32; int  :32;
   int  :32; int  :32; int  :32; int  :32;
   int  :32; int  :32; int  :32;
+# endif
 };
 
 /* Mode codes (timex.mode) */
diff --git a/sysdeps/unix/sysv/linux/sys/timerfd.h b/sysdeps/unix/sysv/linux/sys/timerfd.h
index 0ae60b65bd..cd252476a7 100644
--- a/sysdeps/unix/sysv/linux/sys/timerfd.h
+++ b/sysdeps/unix/sysv/linux/sys/timerfd.h
@@ -47,9 +47,31 @@ extern int timerfd_settime (int __ufd, int __flags,
 			    const struct itimerspec *__utmr,
 			    struct itimerspec *__otmr) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (timerfd_settime,
+                           (int __ufd, int __flags,
+                            const struct itimerspec *__restrict __value,
+                            struct itimerspec *__restrict __ovalue),
+                           __timerfd_settime64);
+# else
+# define timerfd_settime __timerfd_settime64
+# endif
+#endif
+
 /* Return the next expiration time of UFD.  */
 extern int timerfd_gettime (int __ufd, struct itimerspec *__otmr) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (timerfd_gettime, (int __ufd,
+                                             struct itimerspec *__otmr),
+                           __timerfd_gettime64);
+# else
+# define timerfd_gettime __timerfd_gettime64
+# endif
+#endif
+
 __END_DECLS
 
 #endif /* sys/timerfd.h */
diff --git a/sysdeps/unix/sysv/linux/sys/timex.h b/sysdeps/unix/sysv/linux/sys/timex.h
index 6979b86b72..b5271152bb 100644
--- a/sysdeps/unix/sysv/linux/sys/timex.h
+++ b/sysdeps/unix/sysv/linux/sys/timex.h
@@ -57,15 +57,46 @@ __BEGIN_DECLS
 extern int __adjtimex (struct timex *__ntx) __THROW;
 extern int adjtimex (struct timex *__ntx) __THROW;
 
-#ifdef __REDIRECT_NTH
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (adjtimex, (struct timex *__ntx),
+                           ___adjtimex64);
+# else
+# define adjtimex ___adjtimex64
+# endif
+#endif
+
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
 extern int __REDIRECT_NTH (ntp_gettime, (struct ntptimeval *__ntv),
-			   ntp_gettimex);
+                           __ntp_gettime64);
+extern int __REDIRECT_NTH (ntp_gettimex, (struct ntptimeval *__ntv),
+                           __ntp_gettimex64);
+# else
+# define ntp_gettime __ntp_gettime64
+# define ntp_gettimex __ntp_gettimex64
+# endif
 #else
+# ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (ntp_gettime, (struct ntptimeval *__ntv),
+			   ntp_gettimex);
+# else
 extern int ntp_gettimex (struct ntptimeval *__ntv) __THROW;
-# define ntp_gettime ntp_gettimex
+#  define ntp_gettime ntp_gettimex
+# endif
 #endif
+
 extern int ntp_adjtime (struct timex *__tntx) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (ntp_adjtime, (struct timex *__ntx),
+                           ___adjtimex64);
+# else
+# define ntp_adjtime ___adjtimex64
+# endif
+#endif
+
 __END_DECLS
 
 #endif /* sys/timex.h */
diff --git a/sysvipc/Versions b/sysvipc/Versions
index 4c797e25ce..f81f648960 100644
--- a/sysvipc/Versions
+++ b/sysvipc/Versions
@@ -16,5 +16,7 @@ libc {
   GLIBC_PRIVATE {
     # Cancellation point entries.
     __libc_msgrcv; __libc_msgsnd;
+    __semtimedop64; __shmctl64;
+    __semctl64; __msgctl64;
   }
 }
diff --git a/sysvipc/sys/msg.h b/sysvipc/sys/msg.h
index c70cfa582c..f39c153b86 100644
--- a/sysvipc/sys/msg.h
+++ b/sysvipc/sys/msg.h
@@ -60,6 +60,16 @@ __BEGIN_DECLS
 /* Message queue control operation.  */
 extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (msgctl,
+                           (int __msqid, int __cmd, struct msqid_ds *__buf),
+                           __msgctl64);
+# else
+# define msgctl __msgctl64
+# endif
+#endif
+
 /* Get messages queue.  */
 extern int msgget (key_t __key, int __msgflg) __THROW;
 
diff --git a/sysvipc/sys/sem.h b/sysvipc/sys/sem.h
index 4ede2dd6ef..b26c17914c 100644
--- a/sysvipc/sys/sem.h
+++ b/sysvipc/sys/sem.h
@@ -50,6 +50,16 @@ __BEGIN_DECLS
 /* Semaphore control operation.  */
 extern int semctl (int __semid, int __semnum, int __cmd, ...) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (semctl,
+                           (int __semid, int __semnum, int __cmd, ...),
+                           __semctl64);
+# else
+# define semctl __semctl64
+# endif
+#endif
+
 /* Get semaphore.  */
 extern int semget (key_t __key, int __nsems, int __semflg) __THROW;
 
@@ -60,6 +70,17 @@ extern int semop (int __semid, struct sembuf *__sops, size_t __nsops) __THROW;
 /* Operate on semaphore with timeout.  */
 extern int semtimedop (int __semid, struct sembuf *__sops, size_t __nsops,
 		       const struct timespec *__timeout) __THROW;
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (semtimedop, (int __semid, struct sembuf *__sops,
+                                        size_t __nsops,
+                                        const struct timespec *__timeout),
+                           __semtimedop64);
+#  else
+#  define semtimedop __semtimedop64
+#  endif
+# endif
 #endif
 
 __END_DECLS
diff --git a/sysvipc/sys/shm.h b/sysvipc/sys/shm.h
index 6c58742c4f..8d74911e55 100644
--- a/sysvipc/sys/shm.h
+++ b/sysvipc/sys/shm.h
@@ -48,6 +48,16 @@ __BEGIN_DECLS
 /* Shared memory control operation.  */
 extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (shmctl,
+                           (int __shmid, int __cmd, struct shmid_ds *__buf),
+                           __shmctl64);
+# else
+# define shmctl __shmctl64
+# endif
+#endif
+
 /* Get shared memory segment.  */
 extern int shmget (key_t __key, size_t __size, int __shmflg) __THROW;
 
diff --git a/time/Versions b/time/Versions
index df22ac7f6a..85a3c4d9f2 100644
--- a/time/Versions
+++ b/time/Versions
@@ -1,4 +1,25 @@
 libc {
+  GLIBC_PRIVATE {
+    __difftime64;
+    __mktime64;
+    __timegm64;
+    __ctime64;
+    __ctime64_r;
+    __gmtime64;
+    __gmtime64_r;
+    __clock_settime64;
+    __clock_getres64;
+    __clock_nanosleep_time64;
+    __utimensat64;
+    __futimens64;
+    __timer_gettime64;
+    __timer_settime64;
+    __timespec_get64;
+    __settimeofday64;
+    __gettimeofday64;
+    __getitimer64;
+    __setitimer64;
+  }
   GLIBC_2.0 {
     # global variables
     __daylight; __timezone; __tzname;
@@ -78,5 +99,8 @@ libc {
     # same as clock_gettime; used in other libraries
     __clock_gettime;
     __clock_gettime64;
+    __adjtime64;
+    ___adjtimex64;
+    __time64;
   }
 }
diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h
index d11c69cfd3..3e158ad899 100644
--- a/time/bits/types/struct_timespec.h
+++ b/time/bits/types/struct_timespec.h
@@ -4,25 +4,30 @@
 
 #include <bits/types.h>
 #include <bits/endian.h>
+#include <bits/types/time_t.h>
 
 /* POSIX.1b structure for a time value.  This is like a `struct timeval' but
    has nanoseconds instead of microseconds.  */
 struct timespec
 {
+# ifdef __USE_TIME_BITS64
+  __time64_t tv_sec;		/* Seconds.  */
+# else
   __time_t tv_sec;		/* Seconds.  */
-#if __WORDSIZE == 64 \
+# endif
+# if __WORDSIZE == 64 \
   || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
-  || __TIMESIZE == 32
+	|| (__TIMESIZE == 32 && !defined __USE_TIME_BITS64)
   __syscall_slong_t tv_nsec;	/* Nanoseconds.  */
-#else
-# if __BYTE_ORDER == __BIG_ENDIAN
+# else
+#  if __BYTE_ORDER == __BIG_ENDIAN
   int: 32;           /* Padding.  */
   long int tv_nsec;  /* Nanoseconds.  */
-# else
+#  else
   long int tv_nsec;  /* Nanoseconds.  */
   int: 32;           /* Padding.  */
+#  endif
 # endif
-#endif
 };
 
 #endif
diff --git a/time/bits/types/struct_timeval.h b/time/bits/types/struct_timeval.h
index 70394ce886..15be3f4d7a 100644
--- a/time/bits/types/struct_timeval.h
+++ b/time/bits/types/struct_timeval.h
@@ -7,7 +7,12 @@
    microsecond but also has a range of years.  */
 struct timeval
 {
+# ifdef __USE_TIME_BITS64
+  __time64_t tv_sec;		/* Seconds.  */
+  __suseconds64_t tv_usec;	/* Microseconds.  */
+# else
   __time_t tv_sec;		/* Seconds.  */
   __suseconds_t tv_usec;	/* Microseconds.  */
+# endif
 };
 #endif
diff --git a/time/bits/types/time_t.h b/time/bits/types/time_t.h
index ab8287c6fe..84d67f6ac3 100644
--- a/time/bits/types/time_t.h
+++ b/time/bits/types/time_t.h
@@ -4,6 +4,10 @@
 #include <bits/types.h>
 
 /* Returned by `time'.  */
+#ifdef __USE_TIME_BITS64
+typedef __time64_t time_t;
+#else
 typedef __time_t time_t;
+#endif
 
 #endif
diff --git a/time/sys/time.h b/time/sys/time.h
index 21fa9ed451..d3bf1e6588 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -66,6 +66,16 @@ struct timezone
 extern int gettimeofday (struct timeval *__restrict __tv,
 			 void *__restrict __tz) __THROW __nonnull ((1));
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (gettimeofday, (struct timeval *__restrict __tv,
+                                          void *__restrict __tz),
+                           __gettimeofday64);
+# else
+# define gettimeofday __gettimeofday64
+# endif
+#endif
+
 #ifdef __USE_MISC
 /* Set the current time of day and timezone information.
    This call is restricted to the super-user.
@@ -76,12 +86,33 @@ extern int settimeofday (const struct timeval *__tv,
 			 const struct timezone *__tz)
      __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (settimeofday, (const struct timeval *__tv,
+                                          const struct timezone *__tz),
+                           __settimeofday64);
+# else
+# define settimeofday __settimeofday64
+# endif
+#endif
+
 /* Adjust the current time of day by the amount in DELTA.
    If OLDDELTA is not NULL, it is filled in with the amount
    of time adjustment remaining to be done from the last `adjtime' call.
    This call is restricted to the super-user.  */
 extern int adjtime (const struct timeval *__delta,
 		    struct timeval *__olddelta) __THROW;
+
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (adjtime, (const struct timeval *__delta,
+                                     struct timeval *__olddelta),
+                           __adjtime64);
+# else
+# define adjtime __adjtime64
+# endif
+#endif
+
 #endif
 
 
@@ -123,6 +154,16 @@ typedef int __itimer_which_t;
 extern int getitimer (__itimer_which_t __which,
 		      struct itimerval *__value) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (getitimer, (__itimer_which_t __which,
+                                       struct itimerval *__value),
+                           __getitimer64);
+# else
+# define getitimer __getitimer64
+# endif
+#endif
+
 /* Set the timer WHICH to *NEW.  If OLD is not NULL,
    set *OLD to the old value of timer WHICH.
    Returns 0 on success, -1 on errors.  */
@@ -130,19 +171,59 @@ extern int setitimer (__itimer_which_t __which,
 		      const struct itimerval *__restrict __new,
 		      struct itimerval *__restrict __old) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (setitimer, (__itimer_which_t __which,
+                                       const struct itimerval *__restrict __new,
+                                       struct itimerval *__restrict __old),
+                           __setitimer64);
+# else
+# define setitimer __setitimer64
+# endif
+#endif
+
 /* Change the access time of FILE to TVP[0] and the modification time of
    FILE to TVP[1].  If TVP is a null pointer, use the current time instead.
    Returns 0 on success, -1 on errors.  */
 extern int utimes (const char *__file, const struct timeval __tvp[2])
      __THROW __nonnull ((1));
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (utimes, (const char *__file,
+                                    const struct timeval __tvp[2]),
+                           __utimes64);
+# else
+# define utimes __utimes64
+# endif
+#endif
+
 #ifdef __USE_MISC
 /* Same as `utimes', but does not follow symbolic links.  */
 extern int lutimes (const char *__file, const struct timeval __tvp[2])
      __THROW __nonnull ((1));
 
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (lutimes, (const char *__file,
+                                     const struct timeval __tvp[2]),
+                           __lutimes64);
+#  else
+#   define lutimes __lutimes64
+#  endif
+# endif
+
 /* Same as `utimes', but takes an open file descriptor instead of a name.  */
 extern int futimes (int __fd, const struct timeval __tvp[2]) __THROW;
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (futimes, (int __fd, const struct timeval __tvp[2]),
+                           __futimes64);
+#  else
+#   define futimes __futimes64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_GNU
@@ -151,6 +232,16 @@ extern int futimes (int __fd, const struct timeval __tvp[2]) __THROW;
    the current time instead.  Returns 0 on success, -1 on errors.  */
 extern int futimesat (int __fd, const char *__file,
 		      const struct timeval __tvp[2]) __THROW;
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (futimesat, (int __fd, const char *__file,
+                                       const struct timeval __tvp[2]),
+                           __futimesat64);
+#  else
+#   define futimesat __futimesat64
+#  endif
+# endif
 #endif
 
 
diff --git a/time/time.h b/time/time.h
index 015bc1c7f3..9a74f01b2f 100644
--- a/time/time.h
+++ b/time/time.h
@@ -74,13 +74,37 @@ extern clock_t clock (void) __THROW;
 /* Return the current time and put it in *TIMER if TIMER is not NULL.  */
 extern time_t time (time_t *__timer) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern time_t __REDIRECT_NTH (time, (time_t *__timer), __time64);
+# else
+# define time __time64
+# endif
+#endif
+
 /* Return the difference between TIME1 and TIME0.  */
 extern double difftime (time_t __time1, time_t __time0)
      __THROW __attribute__ ((__const__));
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern double __REDIRECT_NTH (difftime, (time_t __time1, time_t __time0),
+                              __difftime64);
+# else
+# define difftime __difftime64
+# endif
+#endif
+
 /* Return the `time_t' representation of TP and normalize TP.  */
 extern time_t mktime (struct tm *__tp) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern time_t __REDIRECT_NTH (mktime, (struct tm *__tp), __mktime64);
+# else
+# define mktime __mktime64
+# endif
+#endif
 
 /* Format TP into S according to FORMAT.
    Write no more than MAXSIZE characters and return the number
@@ -118,6 +142,14 @@ extern char *strptime_l (const char *__restrict __s,
    in Universal Coordinated Time (aka Greenwich Mean Time).  */
 extern struct tm *gmtime (const time_t *__timer) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern struct tm*__REDIRECT_NTH (gmtime, (const time_t *__timer), __gmtime64);
+# else
+# define gmtime __gmtime64
+# endif
+#endif
+
 /* Return the `struct tm' representation
    of *TIMER in the local timezone.  */
 extern struct tm *localtime (const time_t *__timer) __THROW;
@@ -128,6 +160,16 @@ extern struct tm *localtime (const time_t *__timer) __THROW;
 extern struct tm *gmtime_r (const time_t *__restrict __timer,
 			    struct tm *__restrict __tp) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern struct tm*__REDIRECT_NTH (gmtime_r, (const time_t *__restrict __timer,
+                                            struct tm *__restrict __tp),
+                                 __gmtime64_r);
+# else
+# define gmtime_r __gmtime64_r
+# endif
+#endif
+
 /* Return the `struct tm' representation of *TIMER in local time,
    using *TP to store the result.  */
 extern struct tm *localtime_r (const time_t *__restrict __timer,
@@ -141,6 +183,14 @@ extern char *asctime (const struct tm *__tp) __THROW;
 /* Equivalent to `asctime (localtime (timer))'.  */
 extern char *ctime (const time_t *__timer) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern char *__REDIRECT_NTH (ctime, (const time_t *__timer), __ctime64);
+# else
+# define ctime __ctime64
+# endif
+#endif
+
 #if defined __USE_POSIX || __GLIBC_USE (ISOC2X)
 /* Reentrant versions of the above functions.  */
 
@@ -152,6 +202,16 @@ extern char *asctime_r (const struct tm *__restrict __tp,
 /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'.  */
 extern char *ctime_r (const time_t *__restrict __timer,
 		      char *__restrict __buf) __THROW;
+
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern char *__REDIRECT_NTH (ctime_r, (const time_t *__restrict __timer,
+                                       char *__restrict __buf), __ctime64_r);
+# else
+# define ctime_r __ctime64_r
+# endif
+#endif
+
 #endif	/* POSIX || C2X */
 
 
@@ -189,6 +249,14 @@ extern long int timezone;
 /* Like `mktime', but for TP represents Universal Time, not local time.  */
 extern time_t timegm (struct tm *__tp) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern time_t __REDIRECT_NTH (timegm, (struct tm *__tp), __timegm64);
+# else
+# define timegm __timegm64
+# endif
+#endif
+
 /* Another name for `mktime'.  */
 extern time_t timelocal (struct tm *__tp) __THROW;
 
@@ -205,17 +273,54 @@ extern int dysize (int __year) __THROW  __attribute__ ((__const__));
 extern int nanosleep (const struct timespec *__requested_time,
 		      struct timespec *__remaining);
 
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (nanosleep, (const struct timespec *__requested_time,
+                                   struct timespec *__remaining),
+                       __nanosleep64);
+#  else
+#   define nanosleep __nanosleep64
+#  endif
+# endif
 
 /* Get resolution of clock CLOCK_ID.  */
 extern int clock_getres (clockid_t __clock_id, struct timespec *__res) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (clock_getres, (clockid_t __clock_id,
+                                          struct timespec *__res),
+                           __clock_getres64);
+# else
+# define clock_getres __clock_getres64
+# endif
+#endif
+
 /* Get current value of clock CLOCK_ID and store it in TP.  */
 extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (clock_gettime, (clockid_t __clock_id, struct
+                                           timespec *__tp), __clock_gettime64);
+# else
+# define clock_gettime __clock_gettime64
+# endif
+#endif
+
 /* Set clock CLOCK_ID to value TP.  */
 extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp)
      __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (clock_settime, (clockid_t __clock_id, const struct
+                                           timespec *__tp), __clock_settime64);
+# else
+# define clock_settime __clock_settime64
+# endif
+#endif
+
 # ifdef __USE_XOPEN2K
 /* High-resolution sleep with the specified clock.
 
@@ -225,6 +330,17 @@ extern int clock_nanosleep (clockid_t __clock_id, int __flags,
 			    const struct timespec *__req,
 			    struct timespec *__rem);
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (clock_nanosleep, (clockid_t __clock_id, int __flags,
+                                         const struct timespec *__req,
+                                         struct timespec *__rem),
+                       __clock_nanosleep_time64);
+# else
+# define clock_nanosleep __clock_nanosleep_time64
+# endif
+#endif
+
 /* Return clock ID for CPU-time clock.  */
 extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) __THROW;
 # endif
@@ -243,10 +359,31 @@ extern int timer_settime (timer_t __timerid, int __flags,
 			  const struct itimerspec *__restrict __value,
 			  struct itimerspec *__restrict __ovalue) __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (timer_settime, (timer_t __timerid, int __flags,
+     const struct itimerspec *__restrict __value,
+     struct itimerspec *__restrict __ovalue),
+                          __timer_settime64);
+# else
+# define timer_settime __timer_settime64
+# endif
+#endif
+
 /* Get current value of timer TIMERID and store it in VALUE.  */
 extern int timer_gettime (timer_t __timerid, struct itimerspec *__value)
      __THROW;
 
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (timer_gettime, (timer_t __timerid,
+                                           struct itimerspec *__value),
+                           __timer_gettime64) __nonnull ((1));
+# else
+# define timer_gettime __timer_gettime64
+# endif
+#endif
+
 /* Get expiration overrun for timer TIMERID.  */
 extern int timer_getoverrun (timer_t __timerid) __THROW;
 #endif
@@ -256,6 +393,15 @@ extern int timer_getoverrun (timer_t __timerid) __THROW;
 /* Set TS to calendar time based in time base BASE.  */
 extern int timespec_get (struct timespec *__ts, int __base)
      __THROW __nonnull ((1));
+
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (timespec_get, (struct timespec *__ts, int __base),
+                           __timespec_get64);
+#  else
+#  define timespec_get __timespec_get64
+#  endif
+# endif
 #endif
 
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
  2020-12-04 23:35 ` [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems Lukasz Majewski
@ 2020-12-04 23:36 ` Lukasz Majewski
  2020-12-05  0:04   ` Joseph Myers
  2020-12-04 23:36 ` [RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content Lukasz Majewski
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:36 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

---
 io/Versions   |  4 +++
 io/sys/stat.h | 80 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/io/Versions b/io/Versions
index 15616b68f3..ce34180e30 100644
--- a/io/Versions
+++ b/io/Versions
@@ -148,5 +148,9 @@ libc {
     __fstat64;
     __ppoll64;
     __utime64;
+    __stat64_time64;
+    __fstat64_time64;
+    __lstat64_time64;
+    __fstatat64_time64;
   }
 }
diff --git a/io/sys/stat.h b/io/sys/stat.h
index b3f2f0da99..b89b7b1b7d 100644
--- a/io/sys/stat.h
+++ b/io/sys/stat.h
@@ -210,20 +210,45 @@ extern int stat (const char *__restrict __file,
 extern int fstat (int __fd, struct stat *__buf) __THROW __nonnull ((2));
 #else
 # ifdef __REDIRECT_NTH
+#  ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
+                                    struct stat *__restrict __buf),
+                           __stat64_time64) __nonnull ((1, 2));
+extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf),
+                           __fstat64_time64) __nonnull ((2));
+#  else
 extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
 				  struct stat *__restrict __buf), stat64)
      __nonnull ((1, 2));
 extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf), fstat64)
      __nonnull ((2));
+#  endif
 # else
-#  define stat stat64
-#  define fstat fstat64
+#  ifdef __USE_TIME_BITS64
+#   define stat __stat64_time64
+#   define fstat __fstat64_time64
+#  else
+#   define stat stat64
+#   define fstat fstat64
+#  endif
 # endif
 #endif
 #ifdef __USE_LARGEFILE64
 extern int stat64 (const char *__restrict __file,
 		   struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2));
 extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2));
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (stat64, (const char *__restrict __file,
+                                    struct stat64 *__restrict __buf),
+                           __stat64_time64) __nonnull ((1, 2));
+extern int __REDIRECT_NTH (fstat64, (int __fd, struct stat64 *__buf),
+                           __fstat64_time64) __nonnull ((2));
+#  else
+#   define stat64 __stat64_time64
+#   define fstat64 __fstat64_time64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_ATFILE
@@ -236,19 +261,39 @@ extern int fstatat (int __fd, const char *__restrict __file,
      __THROW __nonnull ((2, 3));
 # else
 #  ifdef __REDIRECT_NTH
+#   ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file,
+                                     struct stat *__restrict __buf, int __flag),
+                           __fstatat64_time64) __nonnull ((2, 3));
+#   else
 extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__restrict __file,
 				     struct stat *__restrict __buf,
 				     int __flag),
 			   fstatat64) __nonnull ((2, 3));
+#   endif /* __USE_TIME_BITS64 */
 #  else
-#   define fstatat fstatat64
+#   ifdef __USE_TIME_BITS64
+#    define fstatat __fstatat64_time64
+#   else
+#    define fstatat fstatat64
+#   endif
 #  endif
-# endif
+# endif /* __USE_FILE_OFFSET64 */
 
 # ifdef __USE_LARGEFILE64
 extern int fstatat64 (int __fd, const char *__restrict __file,
 		      struct stat64 *__restrict __buf, int __flag)
      __THROW __nonnull ((2, 3));
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (fstatat64,
+                           (int __fd, const char *__restrict __file,
+                            struct stat64 *__restrict __buf, int __flag),
+                           __fstatat64_time64) __nonnull ((2, 3));
+#   else
+#    define fstatat64 __fstatat64_time64
+#   endif
+#  endif /* __USE_TIME_BITS64 */
 # endif
 #endif
 
@@ -260,19 +305,38 @@ extern int lstat (const char *__restrict __file,
 		  struct stat *__restrict __buf) __THROW __nonnull ((1, 2));
 # else
 #  ifdef __REDIRECT_NTH
+#   ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTH (lstat, (const char *__restrict __file,
+                                   struct stat *__restrict __buf),
+                           __lstat64_time64) __nonnull ((1, 2));
+#   else
 extern int __REDIRECT_NTH (lstat,
 			   (const char *__restrict __file,
 			    struct stat *__restrict __buf), lstat64)
      __nonnull ((1, 2));
+#   endif /* __USE_TIME_BITS64 */
 #  else
-#   define lstat lstat64
-#  endif
-# endif
+#   ifdef __USE_TIME_BITS64
+#    define lstat __lstat64_time64
+#   else
+#    define lstat lstat64
+#   endif
+#  endif /* __REDIRECT_NTH */
+# endif /* __USE_FILE_OFFSET64 */
 # ifdef __USE_LARGEFILE64
 extern int lstat64 (const char *__restrict __file,
 		    struct stat64 *__restrict __buf)
      __THROW __nonnull ((1, 2));
-# endif
+#  ifdef __USE_TIME_BITS64
+#   if defined(__REDIRECT_NTH)
+extern int __REDIRECT_NTH (lstat64, (const char *__restrict __file,
+                                     struct stat64 *__restrict __buf),
+                           __lstat64_time64) __nonnull ((1, 2));
+#   else
+#    define lstat64 __lstat64_time64
+#   endif
+#  endif /* __USE_TIME_BITS64 */
+# endif /* __USE_LARGEFILE64 */
 #endif
 
 /* Set file access permissions for FILE to MODE.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
  2020-12-04 23:35 ` [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems Lukasz Majewski
  2020-12-04 23:36 ` [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems Lukasz Majewski
@ 2020-12-04 23:36 ` Lukasz Majewski
  2020-12-29 10:30   ` Lukasz Majewski
  2020-12-04 23:36 ` [RFC 4/6] y2038: Enhance struct msqid_ds to support 64 bit time Lukasz Majewski
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:36 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

This patch exports fields of y2038 safe members of struct stat when
-D_TIME_BITS=64 is passed as compilation flag.

Such approach will allow avoiding many copies of the same structure
for several other architectures.

It was also necessary to redefine some parts of this structure for
the glibc internal struct __stat64_t64 as the struct __timespec64
is not exported and only used locally in the glibc.

Exported, port specific (with __WORDSIZE=32 && __TIMESIZE!=64),
struct stat has been modified to support 64 bit time as well.
---
 sysdeps/unix/sysv/linux/Makefile              |  3 +-
 sysdeps/unix/sysv/linux/bits/struct_stat.h    | 17 ++++-
 .../linux/bits/struct_stat_time64_helper.h    | 70 +++++++++++++++++++
 .../unix/sysv/linux/m68k/bits/struct_stat.h   | 16 +++++
 .../sysv/linux/microblaze/bits/struct_stat.h  | 16 +++++
 .../unix/sysv/linux/mips/bits/struct_stat.h   | 16 +++++
 .../sysv/linux/powerpc/bits/struct_stat.h     | 48 ++++++++-----
 sysdeps/unix/sysv/linux/struct_stat_time64.h  | 60 +++-------------
 .../unix/sysv/linux/x86/bits/struct_stat.h    | 16 +++++
 9 files changed, 194 insertions(+), 68 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 09604e128b..2d5cf9bf09 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -97,7 +97,8 @@ sysdep_headers += sys/mount.h sys/acct.h \
 		  bits/types/struct_msqid_ds.h \
 		  bits/types/struct_shmid_ds.h \
 		  bits/ipc-perm.h \
-		  bits/struct_stat.h
+		  bits/struct_stat.h \
+		  bits/struct_stat_time64_helper.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h b/sysdeps/unix/sysv/linux/bits/struct_stat.h
index 344bffece6..6dd7aeffcf 100644
--- a/sysdeps/unix/sysv/linux/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/bits/struct_stat.h
@@ -26,6 +26,13 @@
 #include <bits/endian.h>
 #include <bits/wordsize.h>
 
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat
+  {
+    __STAT64_T64_CONTENT
+  };
+#else
 struct stat
   {
     __dev_t st_dev;			/* Device.  */
@@ -81,8 +88,16 @@ struct stat
     __ino64_t st_ino;			/* File serial number.	*/
 #endif
   };
+#endif /* __USE_TIME_BITS64  */
 
 #ifdef __USE_LARGEFILE64
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat64
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat64
   {
     __dev_t st_dev;			/* Device.  */
@@ -119,6 +134,7 @@ struct stat64
 # endif
     __ino64_t st_ino;			/* File serial number.		*/
   };
+# endif /* __USE_TIME_BITS64  */
 #endif
 
 /* Tell code we have these members.  */
@@ -127,5 +143,4 @@ struct stat64
 /* Nanosecond resolution time values are supported.  */
 #define _STATBUF_ST_NSEC
 
-
 #endif /* _BITS_STRUCT_STAT_H  */
diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
new file mode 100644
index 0000000000..3ca6258bd5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
@@ -0,0 +1,70 @@
+/* Definition for helper to define struct stat with 64 bit time.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_STRUCT_STAT_TIME64_HELPER_H
+#define _BITS_STRUCT_STAT_TIME64_HELPER_H	1
+
+#include <bits/endian.h>
+
+/* The definition should be equal to the 'struct __timespec64' internal
+   layout.  */
+#if BYTE_ORDER == BIG_ENDIAN
+# define __fieldts64(name)					\
+     __time64_t name; __int32_t :32; __int32_t name ## nsec
+#else
+# define __fieldts64(name)					\
+     __time64_t name; __int32_t name ## nsec; __int32_t :32
+#endif
+
+# ifdef __USE_XOPEN2K8
+# define st_atime st_atim.tv_sec
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+#  define __STAT64_TIME64_CONTENT  \
+    struct timespec st_atim; \
+    struct timespec st_mtim; \
+    struct timespec st_ctim;
+# else
+#  define __STAT64_TIME64_CONTENT  \
+	__fieldts64 (st_atime); \
+	__fieldts64 (st_mtime); \
+	__fieldts64 (st_ctime);
+# endif /* __USE_XOPEN2K8  */
+
+/* Content of internal __stat64_t64 struct.  */
+#define __STAT64_T64_CONTENT                                                   \
+    __dev_t st_dev;			/* Device.  */                         \
+    __ino64_t st_ino;			/* file serial number.	*/             \
+    __mode_t st_mode;			/* File mode.  */                      \
+    __nlink_t st_nlink;			/* Link count.  */             \
+    __uid_t st_uid;			/* User ID of the file's owner.  */    \
+    __gid_t st_gid;			/* Group ID of the file's group.*/     \
+    __dev_t st_rdev;			/* Device number, if device.  */       \
+    __off64_t st_size;			/* Size of file, in bytes.  */         \
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */     \
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */\
+    __STAT64_TIME64_CONTENT
+
+# undef __fieldts64
+#endif /* _BITS_STRUCT_STAT_TIME64_HELPER_H  */
diff --git a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
index bf457a0db7..5bf9e110fb 100644
--- a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
@@ -23,6 +23,13 @@
 #ifndef _BITS_STRUCT_STAT_H
 #define _BITS_STRUCT_STAT_H	1
 
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat
+  {
+    __STAT64_T64_CONTENT
+  };
+#else
 struct stat
   {
     __dev_t st_dev;			/* Device.  */
@@ -78,8 +85,16 @@ struct stat
     __ino64_t st_ino;			/* File serial number.	*/
 #endif
   };
+#endif /* __USE_TIME_BITS64 */
 
 #ifdef __USE_LARGEFILE64
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat64
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat64
   {
     __dev_t st_dev;			/* Device.  */
@@ -116,6 +131,7 @@ struct stat64
 # endif
     __ino64_t st_ino;			/* File serial number.		*/
   };
+# endif /* __USE_TIME_BITS64 */
 #endif
 
 /* Tell code we have these members.  */
diff --git a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
index db81543b23..3fac74039a 100644
--- a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
@@ -63,6 +63,13 @@ struct stat
         unsigned int            __glibc_reserved5;
 };
 #else /* __USE_FILE_OFFSET64 */
+# ifdef __USE_TIME_BITS64
+#  include <bits/struct_stat_time64_helper.h>
+struct stat
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 /* MS: If __USE_FILE_OFFSET64 is setup then struct stat should match stat64
  * structure. Glibc has no type __dev64_t that's why I had to use standard
  * type for st_dev and st_rdev. Several architectures uses pads after st_dev
@@ -106,9 +113,17 @@ struct stat
         unsigned int            __glibc_reserved4;
         unsigned int            __glibc_reserved5;
 };
+# endif /* __USE_TIME_BITS64 */
 #endif /* __USE_FILE_OFFSET64 */
 
 #ifdef __USE_LARGEFILE64
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat64
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat64
 {
         unsigned long long      st_dev;     /* Device.  */
@@ -147,6 +162,7 @@ struct stat64
         unsigned int            __glibc_reserved4;
         unsigned int            __glibc_reserved5;
 };
+# endif /* __USE_TIME_BITS64 */
 #endif
 
 /* Tell code we have these members.  */
diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
index 5abd71fc23..0b88f7cba5 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
@@ -119,6 +119,13 @@ struct stat64
   };
 #endif
 #else
+# ifdef __USE_TIME_BITS64
+#  include <bits/struct_stat_time64_helper.h>
+struct stat
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat
   {
     __dev_t st_dev;
@@ -171,8 +178,16 @@ struct stat
 #endif
     int st_pad5[14];
   };
+# endif /* __USE_TIME_BITS64 */
 
 #ifdef __USE_LARGEFILE64
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat64
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat64
   {
     __dev_t st_dev;
@@ -208,6 +223,7 @@ struct stat64
     __blkcnt64_t st_blocks;
     int st_pad4[14];
 };
+# endif /* __USE_TIME_BITS64 */
 #endif
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
index cb41adc7c0..09228e046e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
@@ -26,35 +26,41 @@
 #include <bits/wordsize.h>
 
 #if __WORDSIZE == 32
-
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat
   {
     __dev_t st_dev;			/* Device.  */
-# ifndef __USE_FILE_OFFSET64
+#  ifndef __USE_FILE_OFFSET64
     unsigned short int __pad1;
     __ino_t st_ino;			/* File serial number.	*/
-# else
+#  else
     __ino64_t st_ino;			/* File serial number.	*/
-# endif
+#  endif
     __mode_t st_mode;			/* File mode.  */
     __nlink_t st_nlink;			/* Link count.  */
     __uid_t st_uid;			/* User ID of the file's owner.	*/
     __gid_t st_gid;			/* Group ID of the file's group.*/
     __dev_t st_rdev;			/* Device number, if device.  */
     unsigned short int __pad2;
-# ifndef __USE_FILE_OFFSET64
+#  ifndef __USE_FILE_OFFSET64
     __off_t st_size;			/* Size of file, in bytes.  */
-# else
+#  else
     __off64_t st_size;			/* Size of file, in bytes.  */
-# endif
+#  endif
     __blksize_t st_blksize;		/* Optimal block size for I/O.  */
 
-# ifndef __USE_FILE_OFFSET64
+#  ifndef __USE_FILE_OFFSET64
     __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
-# else
+#  else
     __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
-# endif
-# ifdef __USE_XOPEN2K8
+#  endif
+#  ifdef __USE_XOPEN2K8
     /* Nanosecond resolution timestamps are stored in a format
        equivalent to 'struct timespec'.  This is the type used
        whenever possible but the Unix namespace rules do not allow the
@@ -64,23 +70,30 @@ struct stat
     struct timespec st_atim;		/* Time of last access.  */
     struct timespec st_mtim;		/* Time of last modification.  */
     struct timespec st_ctim;		/* Time of last status change.  */
-#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
-#  define st_mtime st_mtim.tv_sec
-#  define st_ctime st_ctim.tv_sec
-# else
+#   define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+#   define st_mtime st_mtim.tv_sec
+#   define st_ctime st_ctim.tv_sec
+#  else
     __time_t st_atime;			/* Time of last access.  */
     unsigned long int st_atimensec;	/* Nscecs of last access.  */
     __time_t st_mtime;			/* Time of last modification.  */
     unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
     __time_t st_ctime;			/* Time of last status change.  */
     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
-# endif
+#  endif
     unsigned long int __glibc_reserved4;
     unsigned long int __glibc_reserved5;
   };
-
+# endif /* __USE_TIME_BITS64 */
 
 # ifdef __USE_LARGEFILE64
+#  ifdef __USE_TIME_BITS64
+#  include <bits/struct_stat_time64_helper.h>
+struct stat64
+  {
+    __STAT64_T64_CONTENT
+  };
+#  else
 struct stat64
   {
     __dev_t st_dev;			/* Device.  */
@@ -213,6 +226,7 @@ struct stat64
     unsigned long int __glibc_reserved5;
     unsigned long int __glibc_reserved6;
   };
+#  endif /* __USE_TIME_BITS64 */
 # endif /* __USE_LARGEFILE64 */
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/struct_stat_time64.h b/sysdeps/unix/sysv/linux/struct_stat_time64.h
index b85385b6f3..5a4949000e 100644
--- a/sysdeps/unix/sysv/linux/struct_stat_time64.h
+++ b/sysdeps/unix/sysv/linux/struct_stat_time64.h
@@ -23,63 +23,25 @@
 # define __stat64_t64 stat64
 #else
 # ifdef __USE_LARGEFILE64
-#  include <endian.h>
-
-/* The definition should be equal to the 'struct __timespec64' internal
-   layout.  */
-#  if BYTE_ORDER == BIG_ENDIAN
-#   define __fieldts64(name) 					\
-     __time64_t name; __int32_t :32; __int32_t name ## nsec
-#  else
-#   define __fieldts64(name)					\
-     __time64_t name; __int32_t name ## nsec; __int32_t :32
-#  endif
-
-/* Workaround for the definition from struct_stat.h  */
-#  undef st_atime
-#  undef st_mtime
-#  undef st_ctime
-
+#  include <struct___timespec64.h>
+#  include <bits/struct_stat_time64_helper.h>
+#  ifdef __USE_XOPEN2K8
+#   undef __STAT64_TIME64_CONTENT
+/* Use glibc internal types for time related members */
+#   define __STAT64_TIME64_CONTENT  \
+      struct __timespec64 st_atim; \
+      struct __timespec64 st_mtim; \
+      struct __timespec64 st_ctim;
+#  endif /* __USE_XOPEN2K8 */
 struct __stat64_t64
   {
-    __dev_t st_dev;			/* Device.  */
-    __ino64_t st_ino;			/* file serial number.	*/
-    __mode_t st_mode;			/* File mode.  */
-    __nlink_t st_nlink;			/* Link count.  */
-    __uid_t st_uid;			/* User ID of the file's owner.	*/
-    __gid_t st_gid;			/* Group ID of the file's group.*/
-    __dev_t st_rdev;			/* Device number, if device.  */
-    __off64_t st_size;			/* Size of file, in bytes.  */
-    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
-    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
-#   ifdef __USE_XOPEN2K8
-    /* Nanosecond resolution timestamps are stored in a format
-       equivalent to 'struct timespec'.  This is the type used
-       whenever possible but the Unix namespace rules do not allow the
-       identifier 'timespec' to appear in the <sys/stat.h> header.
-       Therefore we have to handle the use of this header in strictly
-       standard-compliant sources special.  */
-    struct __timespec64 st_atim;	/* Time of last access.  */
-    struct __timespec64 st_mtim;	/* Time of last modification.  */
-    struct __timespec64 st_ctim;	/* Time of last status change.  */
-#    define st_atime st_atim.tv_sec	/* Backward compatibility.  */
-#    define st_mtime st_mtim.tv_sec
-#    define st_ctime st_ctim.tv_sec
-#   else
-    __fieldts64 (st_atime);
-    __fieldts64 (st_mtime);
-    __fieldts64 (st_ctime);
-#   endif /* __USE_XOPEN2K8  */
+    __STAT64_T64_CONTENT
   };
 
 #   define _STATBUF_ST_BLKSIZE
 #   define _STATBUF_ST_RDEV
 #   define _STATBUF_ST_NSEC
 
-#   undef __fieldts64
-
 #  endif /* __USE_LARGEFILE64  */
-
 # endif /* __TIMESIZE == 64  */
-
 #endif /* _BITS_STRUCT_STAT_TIME64_H  */
diff --git a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
index dae7aa46b3..e7e87c62b4 100644
--- a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
@@ -23,6 +23,13 @@
 #ifndef _BITS_STRUCT_STAT_H
 #define _BITS_STRUCT_STAT_H	1
 
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat
+  {
+    __STAT64_T64_CONTENT
+  };
+#else
 struct stat
   {
     __dev_t st_dev;		/* Device.  */
@@ -93,9 +100,17 @@ struct stat
 # endif
 #endif
   };
+#endif /* __USE_TIME_BITS64 */
 
 #ifdef __USE_LARGEFILE64
 /* Note stat64 has the same shape as stat for x86-64.  */
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+struct stat64
+  {
+    __STAT64_T64_CONTENT
+  };
+# else
 struct stat64
   {
     __dev_t st_dev;		/* Device.  */
@@ -146,6 +161,7 @@ struct stat64
     __ino64_t st_ino;			/* File serial number.		*/
 # endif
   };
+# endif /* __USE_TIME_BITS64  */
 #endif
 
 /* Tell code we have these members.  */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC 4/6] y2038: Enhance struct msqid_ds to support 64 bit time
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
                   ` (2 preceding siblings ...)
  2020-12-04 23:36 ` [RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content Lukasz Majewski
@ 2020-12-04 23:36 ` Lukasz Majewski
  2020-12-29 10:34   ` Lukasz Majewski
  2020-12-04 23:36 ` [RFC 5/6] msqid: Provide internal copy of struct __msqid64_ds Lukasz Majewski
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:36 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

---
 sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h |  8 ++++++++
 .../sysv/linux/hppa/bits/types/struct_msqid_ds.h     |  8 ++++++++
 .../sysv/linux/mips/bits/types/struct_msqid_ds.h     | 12 ++++++++++--
 .../sysv/linux/powerpc/bits/types/struct_msqid_ds.h  |  8 ++++++++
 .../sysv/linux/sparc/bits/types/struct_msqid_ds.h    |  8 ++++++++
 5 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
index 43b38175ad..6d8194991f 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
@@ -20,18 +20,26 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
+#include <bits/types/time_t.h>
+
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
 #if __TIMESIZE == 32
+# if __USE_TIME_BITS64
+  __time64_t msg_stime;	/* time of last msgsnd command */
+  __time64_t msg_rtime;	/* time of last msgsnd command */
+  __time64_t msg_ctime;	/* time of last change */
+# else
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __msg_stime_high;
   __time_t msg_rtime;		/* time of last msgsnd command */
   unsigned long int __msg_rtime_high;
   __time_t msg_ctime;		/* time of last change */
   unsigned long int __msg_ctime_high;
+# endif
 #else
   __time_t msg_stime;		/* time of last msgsnd command */
   __time_t msg_rtime;		/* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
index 16eac46941..08c5323f03 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
@@ -20,18 +20,26 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
+#include <bits/types/time_t.h>
+
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
 #if __TIMESIZE == 32
+# if __USE_TIME_BITS64
+  __time64_t msg_stime;	/* time of last msgsnd command */
+  __time64_t msg_rtime;	/* time of last msgsnd command */
+  __time64_t msg_ctime;	/* time of last change */
+# else
   unsigned long int __msg_stime_high;
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __msg_rtime_high;
   __time_t msg_rtime;		/* time of last msgsnd command */
   unsigned long int __msg_ctime_high;
   __time_t msg_ctime;		/* time of last change */
+# endif
 #else
   __time_t msg_stime;		/* time of last msgsnd command */
   __time_t msg_rtime;		/* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
index 513e01a171..ac077bfca8 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
@@ -20,26 +20,34 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
+#include <bits/types/time_t.h>
+
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
 #if __TIMESIZE == 32
-# ifdef __MIPSEL__
+# if __USE_TIME_BITS64
+  __time64_t msg_stime;	/* time of last msgsnd command */
+  __time64_t msg_rtime;	/* time of last msgsnd command */
+  __time64_t msg_ctime;	/* time of last change */
+# else
+#  ifdef __MIPSEL__
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __msg_stime_high;
   __time_t msg_rtime;		/* time of last msgsnd command */
   unsigned long int __msg_rtime_high;
   __time_t msg_ctime;		/* time of last change */
   unsigned long int __msg_ctime_high;
-# else
+#  else
   unsigned long int __msg_stime_high;
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __msg_rtime_high;
   __time_t msg_rtime;		/* time of last msgsnd command */
   unsigned long int __msg_ctime_high;
   __time_t msg_ctime;		/* time of last change */
+#  endif
 # endif
 #else
   __time_t msg_stime;		/* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
index 35cc51f733..bf450c9605 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
@@ -20,18 +20,26 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
+#include <bits/types/time_t.h>
+
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
 #if __TIMESIZE == 32
+# if __USE_TIME_BITS64
+  __time64_t msg_stime;	/* time of last msgsnd command */
+  __time64_t msg_rtime;	/* time of last msgsnd command */
+  __time64_t msg_ctime;	/* time of last change */
+# else
   unsigned long int __msg_stime_high;
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __msg_rtime_high;
   __time_t msg_rtime;		/* time of last msgsnd command */
   unsigned long int __msg_ctime_high;
   __time_t msg_ctime;		/* time of last change */
+# endif
 #else
   __time_t msg_stime;		/* time of last msgsnd command */
   __time_t msg_rtime;		/* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
index 502c23d91e..a9e309dafc 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
@@ -20,18 +20,26 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
+#include <bits/types/time_t.h>
+
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
 #if __TIMESIZE == 32
+# if __USE_TIME_BITS64
+  __time64_t msg_stime;	/* time of last msgsnd command */
+  __time64_t msg_rtime;	/* time of last msgsnd command */
+  __time64_t msg_ctime;	/* time of last change */
+# else
   unsigned long int __msg_stime_high;
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __msg_rtime_high;
   __time_t msg_rtime;		/* time of last msgsnd command */
   unsigned long int __msg_ctime_high;
   __time_t msg_ctime;		/* time of last change */
+# endif
 #else
   __time_t msg_stime;		/* time of last msgsnd command */
   __time_t msg_rtime;		/* time of last msgsnd command */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC 5/6] msqid: Provide internal copy of struct __msqid64_ds
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
                   ` (3 preceding siblings ...)
  2020-12-04 23:36 ` [RFC 4/6] y2038: Enhance struct msqid_ds to support 64 bit time Lukasz Majewski
@ 2020-12-04 23:36 ` Lukasz Majewski
  2020-12-29 10:54   ` Lukasz Majewski
  2020-12-04 23:36 ` [RFC 6/6] msg: provide glibc local copy of struct msqid_ds Lukasz Majewski
  2020-12-05  0:01 ` [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Joseph Myers
  6 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:36 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

After the commit SHA1: 3283f711132eaadc4f04bd8c1d84c910c29ba
"sysv: linux: Add 64-bit time_t variant for msgctl"

The glibc internal, 64 bit supporting version of struct __msqid64_ds has
been exported.

This approach has issue when one would like to add Y2038 support to glibc.
The problem is that both struct msqid_ds and __msqid64_ds rely on exported
implementation of the msg.h header (./sysvipc/sys/msg.h) which
unconditionally includes ./sysdeps/unix/sysv/linux/bits/msq.h which in
turn includes ./sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h

As a result the externally exported struct msqid_ds.h is used internally
by glibc. Problem starts when one wants to extend this struct with 64 bit
time support:

| In file included from ../sysdeps/unix/sysv/linux/bits/msq.h:28,
|                  from ../sysvipc/sys/msg.h:30,
|                  from ../sysdeps/unix/sysv/linux/include/sys/msg.h:2,
|                  from ../include/sys/msg.h:1,
|                  from ../sysdeps/unix/sysv/linux/msgctl.c:19:
| ../sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h:31:6: error:
            "__USE_TIME_BITS64" is not defined, evaluates to 0 [-Werror=undef]
|  # if __USE_TIME_BITS64
|       ^~~~~~~~~~~~~~~~~


To fix this issue - the internal,for glibc, copy of struct __msqid64_ds
has been re-introduced. This will allow clear separation between exported
and internal glibc types.

Moreover, the __TIMESIZE based alias shall be internal to glibc.

Build tests:
./src/scripts/build-many-glibcs.py glibcs
---
 include/bits/types/struct_msqid64_ds.h        | 36 +++++++++++++++++++
 .../sysv/linux/bits/types/struct_msqid64_ds.h |  4 ---
 2 files changed, 36 insertions(+), 4 deletions(-)
 create mode 100644 include/bits/types/struct_msqid64_ds.h

diff --git a/include/bits/types/struct_msqid64_ds.h b/include/bits/types/struct_msqid64_ds.h
new file mode 100644
index 0000000000..8c39a2a872
--- /dev/null
+++ b/include/bits/types/struct_msqid64_ds.h
@@ -0,0 +1,36 @@
+/* Internal for glibc implementation of the SysV message struct msqid64_ds.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+
+#if __TIMESIZE == 64
+# define __msqid64_ds msqid_ds
+#else
+struct __msqid64_ds
+{
+  struct ipc_perm msg_perm;	/* structure describing operation permission */
+  __time64_t msg_stime;		/* time of last msgsnd command */
+  __time64_t msg_rtime;		/* time of last msgsnd command */
+  __time64_t msg_ctime;		/* time of last change */
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum;		/* number of messages currently on queue */
+  msglen_t msg_qbytes;		/* max number of bytes allowed on queue */
+  __pid_t msg_lspid;		/* pid of last msgsnd() */
+  __pid_t msg_lrpid;		/* pid of last msgrcv() */
+};
+#endif
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
index 3536c8ea62..07cc1036ab 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
@@ -20,9 +20,6 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
-#if __TIMESIZE == 64
-# define __msqid64_ds msqid_ds
-#else
 struct __msqid64_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
@@ -35,4 +32,3 @@ struct __msqid64_ds
   __pid_t msg_lspid;		/* pid of last msgsnd() */
   __pid_t msg_lrpid;		/* pid of last msgrcv() */
 };
-#endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC 6/6] msg: provide glibc local copy of struct msqid_ds
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
                   ` (4 preceding siblings ...)
  2020-12-04 23:36 ` [RFC 5/6] msqid: Provide internal copy of struct __msqid64_ds Lukasz Majewski
@ 2020-12-04 23:36 ` Lukasz Majewski
  2020-12-05  0:01 ` [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Joseph Myers
  6 siblings, 0 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-04 23:36 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

The rationale for this change is to provide y2038 support for
syscalls which use struct msqid_ds as __USE_TIME64_BITS is only available
in exported headers.

After this commit there is no need to unconditionally
#include <sysvipc/sys/msg.h> header, which prevents from using the
exported struct msqid_ds. The aforementioned header is only included when
_ISOMAC is defined - e.g. when the testsuite is built and executed.

For example the ./sysdeps/unix/sysv/linux/msgctl.c includes <sys/msg.h>:
			(include/sys/msg.h) which has
			#include_next <sys/msg.h>
				    |
				   \|/
			./sysdeps/unix/sysv/linux/include/sys/msg.h
				    |
				   \|/
	(./sysvipc/sys/msg.h) which unconditionally includes
        ./sysdeps/unix/sysv/linux/bits/msq.h
				    |
				   \|/
        ./sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h

As a result the externally exported struct msqid_ds.h is used internally
by glibc.

To fix this issue - the internal for glibc copy of struct msqid_ds
has been re-introduced. This will allow clear separation between exported
and internal glibc types.

Build tests:
./src/scripts/build-many-glibcs.py glibcs
---
 sysdeps/unix/sysv/linux/include/sys/msg.h | 66 +++++++++++++++++++++--
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/include/sys/msg.h b/sysdeps/unix/sysv/linux/include/sys/msg.h
index 522903f818..1057c2e278 100644
--- a/sysdeps/unix/sysv/linux/include/sys/msg.h
+++ b/sysdeps/unix/sysv/linux/include/sys/msg.h
@@ -1,7 +1,63 @@
 #ifndef _SYS_MSG_H
-#include <sysvipc/sys/msg.h>
-
 #ifndef _ISOMAC
+# include <time.h>
+# include <sys/ipc.h>
+
+/* Types used in the MSQID_DS structure definition.  */
+typedef __syscall_ulong_t msgqnum_t;
+typedef __syscall_ulong_t msglen_t;
+
+struct msqid_ds
+{
+  struct ipc_perm msg_perm;	/* structure describing operation permission */
+# if __TIMESIZE == 32
+  __time_t msg_stime;		/* time of last msgsnd command */
+  unsigned long int __msg_stime_high;
+  __time_t msg_rtime;		/* time of last msgsnd command */
+  unsigned long int __msg_rtime_high;
+  __time_t msg_ctime;		/* time of last change */
+  unsigned long int __msg_ctime_high;
+# else
+  __time_t msg_stime;		/* time of last msgsnd command */
+  __time_t msg_rtime;		/* time of last msgsnd command */
+  __time_t msg_ctime;		/* time of last change */
+# endif
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum;		/* number of messages currently on queue */
+  msglen_t msg_qbytes;		/* max number of bytes allowed on queue */
+  __pid_t msg_lspid;		/* pid of last msgsnd() */
+  __pid_t msg_lrpid;		/* pid of last msgrcv() */
+  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __glibc_reserved5;
+};
+
+# ifdef __USE_MISC
+#  define msg_cbytes	__msg_cbytes
+
+/* ipcs ctl commands */
+#  define MSG_STAT 11
+#  define MSG_INFO 12
+#  define MSG_STAT_ANY 13
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+  {
+    int msgpool;
+    int msgmap;
+    int msgmax;
+    int msgmnb;
+    int msgmni;
+    int msgssz;
+    int msgtql;
+    unsigned short int msgseg;
+  };
+# endif /* __USE_MISC */
+
+# ifndef __ssize_t_defined
+typedef __ssize_t ssize_t;
+#  define __ssize_t_defined
+# endif
+
 extern ssize_t __libc_msgrcv (int msqid, void *msgp, size_t msgsz,
 			      long int msgtyp, int msgflg);
 extern int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz,
@@ -15,7 +71,9 @@ extern int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz,
 extern int __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf);
 libc_hidden_proto (__msgctl64);
 # endif
-
-#endif
+#else /* _ISOMAC = 1 - e.g. testsuite */
+/* Provide exported sys/msg.h header */
+# include <sysvipc/sys/msg.h>
+#endif /* _ISOMAC */
 
 #endif
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
  2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
                   ` (5 preceding siblings ...)
  2020-12-04 23:36 ` [RFC 6/6] msg: provide glibc local copy of struct msqid_ds Lukasz Majewski
@ 2020-12-05  0:01 ` Joseph Myers
  2020-12-07 10:22   ` Lukasz Majewski
  6 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2020-12-05  0:01 UTC (permalink / raw
  To: Lukasz Majewski
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

On Sat, 5 Dec 2020, Lukasz Majewski wrote:

> This patch series is the RFC for preparing glibc to be Y2038 safe on
> ports with __WORDSIZE=32 && __TIMESIZE!=64 (e.g. 32 bit ARM).

What exactly does "preparing" mean here?

I'd expect support for _TIME_BITS to go along with public symbol versions 
for all the new symbols that functions get redirected to, because 
otherwise people building with _TIME_BITS=64 will get either link failures 
or broken binaries depending on GLIBC_PRIVATE symbols.  But as far as I 
can see, this patch series only adds GLIBC_PRIVATE symbols, not any public 
symbols or corresponding abilist updates.

I'd also expect support for _TIME_BITS to go along with tests covering all 
the new interfaces (that is, for every time-affected interface, there 
should be a test that it works properly with _TIME_BITS=64, typically a 
test that defines _TIME_BITS to 64 then includes an existing test for that 
interface, possibly with other tests to verify that large time values work 
properly where possible).

You don't say how this series was tested, but this may be around the point 
where build-many-glibcs.py testing is needed.  Certainly any patch in such 
a series that adds a new public symbol should be tested with 
build-many-glibcs.py to make sure that all the ABI test baseline updates 
are correct.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems
  2020-12-04 23:36 ` [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems Lukasz Majewski
@ 2020-12-05  0:04   ` Joseph Myers
  2020-12-07 10:28     ` Lukasz Majewski
  0 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2020-12-05  0:04 UTC (permalink / raw
  To: Lukasz Majewski
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

On Sat, 5 Dec 2020, Lukasz Majewski wrote:

> --- a/io/Versions
> +++ b/io/Versions
> @@ -148,5 +148,9 @@ libc {
>      __fstat64;
>      __ppoll64;
>      __utime64;
> +    __stat64_time64;
> +    __fstat64_time64;
> +    __lstat64_time64;
> +    __fstatat64_time64;

This is adding to GLIBC_PRIVATE.

> --- a/io/sys/stat.h
> +++ b/io/sys/stat.h
> @@ -210,20 +210,45 @@ extern int stat (const char *__restrict __file,
>  extern int fstat (int __fd, struct stat *__buf) __THROW __nonnull ((2));
>  #else
>  # ifdef __REDIRECT_NTH
> +#  ifdef __USE_TIME_BITS64
> +extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
> +                                    struct stat *__restrict __buf),
> +                           __stat64_time64) __nonnull ((1, 2));
> +extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf),
> +                           __fstat64_time64) __nonnull ((2));

And this is changing an installed header.

An installed header should never reference a GLIBC_PRIVATE symbol.  The 
commit that adds a redirection to a new symbol for 64-bit time_t must 
either be the same commit that adds that symbol to a *public* symbol 
version, or a subsequent commit.  The commit adding it to a public symbol 
version must be the same commit that updates all relevant ABI test 
baselines so that ABI tests pass after every commit.

The same comments apply to other patches in this series.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems
  2020-12-04 23:35 ` [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems Lukasz Majewski
@ 2020-12-05  0:12   ` Joseph Myers
  2020-12-07 13:00     ` Lukasz Majewski
  0 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2020-12-05  0:12 UTC (permalink / raw
  To: Lukasz Majewski
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

On Sat, 5 Dec 2020, Lukasz Majewski wrote:

> This change introduces new compile time, supported by glibc flag - namely
> _TIME_BITS, which then is responsible for exporting __USE_TIME_BITS64 only

As a major new user-visible feature, this needs to be mentioned in NEWS.

> +/* We need to know the word size in order to check the time size.  */
> +#include <bits/wordsize.h>
> +
> +#if defined _TIME_BITS
> +# if _TIME_BITS == 64
> +#  if ! defined (_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
> +#   error _TIME_BITS==64 is allowed only when _FILE_OFFSET_BITS==64
> +#  elif __WORDSIZE == 32
> +#   define __USE_TIME_BITS64	1
> +#  endif

__WORDSIZE isn't the right thing to check.  On ARC or RV32 or x32, 
_TIME_BITS == 64 should be a no-op, because time_t has always been 64-bit 
for those glibc ports.  That is, you should be checking __TIMESIZE, not 
__WORDSIZE.

> +# elif _TIME_BITS == 32
> +#  if __WORDSIZE > 32
> +#   error _TIME_BITS=32 is not compatible with __WORDSIZE > 32

Likewise, __TIMESIZE should be checked here, not __WORDSIZE.

> +@defvr Macro _TIME_BITS
> +This macro determines the bit size of @code{time_t} (and therefore the
> +bit size of all @code{time_t} derived types and the prototypes of all
> +related functions). If @code{_TIME_BITS} is undefined, the bit size of
> +time_t equals the bit size of the architecture.

Apart from "bit size of the architecture" not being well-defined, that's 
not right for ARC or RV32, 32-bit architectures with 64-bit time_t.

Note there should be two spaces after "." in Texinfo manuals.

> +If @code{_TIME_BITS} is undefined, or if @code{_TIME_BITS} is defined
> +to the value @code{32} and @code{__WORDSIZE} is defined to the value
> +@code{32}, or or if @code{_TIME_BITS} is defined to the value @code{64}
> +and @code{__WORDSIZE} is defined to the value @code{64}, nothing changes.

__WORDSIZE (and __TIMESIZE after the fix above) is not a user-visible 
interface, it's a glibc header implementation detail.  The manual (other 
than maint.texi) should not mention either such internal macro; you need 
to talk about a concept of word size / default time_t size that's 
explained purely in user-level interfaces, not glibc internal macros.

> +If @code{_TIME_BITS} is defined to the value @code{64} and if
> +@code{__WORDSIZE} is defined to the value @code{32}, then the @w{64 bit}
> +time API and implementation are used even though the architecture word
> +size is @code{32}. Also, if the kernel provides @w{64 bit} time support,
> +it is used; otherwise, the @w{32 bit} kernel time support is used (with
> +no provision to address kernel Y2038 shortcomings).

Use "32-bit" and "64-bit" (with hyphen) as adjectives.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
  2020-12-05  0:01 ` [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Joseph Myers
@ 2020-12-07 10:22   ` Lukasz Majewski
  2020-12-07 18:01     ` Joseph Myers
  0 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-07 10:22 UTC (permalink / raw
  To: Joseph Myers, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 4665 bytes --]

Hi Joseph,

> On Sat, 5 Dec 2020, Lukasz Majewski wrote:
> 
> > This patch series is the RFC for preparing glibc to be Y2038 safe on
> > ports with __WORDSIZE=32 && __TIMESIZE!=64 (e.g. 32 bit ARM).  
> 
> What exactly does "preparing" mean here?

In this particular case - I meant that all the patches in this series
are necessary to provide Y2038 support. Please also be aware that this
is only the RFC.

To be more specific - only patch 1/6 will be the "transitional" patch
in a sense that after applying it the _TIME_BITS flag would be
introduced and ready to be use by users.

Patches following it - i.e. from 2 to 6 are added to show what is
needed to tune glibc to have 64 bit time support. Those are mostly
related to earlier 'stat' rework done by Adhemerval and shall be
applied (or the problem shall be resolved in the other way) before patch
1/6 is applied.

I just wanted to wrap all the necessary patches in a single patch
series to show how much work is still necessary.

> 
> I'd expect support for _TIME_BITS to go along with public symbol
> versions for all the new symbols that functions get redirected to,
> because otherwise people building with _TIME_BITS=64 will get either
> link failures or broken binaries depending on GLIBC_PRIVATE symbols.
> But as far as I can see, this patch series only adds GLIBC_PRIVATE
> symbols, not any public symbols or corresponding abilist updates.

You are right - this was my omission. I've added those new symbols to
GLIBC_PRIVATE as it was easier for maintenance.

For the "final" version of this patch set I will add all those symbols
to GLIBC_2.3X {}.

> 
> I'd also expect support for _TIME_BITS to go along with tests
> covering all the new interfaces (that is, for every time-affected
> interface, there should be a test that it works properly with
> _TIME_BITS=64, typically a test that defines _TIME_BITS to 64 then
> includes an existing test for that interface, possibly with other
> tests to verify that large time values work properly where possible).

This is a bit problematic as was discussed earlier [1] as we don't
have the easy way to set host's (on which tests are running) time.

The time namespaces don't support CLOCK_REALTIME, and the only feasible
way to do this is with re-using (and optimizing):
test-wrapper='/opt/glibc/src/scripts/cross-test-ssh.sh

I'm also concerned how this work shall be divided - the patch which
introduces _TIME_BITS flag would be very large and difficult to review.
Would it be allowed to add tests (which would use _TIME_BITS) to glibc
tree earlier?

> 
> You don't say how this series was tested,

This patch set causes following Y2038 tests being all passed:
https://github.com/lmajewski/y2038-tests/

Those tests are run as part of meta-y2038:
https://github.com/lmajewski/meta-y2038/

Those are "simple" programs to test single syscall (e.g. clock_settime
or stat) built with _TIME_BITS=64 and _FILE_OFFSET=64 and run on QEMU
(arm32 bit vexpress-c15 board).

This is the only way to be able to set future time after time_t
overflow.

> but this may be around the
> point where build-many-glibcs.py testing is needed. 

In the thread [2] - I've suggested such approach, but this would imply
setting/changing time on the build host.

To overcome this problem we would need time namespaces, but for now
there is no plan to provide such functionality ([1]).

> Certainly any
> patch in such a series that adds a new public symbol should be tested
> with build-many-glibcs.py to make sure that all the ABI test baseline
> updates are correct.
> 

Would it be possible to test e.g. clock_settime64 if it sets correct
time after 32 bit time_t overflow? Any other syscall would require time
adjustment of host to properly test execution paths.

Would you recommend extending build-many-glibc to also download, build
qemu and run tests inside?

In the discussion [1] it was pointed out that this would be a bit
cumbersome. 

Last but not least, just the "build" testing shall be provided with
current setup as for e.g. __WORDSIZE=32 and __TIMESIZE!=64 (e.g. arm32
bit) we do use 64 bit interfaces anyway.


Links:
[1] - https://lore.kernel.org/lkml/20201114102503.GB1000@bug/T/
[2] -
http://sourceware-org.1504.n7.nabble.com/Y2038-Question-about-porting-y2038-tests-to-glibc-td652557.html

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems
  2020-12-05  0:04   ` Joseph Myers
@ 2020-12-07 10:28     ` Lukasz Majewski
  2020-12-07 18:07       ` Joseph Myers
  0 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-07 10:28 UTC (permalink / raw
  To: Joseph Myers
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 2157 bytes --]

Hi Joseph,

> On Sat, 5 Dec 2020, Lukasz Majewski wrote:
> 
> > --- a/io/Versions
> > +++ b/io/Versions
> > @@ -148,5 +148,9 @@ libc {
> >      __fstat64;
> >      __ppoll64;
> >      __utime64;
> > +    __stat64_time64;
> > +    __fstat64_time64;
> > +    __lstat64_time64;
> > +    __fstatat64_time64;  
> 
> This is adding to GLIBC_PRIVATE.

This shall be added to GLIBC_2.3X.

> 
> > --- a/io/sys/stat.h
> > +++ b/io/sys/stat.h
> > @@ -210,20 +210,45 @@ extern int stat (const char *__restrict
> > __file, extern int fstat (int __fd, struct stat *__buf) __THROW
> > __nonnull ((2)); #else
> >  # ifdef __REDIRECT_NTH
> > +#  ifdef __USE_TIME_BITS64
> > +extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
> > +                                    struct stat *__restrict __buf),
> > +                           __stat64_time64) __nonnull ((1, 2));
> > +extern int __REDIRECT_NTH (fstat, (int __fd, struct stat *__buf),
> > +                           __fstat64_time64) __nonnull ((2));  
> 
> And this is changing an installed header.
> 
> An installed header should never reference a GLIBC_PRIVATE symbol.

A side question:

Is my understanding correct that GLIBC_PRIVATE symbols are only for
cross libraries reference? For example such symbol from glibc could be
referenced in librt?

> The commit that adds a redirection to a new symbol for 64-bit time_t
> must either be the same commit that adds that symbol to a *public*
> symbol version, or a subsequent commit.  The commit adding it to a
> public symbol version must be the same commit that updates all
> relevant ABI test baselines so that ABI tests pass after every commit.
> 
> The same comments apply to other patches in this series.
> 

This commit shall be squashed with the first one - I just defer to do
this as there are still some issues with 'stat{x}'.



Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems
  2020-12-05  0:12   ` Joseph Myers
@ 2020-12-07 13:00     ` Lukasz Majewski
  0 siblings, 0 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-07 13:00 UTC (permalink / raw
  To: Joseph Myers
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 3299 bytes --]

Hi Joseph,

> On Sat, 5 Dec 2020, Lukasz Majewski wrote:
> 
> > This change introduces new compile time, supported by glibc flag -
> > namely _TIME_BITS, which then is responsible for exporting
> > __USE_TIME_BITS64 only  
> 
> As a major new user-visible feature, this needs to be mentioned in
> NEWS.

Ok.

> 
> > +/* We need to know the word size in order to check the time size.
> > */ +#include <bits/wordsize.h>
> > +
> > +#if defined _TIME_BITS
> > +# if _TIME_BITS == 64
> > +#  if ! defined (_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
> > +#   error _TIME_BITS==64 is allowed only when _FILE_OFFSET_BITS==64
> > +#  elif __WORDSIZE == 32
> > +#   define __USE_TIME_BITS64	1
> > +#  endif  
> 
> __WORDSIZE isn't the right thing to check.  On ARC or RV32 or x32, 
> _TIME_BITS == 64 should be a no-op, because time_t has always been
> 64-bit for those glibc ports.  That is, you should be checking
> __TIMESIZE, not __WORDSIZE.

Ok. Thanks for pointing this out

> 
> > +# elif _TIME_BITS == 32
> > +#  if __WORDSIZE > 32
> > +#   error _TIME_BITS=32 is not compatible with __WORDSIZE > 32  
> 
> Likewise, __TIMESIZE should be checked here, not __WORDSIZE.
> 

Ok.

> > +@defvr Macro _TIME_BITS
> > +This macro determines the bit size of @code{time_t} (and therefore
> > the +bit size of all @code{time_t} derived types and the prototypes
> > of all +related functions). If @code{_TIME_BITS} is undefined, the
> > bit size of +time_t equals the bit size of the architecture.  
> 
> Apart from "bit size of the architecture" not being well-defined,
> that's not right for ARC or RV32, 32-bit architectures with 64-bit
> time_t.
> 
> Note there should be two spaces after "." in Texinfo manuals.
> 
> > +If @code{_TIME_BITS} is undefined, or if @code{_TIME_BITS} is
> > defined +to the value @code{32} and @code{__WORDSIZE} is defined to
> > the value +@code{32}, or or if @code{_TIME_BITS} is defined to the
> > value @code{64} +and @code{__WORDSIZE} is defined to the value
> > @code{64}, nothing changes.  
> 
> __WORDSIZE (and __TIMESIZE after the fix above) is not a user-visible 
> interface, it's a glibc header implementation detail.  The manual
> (other than maint.texi) should not mention either such internal
> macro; you need to talk about a concept of word size / default time_t
> size that's explained purely in user-level interfaces, not glibc
> internal macros.
> 
> > +If @code{_TIME_BITS} is defined to the value @code{64} and if
> > +@code{__WORDSIZE} is defined to the value @code{32}, then the
> > @w{64 bit} +time API and implementation are used even though the
> > architecture word +size is @code{32}. Also, if the kernel provides
> > @w{64 bit} time support, +it is used; otherwise, the @w{32 bit}
> > kernel time support is used (with +no provision to address kernel
> > Y2038 shortcomings).  
> 
> Use "32-bit" and "64-bit" (with hyphen) as adjectives.
> 

Thanks for pointing this out - I will rewrite the manual entry.


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
  2020-12-07 10:22   ` Lukasz Majewski
@ 2020-12-07 18:01     ` Joseph Myers
  2020-12-08 10:07       ` Lukasz Majewski
  0 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2020-12-07 18:01 UTC (permalink / raw
  To: Lukasz Majewski
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

On Mon, 7 Dec 2020, Lukasz Majewski wrote:

> > I'd also expect support for _TIME_BITS to go along with tests
> > covering all the new interfaces (that is, for every time-affected
> > interface, there should be a test that it works properly with
> > _TIME_BITS=64, typically a test that defines _TIME_BITS to 64 then
> > includes an existing test for that interface, possibly with other
> > tests to verify that large time values work properly where possible).
> 
> This is a bit problematic as was discussed earlier [1] as we don't
> have the easy way to set host's (on which tests are running) time.

I'd like the _TIME_BITS=64 interfaces to be covered as well as the 
existing interfaces.  That is, test what can readily be covered with the 
existing testsuite infrastructure, but not things that require setting the 
system clock.  (You might be able to e.g. test sleeping for 2^32 seconds 
and interrupting that sleep after a second or two.)

E.g. pthread_mutex_timedlock / pthread_mutex_clocklock / mtx_timedlock are 
functions with a complicated implementation and several tests (in nptl/ 
and sysdeps/pthread/).  Whether or not there are further things to test 
specific to 64-bit time, it's definitely straightforward to add tests that 
define _TIME_BITS=64 then include one of the existing tests for one of 
those functions - so ensuring similar test coverage for both versions of 
each such function.

If any of the functions being changed aren't covered in the testsuite at 
all, but can be tested meaningfully as an unprivileged user, it would be a 
good idea to add basic tests of those functions that get run both with and 
without _TIME_BITS=64.

> Would it be allowed to add tests (which would use _TIME_BITS) to glibc
> tree earlier?

I think that's fine - certainly for tests which just define _TIME_BITS 
before including another test and will work for both 32-bit and 64-bit 
time_t.

The commit that causes installed headers to support redirecting interfaces 
when _TIME_BITS is defined to 64 should come last - there shouldn't be an 
intermediate state where a user defining _TIME_BITS=64 gets some 
interfaces redirected by installed headers and others not redirected.  
But before that final change to installed headers, there can be any number 
of preparatory commits (possibly including ones that add redirection 
support to individual headers, if the features.h patch that handles 
_TIME_BITS comes last).

I'm not sure if there is going to be any support for _TIME_BITS=64 for 
Hurd - the minimum requirement there is simply not to provide an 
inconsistent ABI (so either no header redirections, or all header 
redirections operate and go to working functions) and not to break the 
build of glibc or the testsuite.

> Would you recommend extending build-many-glibc to also download, build
> qemu and run tests inside?

My recommendation is simply to add those tests of the new interfaces that 
are reasonably straightforward within the existing testsuite and don't 
require running QEMU or changing the system clock or anything needing 
privileged access or unsuitable for running on a shared system.

Adding extra support for building and running QEMU should be considered a 
separate matter, quite possibly useful to help people test glibc patches 
more thoroughly where appropriate but not expected to be done as part of 
the Y2038 work.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems
  2020-12-07 10:28     ` Lukasz Majewski
@ 2020-12-07 18:07       ` Joseph Myers
  0 siblings, 0 replies; 21+ messages in thread
From: Joseph Myers @ 2020-12-07 18:07 UTC (permalink / raw
  To: Lukasz Majewski
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

On Mon, 7 Dec 2020, Lukasz Majewski wrote:

> Is my understanding correct that GLIBC_PRIVATE symbols are only for
> cross libraries reference? For example such symbol from glibc could be
> referenced in librt?

GLIBC_PRIVATE symbols are only for reference by libraries or programs 
installed by glibc.  So, yes, a symbol provided by libc.so for use from 
librt.so could be GLIBC_PRIVATE, if it's not intended for users to link 
their own code against and is not referenced in any installed header or 
*_nonshared.a library or crt*.o.  Sometimes such symbols may be used in 
the programs glibc installs (in usr/bin, usr/sbin, etc.; e.g. nscd), not 
just libraries, though it's less clear if that's a good idea.

GLIBC_PRIVATE symbols do not need to have any kind of a stable ABI, 
because the definition and user of the symbol always come from the same 
set of glibc sources.  However, ABI changes to such symbols can be 
dangerous on release branches, because of the situation where (a) a 
process starts up and loads libc, (b) an updated distribution package of 
glibc libraries is installed, (c) that process dlopens a glibc shared 
library it didn't load at startup, and that library (from the updated 
package) wants a GLIBC_PRIVATE symbol that's not present with the right 
ABI in the (older) libc it loaded at startup.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
  2020-12-07 18:01     ` Joseph Myers
@ 2020-12-08 10:07       ` Lukasz Majewski
  2020-12-08 15:25         ` Joseph Myers
  0 siblings, 1 reply; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-08 10:07 UTC (permalink / raw
  To: Joseph Myers, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 5525 bytes --]

Hi Joseph,

> On Mon, 7 Dec 2020, Lukasz Majewski wrote:
> 
> > > I'd also expect support for _TIME_BITS to go along with tests
> > > covering all the new interfaces (that is, for every time-affected
> > > interface, there should be a test that it works properly with
> > > _TIME_BITS=64, typically a test that defines _TIME_BITS to 64 then
> > > includes an existing test for that interface, possibly with other
> > > tests to verify that large time values work properly where
> > > possible).  
> > 
> > This is a bit problematic as was discussed earlier [1] as we don't
> > have the easy way to set host's (on which tests are running) time.  
> 
> I'd like the _TIME_BITS=64 interfaces to be covered as well as the 
> existing interfaces.  That is, test what can readily be covered with
> the existing testsuite infrastructure, but not things that require
> setting the system clock.  (You might be able to e.g. test sleeping
> for 2^32 seconds and interrupting that sleep after a second or two.)
> 
> E.g. pthread_mutex_timedlock / pthread_mutex_clocklock /
> mtx_timedlock are functions with a complicated implementation and
> several tests (in nptl/ and sysdeps/pthread/).  Whether or not there
> are further things to test specific to 64-bit time, it's definitely
> straightforward to add tests that define _TIME_BITS=64 then include
> one of the existing tests for one of those functions - so ensuring
> similar test coverage for both versions of each such function.
> 
> If any of the functions being changed aren't covered in the testsuite
> at all, but can be tested meaningfully as an unprivileged user, it
> would be a good idea to add basic tests of those functions that get
> run both with and without _TIME_BITS=64.

Ok, so if I understood you correctly - I shall devise tests, which can
be run as unprivileged user and if possible reuse existing tests with
_TIME_BITS=64 defined.

> 
> > Would it be allowed to add tests (which would use _TIME_BITS) to
> > glibc tree earlier?  
> 
> I think that's fine - certainly for tests which just define
> _TIME_BITS before including another test and will work for both
> 32-bit and 64-bit time_t.
> 
> The commit that causes installed headers to support redirecting
> interfaces when _TIME_BITS is defined to 64 should come last - there
> shouldn't be an intermediate state where a user defining
> _TIME_BITS=64 gets some interfaces redirected by installed headers
> and others not redirected. But before that final change to installed
> headers, there can be any number of preparatory commits (possibly
> including ones that add redirection support to individual headers, if
> the features.h patch that handles _TIME_BITS comes last).

Ok, I will prepare proper patch - as I do already have all the
redirections for already converted syscalls.

In that way we would avoid one bit patch, which would add _TIME_BITS
support.

> 
> I'm not sure if there is going to be any support for _TIME_BITS=64
> for Hurd

I've focused on the glibc ports, which use Linux as the kernel (mostly
ARM 32 bit). 

I do NOT have any plans to also support HURD.

> - the minimum requirement there is simply not to provide an 
> inconsistent ABI (so either no header redirections,

I would opt for the above option - no redirections for HURD.

> or all header 
> redirections operate and go to working functions) and not to break
> the build of glibc or the testsuite.

All exported headers' redirections are "protected" by:
"#ifdef __USE_TIME_BITS64"

And __USE_TIME_BITS64 will be only defined when _TIME_BITS=64 &&
_FILE_OFFSET_BITS=64 && __TIMESIZE != 64

I think that the most pragmatic approach would be for HURD to:

1. Introduce new header - ./sysdeps/hurd/include/features.h
2. In this file:

	#include_next <features.h>
	/*
	 * HURD is not (yet) supporting 64 bit time on archs with
	 * __TIMESIZE!=64 && __WORDSIZE=32
	 * For that reason we explicitly undefine the __USE_TIME_BITS64
	 */
	#undef __USE_TIME_BITS64

or even better:

	#ifdef __USE_TIME_BITS64
	# error "On i686-gnu HURD the _TIME_BITS flag is not supported!"
	#endif


In that way we would either silently disable Y2038 suport on HURD or
(preferable) prevent compilation with the error information.

> 
> > Would you recommend extending build-many-glibc to also download,
> > build qemu and run tests inside?  
> 
> My recommendation is simply to add those tests of the new interfaces
> that are reasonably straightforward within the existing testsuite and
> don't require running QEMU or changing the system clock or anything
> needing privileged access or unsuitable for running on a shared
> system.

Ok. Thanks for the clarification.

> 
> Adding extra support for building and running QEMU should be
> considered a separate matter, quite possibly useful to help people
> test glibc patches more thoroughly where appropriate but not expected
> to be done as part of the Y2038 work.
> 

I could add / port / maintain the meta-y2038 on the sourceware.org or
Yocto, so people could use Y2038 safe glibc on embedded systems. For
now I do maintain it on GitHub:
https://github.com/lmajewski/meta-y2038/blob/master/README


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
  2020-12-08 10:07       ` Lukasz Majewski
@ 2020-12-08 15:25         ` Joseph Myers
  2020-12-13 11:49           ` Lukasz Majewski
  0 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2020-12-08 15:25 UTC (permalink / raw
  To: Lukasz Majewski
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

On Tue, 8 Dec 2020, Lukasz Majewski wrote:

> 1. Introduce new header - ./sysdeps/hurd/include/features.h
> 2. In this file:
> 
> 	#include_next <features.h>

<features.h> is an *installed* header, and sysdeps/*/include/ is only for 
*non-installed* wrappers used when building glibc itself.  So this 
approach can't work.  (But you could e.g. have two different 
bits/features-time64.h headers, one in the toplevel bits/ and one under 
sysdeps, so that the appropriate one is installed, and include 
<bits/features-time64.h> from <features.h>.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports
  2020-12-08 15:25         ` Joseph Myers
@ 2020-12-13 11:49           ` Lukasz Majewski
  0 siblings, 0 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-13 11:49 UTC (permalink / raw
  To: Joseph Myers
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 928 bytes --]

Hi Joseph,

> On Tue, 8 Dec 2020, Lukasz Majewski wrote:
> 
> > 1. Introduce new header - ./sysdeps/hurd/include/features.h
> > 2. In this file:
> > 
> > 	#include_next <features.h>  
> 
> <features.h> is an *installed* header, and sysdeps/*/include/ is only
> for *non-installed* wrappers used when building glibc itself.  So
> this approach can't work.  (But you could e.g. have two different 
> bits/features-time64.h headers, one in the toplevel bits/ and one
> under sysdeps, so that the appropriate one is installed, and include 
> <bits/features-time64.h> from <features.h>.)
> 

Ok, I will do this in that way. Thanks for sharing the idea.


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content
  2020-12-04 23:36 ` [RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content Lukasz Majewski
@ 2020-12-29 10:30   ` Lukasz Majewski
  0 siblings, 0 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-29 10:30 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 18920 bytes --]

Dear Community,

> This patch exports fields of y2038 safe members of struct stat when
> -D_TIME_BITS=64 is passed as compilation flag.
> 
> Such approach will allow avoiding many copies of the same structure
> for several other architectures.
> 
> It was also necessary to redefine some parts of this structure for
> the glibc internal struct __stat64_t64 as the struct __timespec64
> is not exported and only used locally in the glibc.
> 
> Exported, port specific (with __WORDSIZE=32 && __TIMESIZE!=64),
> struct stat has been modified to support 64 bit time as well.

I would like to ask for review on this patch, as it is crucial for 64
bit stat support on ports with __WORDSIZE != 64 && _TIMESIZE==32.

It shall not bring any issues untill __USE_TIME_BITS64 is defined.

> ---
>  sysdeps/unix/sysv/linux/Makefile              |  3 +-
>  sysdeps/unix/sysv/linux/bits/struct_stat.h    | 17 ++++-
>  .../linux/bits/struct_stat_time64_helper.h    | 70
> +++++++++++++++++++ .../unix/sysv/linux/m68k/bits/struct_stat.h   |
> 16 +++++ .../sysv/linux/microblaze/bits/struct_stat.h  | 16 +++++
>  .../unix/sysv/linux/mips/bits/struct_stat.h   | 16 +++++
>  .../sysv/linux/powerpc/bits/struct_stat.h     | 48 ++++++++-----
>  sysdeps/unix/sysv/linux/struct_stat_time64.h  | 60 +++-------------
>  .../unix/sysv/linux/x86/bits/struct_stat.h    | 16 +++++
>  9 files changed, 194 insertions(+), 68 deletions(-)
>  create mode 100644
> sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index 09604e128b..2d5cf9bf09 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -97,7 +97,8 @@ sysdep_headers += sys/mount.h sys/acct.h \
>  		  bits/types/struct_msqid_ds.h \
>  		  bits/types/struct_shmid_ds.h \
>  		  bits/ipc-perm.h \
> -		  bits/struct_stat.h
> +		  bits/struct_stat.h \
> +		  bits/struct_stat_time64_helper.h
>  
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify
> tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max
> tst-ttyname \ diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/bits/struct_stat.h index
> 344bffece6..6dd7aeffcf 100644 ---
> a/sysdeps/unix/sysv/linux/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/bits/struct_stat.h @@ -26,6 +26,13 @@
>  #include <bits/endian.h>
>  #include <bits/wordsize.h>
>  
> +#ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +#else
>  struct stat
>    {
>      __dev_t st_dev;			/* Device.  */
> @@ -81,8 +88,16 @@ struct stat
>      __ino64_t st_ino;			/* File serial
> number.	*/ #endif
>    };
> +#endif /* __USE_TIME_BITS64  */
>  
>  #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat64
>    {
>      __dev_t st_dev;			/* Device.  */
> @@ -119,6 +134,7 @@ struct stat64
>  # endif
>      __ino64_t st_ino;			/* File serial
> number.		*/ };
> +# endif /* __USE_TIME_BITS64  */
>  #endif
>  
>  /* Tell code we have these members.  */
> @@ -127,5 +143,4 @@ struct stat64
>  /* Nanosecond resolution time values are supported.  */
>  #define _STATBUF_ST_NSEC
>  
> -
>  #endif /* _BITS_STRUCT_STAT_H  */
> diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
> b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h new file
> mode 100644 index 0000000000..3ca6258bd5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
> @@ -0,0 +1,70 @@
> +/* Definition for helper to define struct stat with 64 bit time.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _BITS_STRUCT_STAT_TIME64_HELPER_H
> +#define _BITS_STRUCT_STAT_TIME64_HELPER_H	1
> +
> +#include <bits/endian.h>
> +
> +/* The definition should be equal to the 'struct __timespec64'
> internal
> +   layout.  */
> +#if BYTE_ORDER == BIG_ENDIAN
> +# define __fieldts64(name)					\
> +     __time64_t name; __int32_t :32; __int32_t name ## nsec
> +#else
> +# define __fieldts64(name)					\
> +     __time64_t name; __int32_t name ## nsec; __int32_t :32
> +#endif
> +
> +# ifdef __USE_XOPEN2K8
> +# define st_atime st_atim.tv_sec
> +# define st_mtime st_mtim.tv_sec
> +# define st_ctime st_ctim.tv_sec
> +    /* Nanosecond resolution timestamps are stored in a format
> +       equivalent to 'struct timespec'.  This is the type used
> +       whenever possible but the Unix namespace rules do not allow
> the
> +       identifier 'timespec' to appear in the <sys/stat.h> header.
> +       Therefore we have to handle the use of this header in strictly
> +       standard-compliant sources special.  */
> +#  define __STAT64_TIME64_CONTENT  \
> +    struct timespec st_atim; \
> +    struct timespec st_mtim; \
> +    struct timespec st_ctim;
> +# else
> +#  define __STAT64_TIME64_CONTENT  \
> +	__fieldts64 (st_atime); \
> +	__fieldts64 (st_mtime); \
> +	__fieldts64 (st_ctime);
> +# endif /* __USE_XOPEN2K8  */
> +
> +/* Content of internal __stat64_t64 struct.  */
> +#define __STAT64_T64_CONTENT
>           \
> +    __dev_t st_dev;			/* Device.  */
>              \
> +    __ino64_t st_ino;			/* file serial
> number.	*/             \
> +    __mode_t st_mode;			/* File mode.  */
>                \
> +    __nlink_t st_nlink;			/* Link count.  */
>          \
> +    __uid_t st_uid;			/* User ID of the file's
> owner.  */    \
> +    __gid_t st_gid;			/* Group ID of the file's
> group.*/     \
> +    __dev_t st_rdev;			/* Device number, if
> device.  */       \
> +    __off64_t st_size;			/* Size of file, in
> bytes.  */         \
> +    __blksize_t st_blksize;		/* Optimal block size for
> I/O.  */     \
> +    __blkcnt64_t st_blocks;		/* Number 512-byte blocks
> allocated. */\
> +    __STAT64_TIME64_CONTENT
> +
> +# undef __fieldts64
> +#endif /* _BITS_STRUCT_STAT_TIME64_HELPER_H  */
> diff --git a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h index
> bf457a0db7..5bf9e110fb 100644 ---
> a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h @@ -23,6 +23,13 @@
>  #ifndef _BITS_STRUCT_STAT_H
>  #define _BITS_STRUCT_STAT_H	1
>  
> +#ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +#else
>  struct stat
>    {
>      __dev_t st_dev;			/* Device.  */
> @@ -78,8 +85,16 @@ struct stat
>      __ino64_t st_ino;			/* File serial
> number.	*/ #endif
>    };
> +#endif /* __USE_TIME_BITS64 */
>  
>  #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat64
>    {
>      __dev_t st_dev;			/* Device.  */
> @@ -116,6 +131,7 @@ struct stat64
>  # endif
>      __ino64_t st_ino;			/* File serial
> number.		*/ };
> +# endif /* __USE_TIME_BITS64 */
>  #endif
>  
>  /* Tell code we have these members.  */
> diff --git a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h index
> db81543b23..3fac74039a 100644 ---
> a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h @@ -63,6
> +63,13 @@ struct stat unsigned int            __glibc_reserved5;
>  };
>  #else /* __USE_FILE_OFFSET64 */
> +# ifdef __USE_TIME_BITS64
> +#  include <bits/struct_stat_time64_helper.h>
> +struct stat
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  /* MS: If __USE_FILE_OFFSET64 is setup then struct stat should match
> stat64
>   * structure. Glibc has no type __dev64_t that's why I had to use
> standard
>   * type for st_dev and st_rdev. Several architectures uses pads
> after st_dev @@ -106,9 +113,17 @@ struct stat
>          unsigned int            __glibc_reserved4;
>          unsigned int            __glibc_reserved5;
>  };
> +# endif /* __USE_TIME_BITS64 */
>  #endif /* __USE_FILE_OFFSET64 */
>  
>  #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat64
>  {
>          unsigned long long      st_dev;     /* Device.  */
> @@ -147,6 +162,7 @@ struct stat64
>          unsigned int            __glibc_reserved4;
>          unsigned int            __glibc_reserved5;
>  };
> +# endif /* __USE_TIME_BITS64 */
>  #endif
>  
>  /* Tell code we have these members.  */
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h index
> 5abd71fc23..0b88f7cba5 100644 ---
> a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h @@ -119,6 +119,13
> @@ struct stat64 };
>  #endif
>  #else
> +# ifdef __USE_TIME_BITS64
> +#  include <bits/struct_stat_time64_helper.h>
> +struct stat
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat
>    {
>      __dev_t st_dev;
> @@ -171,8 +178,16 @@ struct stat
>  #endif
>      int st_pad5[14];
>    };
> +# endif /* __USE_TIME_BITS64 */
>  
>  #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat64
>    {
>      __dev_t st_dev;
> @@ -208,6 +223,7 @@ struct stat64
>      __blkcnt64_t st_blocks;
>      int st_pad4[14];
>  };
> +# endif /* __USE_TIME_BITS64 */
>  #endif
>  #endif
>  
> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h index
> cb41adc7c0..09228e046e 100644 ---
> a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h @@ -26,35 +26,41
> @@ #include <bits/wordsize.h>
>  
>  #if __WORDSIZE == 32
> -
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat
>    {
>      __dev_t st_dev;			/* Device.  */
> -# ifndef __USE_FILE_OFFSET64
> +#  ifndef __USE_FILE_OFFSET64
>      unsigned short int __pad1;
>      __ino_t st_ino;			/* File serial
> number.	*/ -# else
> +#  else
>      __ino64_t st_ino;			/* File serial
> number.	*/ -# endif
> +#  endif
>      __mode_t st_mode;			/* File mode.  */
>      __nlink_t st_nlink;			/* Link count.  */
>      __uid_t st_uid;			/* User ID of the file's
> owner.	*/ __gid_t st_gid;			/* Group ID
> of the file's group.*/ __dev_t st_rdev;			/*
> Device number, if device.  */ unsigned short int __pad2;
> -# ifndef __USE_FILE_OFFSET64
> +#  ifndef __USE_FILE_OFFSET64
>      __off_t st_size;			/* Size of file, in
> bytes.  */ -# else
> +#  else
>      __off64_t st_size;			/* Size of file, in
> bytes.  */ -# endif
> +#  endif
>      __blksize_t st_blksize;		/* Optimal block size for
> I/O.  */ 
> -# ifndef __USE_FILE_OFFSET64
> +#  ifndef __USE_FILE_OFFSET64
>      __blkcnt_t st_blocks;		/* Number 512-byte blocks
> allocated. */ -# else
> +#  else
>      __blkcnt64_t st_blocks;		/* Number 512-byte blocks
> allocated. */ -# endif
> -# ifdef __USE_XOPEN2K8
> +#  endif
> +#  ifdef __USE_XOPEN2K8
>      /* Nanosecond resolution timestamps are stored in a format
>         equivalent to 'struct timespec'.  This is the type used
>         whenever possible but the Unix namespace rules do not allow
> the @@ -64,23 +70,30 @@ struct stat
>      struct timespec st_atim;		/* Time of last access.
> */ struct timespec st_mtim;		/* Time of last
> modification.  */ struct timespec st_ctim;		/* Time of
> last status change.  */ -#  define st_atime st_atim.tv_sec	/*
> Backward compatibility.  */ -#  define st_mtime st_mtim.tv_sec
> -#  define st_ctime st_ctim.tv_sec
> -# else
> +#   define st_atime st_atim.tv_sec	/* Backward compatibility.
>  */ +#   define st_mtime st_mtim.tv_sec
> +#   define st_ctime st_ctim.tv_sec
> +#  else
>      __time_t st_atime;			/* Time of last
> access.  */ unsigned long int st_atimensec;	/* Nscecs of last
> access.  */ __time_t st_mtime;			/* Time of last
> modification.  */ unsigned long int st_mtimensec;	/* Nsecs of
> last modification.  */ __time_t st_ctime;			/*
> Time of last status change.  */ unsigned long int
> st_ctimensec;	/* Nsecs of last status change.  */ -# endif
> +#  endif
>      unsigned long int __glibc_reserved4;
>      unsigned long int __glibc_reserved5;
>    };
> -
> +# endif /* __USE_TIME_BITS64 */
>  
>  # ifdef __USE_LARGEFILE64
> +#  ifdef __USE_TIME_BITS64
> +#  include <bits/struct_stat_time64_helper.h>
> +struct stat64
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +#  else
>  struct stat64
>    {
>      __dev_t st_dev;			/* Device.  */
> @@ -213,6 +226,7 @@ struct stat64
>      unsigned long int __glibc_reserved5;
>      unsigned long int __glibc_reserved6;
>    };
> +#  endif /* __USE_TIME_BITS64 */
>  # endif /* __USE_LARGEFILE64 */
>  #endif
>  
> diff --git a/sysdeps/unix/sysv/linux/struct_stat_time64.h
> b/sysdeps/unix/sysv/linux/struct_stat_time64.h index
> b85385b6f3..5a4949000e 100644 ---
> a/sysdeps/unix/sysv/linux/struct_stat_time64.h +++
> b/sysdeps/unix/sysv/linux/struct_stat_time64.h @@ -23,63 +23,25 @@
>  # define __stat64_t64 stat64
>  #else
>  # ifdef __USE_LARGEFILE64
> -#  include <endian.h>
> -
> -/* The definition should be equal to the 'struct __timespec64'
> internal
> -   layout.  */
> -#  if BYTE_ORDER == BIG_ENDIAN
> -#   define __fieldts64(name)
> \
> -     __time64_t name; __int32_t :32; __int32_t name ## nsec
> -#  else
> -#   define __fieldts64(name)					\
> -     __time64_t name; __int32_t name ## nsec; __int32_t :32
> -#  endif
> -
> -/* Workaround for the definition from struct_stat.h  */
> -#  undef st_atime
> -#  undef st_mtime
> -#  undef st_ctime
> -
> +#  include <struct___timespec64.h>
> +#  include <bits/struct_stat_time64_helper.h>
> +#  ifdef __USE_XOPEN2K8
> +#   undef __STAT64_TIME64_CONTENT
> +/* Use glibc internal types for time related members */
> +#   define __STAT64_TIME64_CONTENT  \
> +      struct __timespec64 st_atim; \
> +      struct __timespec64 st_mtim; \
> +      struct __timespec64 st_ctim;
> +#  endif /* __USE_XOPEN2K8 */
>  struct __stat64_t64
>    {
> -    __dev_t st_dev;			/* Device.  */
> -    __ino64_t st_ino;			/* file serial
> number.	*/
> -    __mode_t st_mode;			/* File mode.  */
> -    __nlink_t st_nlink;			/* Link count.  */
> -    __uid_t st_uid;			/* User ID of the file's
> owner.	*/
> -    __gid_t st_gid;			/* Group ID of the file's
> group.*/
> -    __dev_t st_rdev;			/* Device number, if
> device.  */
> -    __off64_t st_size;			/* Size of file, in
> bytes.  */
> -    __blksize_t st_blksize;		/* Optimal block size for
> I/O.  */
> -    __blkcnt64_t st_blocks;		/* Number 512-byte blocks
> allocated. */ -#   ifdef __USE_XOPEN2K8
> -    /* Nanosecond resolution timestamps are stored in a format
> -       equivalent to 'struct timespec'.  This is the type used
> -       whenever possible but the Unix namespace rules do not allow
> the
> -       identifier 'timespec' to appear in the <sys/stat.h> header.
> -       Therefore we have to handle the use of this header in strictly
> -       standard-compliant sources special.  */
> -    struct __timespec64 st_atim;	/* Time of last access.  */
> -    struct __timespec64 st_mtim;	/* Time of last
> modification.  */
> -    struct __timespec64 st_ctim;	/* Time of last status
> change.  */ -#    define st_atime st_atim.tv_sec	/* Backward
> compatibility.  */ -#    define st_mtime st_mtim.tv_sec
> -#    define st_ctime st_ctim.tv_sec
> -#   else
> -    __fieldts64 (st_atime);
> -    __fieldts64 (st_mtime);
> -    __fieldts64 (st_ctime);
> -#   endif /* __USE_XOPEN2K8  */
> +    __STAT64_T64_CONTENT
>    };
>  
>  #   define _STATBUF_ST_BLKSIZE
>  #   define _STATBUF_ST_RDEV
>  #   define _STATBUF_ST_NSEC
>  
> -#   undef __fieldts64
> -
>  #  endif /* __USE_LARGEFILE64  */
> -
>  # endif /* __TIMESIZE == 64  */
> -
>  #endif /* _BITS_STRUCT_STAT_TIME64_H  */
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h index
> dae7aa46b3..e7e87c62b4 100644 ---
> a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h @@ -23,6 +23,13 @@
>  #ifndef _BITS_STRUCT_STAT_H
>  #define _BITS_STRUCT_STAT_H	1
>  
> +#ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +#else
>  struct stat
>    {
>      __dev_t st_dev;		/* Device.  */
> @@ -93,9 +100,17 @@ struct stat
>  # endif
>  #endif
>    };
> +#endif /* __USE_TIME_BITS64 */
>  
>  #ifdef __USE_LARGEFILE64
>  /* Note stat64 has the same shape as stat for x86-64.  */
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> +  {
> +    __STAT64_T64_CONTENT
> +  };
> +# else
>  struct stat64
>    {
>      __dev_t st_dev;		/* Device.  */
> @@ -146,6 +161,7 @@ struct stat64
>      __ino64_t st_ino;			/* File serial
> number.		*/ # endif
>    };
> +# endif /* __USE_TIME_BITS64  */
>  #endif
>  
>  /* Tell code we have these members.  */




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 4/6] y2038: Enhance struct msqid_ds to support 64 bit time
  2020-12-04 23:36 ` [RFC 4/6] y2038: Enhance struct msqid_ds to support 64 bit time Lukasz Majewski
@ 2020-12-29 10:34   ` Lukasz Majewski
  0 siblings, 0 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-29 10:34 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 7813 bytes --]

Dear Community,

> ---
>  sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h |  8 ++++++++
>  .../sysv/linux/hppa/bits/types/struct_msqid_ds.h     |  8 ++++++++
>  .../sysv/linux/mips/bits/types/struct_msqid_ds.h     | 12
> ++++++++++-- .../sysv/linux/powerpc/bits/types/struct_msqid_ds.h  |
> 8 ++++++++ .../sysv/linux/sparc/bits/types/struct_msqid_ds.h    |  8
> ++++++++ 5 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h index
> 43b38175ad..6d8194991f 100644 ---
> a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h +++
> b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h @@ -20,18
> +20,26 @@ # error "Never use <bits/msq.h> directly; include
> <sys/msg.h> instead." #endif
>  

Gentle request for feedback for this patch set.

> +#include <bits/types/time_t.h>
> +
>  /* Structure of record for one message inside the kernel.
>     The type `struct msg' is opaque.  */
>  struct msqid_ds
>  {
>    struct ipc_perm msg_perm;	/* structure describing operation
> permission */ #if __TIMESIZE == 32
> +# if __USE_TIME_BITS64
> +  __time64_t msg_stime;	/* time of last msgsnd command */
> +  __time64_t msg_rtime;	/* time of last msgsnd command */
> +  __time64_t msg_ctime;	/* time of last change */
> +# else
>    __time_t msg_stime;		/* time of last msgsnd command
> */ unsigned long int __msg_stime_high;
>    __time_t msg_rtime;		/* time of last msgsnd command
> */ unsigned long int __msg_rtime_high;
>    __time_t msg_ctime;		/* time of last change */
>    unsigned long int __msg_ctime_high;
> +# endif
>  #else
>    __time_t msg_stime;		/* time of last msgsnd command
> */ __time_t msg_rtime;		/* time of last msgsnd command
> */ diff --git
> a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
> b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h index
> 16eac46941..08c5323f03 100644 ---
> a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h +++
> b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h @@ -20,18
> +20,26 @@ # error "Never use <bits/msq.h> directly; include
> <sys/msg.h> instead." #endif 
> +#include <bits/types/time_t.h>
> +
>  /* Structure of record for one message inside the kernel.
>     The type `struct msg' is opaque.  */
>  struct msqid_ds
>  {
>    struct ipc_perm msg_perm;	/* structure describing operation
> permission */ #if __TIMESIZE == 32
> +# if __USE_TIME_BITS64
> +  __time64_t msg_stime;	/* time of last msgsnd command */
> +  __time64_t msg_rtime;	/* time of last msgsnd command */
> +  __time64_t msg_ctime;	/* time of last change */
> +# else
>    unsigned long int __msg_stime_high;
>    __time_t msg_stime;		/* time of last msgsnd command
> */ unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;		/* time of last msgsnd command
> */ unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;		/* time of last change */
> +# endif
>  #else
>    __time_t msg_stime;		/* time of last msgsnd command
> */ __time_t msg_rtime;		/* time of last msgsnd command
> */ diff --git
> a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
> b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h index
> 513e01a171..ac077bfca8 100644 ---
> a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h +++
> b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h @@ -20,26
> +20,34 @@ # error "Never use <bits/msq.h> directly; include
> <sys/msg.h> instead." #endif 
> +#include <bits/types/time_t.h>
> +
>  /* Structure of record for one message inside the kernel.
>     The type `struct msg' is opaque.  */
>  struct msqid_ds
>  {
>    struct ipc_perm msg_perm;	/* structure describing operation
> permission */ #if __TIMESIZE == 32
> -# ifdef __MIPSEL__
> +# if __USE_TIME_BITS64
> +  __time64_t msg_stime;	/* time of last msgsnd command */
> +  __time64_t msg_rtime;	/* time of last msgsnd command */
> +  __time64_t msg_ctime;	/* time of last change */
> +# else
> +#  ifdef __MIPSEL__
>    __time_t msg_stime;		/* time of last msgsnd command
> */ unsigned long int __msg_stime_high;
>    __time_t msg_rtime;		/* time of last msgsnd command
> */ unsigned long int __msg_rtime_high;
>    __time_t msg_ctime;		/* time of last change */
>    unsigned long int __msg_ctime_high;
> -# else
> +#  else
>    unsigned long int __msg_stime_high;
>    __time_t msg_stime;		/* time of last msgsnd command
> */ unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;		/* time of last msgsnd command
> */ unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;		/* time of last change */
> +#  endif
>  # endif
>  #else
>    __time_t msg_stime;		/* time of last msgsnd command
> */ diff --git
> a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
> b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h index
> 35cc51f733..bf450c9605 100644 ---
> a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h +++
> b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h @@
> -20,18 +20,26 @@ # error "Never use <bits/msq.h> directly; include
> <sys/msg.h> instead." #endif 
> +#include <bits/types/time_t.h>
> +
>  /* Structure of record for one message inside the kernel.
>     The type `struct msg' is opaque.  */
>  struct msqid_ds
>  {
>    struct ipc_perm msg_perm;	/* structure describing operation
> permission */ #if __TIMESIZE == 32
> +# if __USE_TIME_BITS64
> +  __time64_t msg_stime;	/* time of last msgsnd command */
> +  __time64_t msg_rtime;	/* time of last msgsnd command */
> +  __time64_t msg_ctime;	/* time of last change */
> +# else
>    unsigned long int __msg_stime_high;
>    __time_t msg_stime;		/* time of last msgsnd command
> */ unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;		/* time of last msgsnd command
> */ unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;		/* time of last change */
> +# endif
>  #else
>    __time_t msg_stime;		/* time of last msgsnd command
> */ __time_t msg_rtime;		/* time of last msgsnd command
> */ diff --git
> a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
> b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h index
> 502c23d91e..a9e309dafc 100644 ---
> a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h +++
> b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h @@
> -20,18 +20,26 @@ # error "Never use <bits/msq.h> directly; include
> <sys/msg.h> instead." #endif 
> +#include <bits/types/time_t.h>
> +
>  /* Structure of record for one message inside the kernel.
>     The type `struct msg' is opaque.  */
>  struct msqid_ds
>  {
>    struct ipc_perm msg_perm;	/* structure describing operation
> permission */ #if __TIMESIZE == 32
> +# if __USE_TIME_BITS64
> +  __time64_t msg_stime;	/* time of last msgsnd command */
> +  __time64_t msg_rtime;	/* time of last msgsnd command */
> +  __time64_t msg_ctime;	/* time of last change */
> +# else
>    unsigned long int __msg_stime_high;
>    __time_t msg_stime;		/* time of last msgsnd command
> */ unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;		/* time of last msgsnd command
> */ unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;		/* time of last change */
> +# endif
>  #else
>    __time_t msg_stime;		/* time of last msgsnd command
> */ __time_t msg_rtime;		/* time of last msgsnd command
> */




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC 5/6] msqid: Provide internal copy of struct __msqid64_ds
  2020-12-04 23:36 ` [RFC 5/6] msqid: Provide internal copy of struct __msqid64_ds Lukasz Majewski
@ 2020-12-29 10:54   ` Lukasz Majewski
  0 siblings, 0 replies; 21+ messages in thread
From: Lukasz Majewski @ 2020-12-29 10:54 UTC (permalink / raw
  To: Joseph Myers, Paul Eggert, Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Siddhesh Poyarekar, Andreas Schwab,
	Stepan Golosunov, Alistair Francis

[-- Attachment #1: Type: text/plain, Size: 5363 bytes --]

Hi Adhemerval,

> After the commit SHA1: 3283f711132eaadc4f04bd8c1d84c910c29ba
> "sysv: linux: Add 64-bit time_t variant for msgctl"
> 
> The glibc internal, 64 bit supporting version of struct __msqid64_ds
> has been exported.
> 
> This approach has issue when one would like to add Y2038 support to
> glibc. The problem is that both struct msqid_ds and __msqid64_ds rely
> on exported implementation of the msg.h header (./sysvipc/sys/msg.h)
> which unconditionally includes ./sysdeps/unix/sysv/linux/bits/msq.h
> which in turn includes
> ./sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> 
> As a result the externally exported struct msqid_ds.h is used
> internally by glibc. Problem starts when one wants to extend this
> struct with 64 bit time support:
> 
> | In file included from ../sysdeps/unix/sysv/linux/bits/msq.h:28,
> |                  from ../sysvipc/sys/msg.h:30,
> |                  from
> ../sysdeps/unix/sysv/linux/include/sys/msg.h:2, |
> from ../include/sys/msg.h:1, |                  from
> ../sysdeps/unix/sysv/linux/msgctl.c:19: |
> ../sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h:31:6: error:
> "__USE_TIME_BITS64" is not defined, evaluates to 0 [-Werror=undef] |
> # if __USE_TIME_BITS64 |       ^~~~~~~~~~~~~~~~~
> 
> 
> To fix this issue - the internal,for glibc, copy of struct
> __msqid64_ds has been re-introduced. This will allow clear separation
> between exported and internal glibc types.
> 
> Moreover, the __TIMESIZE based alias shall be internal to glibc.
> 
> Build tests:
> ./src/scripts/build-many-glibcs.py glibcs

We had a discussion regarding this patch some time ago [1].

The conclusion was that we would need to duplicate this structure to
have a copy of msqid_ds structure as adding new members to exported
(and POSIX standardized) headers causes POSIX naming pollution.

Can we have a final agreement on this patch?

This also would require discussion about related patch - 
"msg: provide glibc local copy of struct msqid_ds" [2]

Links: 
[1] - https://marc.info/?t=160383682700004&r=1&w=2
[2] - https://marc.info/?t=160383682700003&r=1&w=2

> ---
>  include/bits/types/struct_msqid64_ds.h        | 36
> +++++++++++++++++++ .../sysv/linux/bits/types/struct_msqid64_ds.h |
> 4 --- 2 files changed, 36 insertions(+), 4 deletions(-)
>  create mode 100644 include/bits/types/struct_msqid64_ds.h
> 
> diff --git a/include/bits/types/struct_msqid64_ds.h
> b/include/bits/types/struct_msqid64_ds.h new file mode 100644
> index 0000000000..8c39a2a872
> --- /dev/null
> +++ b/include/bits/types/struct_msqid64_ds.h
> @@ -0,0 +1,36 @@
> +/* Internal for glibc implementation of the SysV message struct
> msqid64_ds.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <time.h>
> +
> +#if __TIMESIZE == 64
> +# define __msqid64_ds msqid_ds
> +#else
> +struct __msqid64_ds
> +{
> +  struct ipc_perm msg_perm;	/* structure describing operation
> permission */
> +  __time64_t msg_stime;		/* time of last msgsnd
> command */
> +  __time64_t msg_rtime;		/* time of last msgsnd
> command */
> +  __time64_t msg_ctime;		/* time of last change */
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on
> queue */
> +  msgqnum_t msg_qnum;		/* number of messages currently
> on queue */
> +  msglen_t msg_qbytes;		/* max number of bytes allowed
> on queue */
> +  __pid_t msg_lspid;		/* pid of last msgsnd() */
> +  __pid_t msg_lrpid;		/* pid of last msgrcv() */
> +};
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
> b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h index
> 3536c8ea62..07cc1036ab 100644 ---
> a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h +++
> b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h @@ -20,9
> +20,6 @@ # error "Never use <bits/msq.h> directly; include
> <sys/msg.h> instead." #endif
>  
> -#if __TIMESIZE == 64
> -# define __msqid64_ds msqid_ds
> -#else
>  struct __msqid64_ds
>  {
>    struct ipc_perm msg_perm;	/* structure describing operation
> permission */ @@ -35,4 +32,3 @@ struct __msqid64_ds
>    __pid_t msg_lspid;		/* pid of last msgsnd() */
>    __pid_t msg_lrpid;		/* pid of last msgrcv() */
>  };
> -#endif




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-12-29 10:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-04 23:35 [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Lukasz Majewski
2020-12-04 23:35 ` [RFC 1/6] y2038: Introduce _TIME_BITS flag to support 64 bit time on 32 bit systems Lukasz Majewski
2020-12-05  0:12   ` Joseph Myers
2020-12-07 13:00     ` Lukasz Majewski
2020-12-04 23:36 ` [RFC 2/6] y2038: stat: {f}stat{at}64_time64 redirection to be used on Y2038 systems Lukasz Majewski
2020-12-05  0:04   ` Joseph Myers
2020-12-07 10:28     ` Lukasz Majewski
2020-12-07 18:07       ` Joseph Myers
2020-12-04 23:36 ` [RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content Lukasz Majewski
2020-12-29 10:30   ` Lukasz Majewski
2020-12-04 23:36 ` [RFC 4/6] y2038: Enhance struct msqid_ds to support 64 bit time Lukasz Majewski
2020-12-29 10:34   ` Lukasz Majewski
2020-12-04 23:36 ` [RFC 5/6] msqid: Provide internal copy of struct __msqid64_ds Lukasz Majewski
2020-12-29 10:54   ` Lukasz Majewski
2020-12-04 23:36 ` [RFC 6/6] msg: provide glibc local copy of struct msqid_ds Lukasz Majewski
2020-12-05  0:01 ` [RFC 0/6] y2038: Prepare glibc to be Y2038 safe for 32 bit ports Joseph Myers
2020-12-07 10:22   ` Lukasz Majewski
2020-12-07 18:01     ` Joseph Myers
2020-12-08 10:07       ` Lukasz Majewski
2020-12-08 15:25         ` Joseph Myers
2020-12-13 11:49           ` Lukasz Majewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).