This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch aaribaud/y2038 created. glibc-2.28.9000-240-g7049c17


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, aaribaud/y2038 has been created
        at  7049c171f816f22a40e8495f2ae9dfc4441fc392 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7049c171f816f22a40e8495f2ae9dfc4441fc392

commit 7049c171f816f22a40e8495f2ae9dfc4441fc392
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Wed Sep 6 10:00:42 2017 +0200

    Y2038: add _TIME_BITS support
    
    This makes all previously defined Y2038-proof API types, functions and
    implementations the default when _TIME_BITS==64 and __WORDSIZE==32 (so
    that 64-bit architectures are unaffected).
    
    Note: it is assumed that the API is consistent, i.e. for each API type
    which is enabled here, all API functions which depend on this type are
    enabled and mapped to Y2038-proof implementations.

diff --git a/include/features.h b/include/features.h
index 5bed0a4..47eb58b 100644
--- a/include/features.h
+++ b/include/features.h
@@ -364,6 +364,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_BIT==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/sys/stat.h b/io/sys/stat.h
index 762c853..f5831cb 100644
--- a/io/sys/stat.h
+++ b/io/sys/stat.h
@@ -210,14 +210,27 @@ 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
@@ -260,12 +273,23 @@ 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
 #  else
-#   define lstat lstat64
+#   ifdef __USE_TIME_BITS64
+#    define lstat __lstat64_time64
+#   else
+#    define lstat lstat64
+#   endif
 #  endif
 # endif
 # ifdef __USE_LARGEFILE64
@@ -357,6 +381,15 @@ extern int mkfifoat (int __fd, const char *__path, __mode_t __mode)
 #ifdef __USE_ATFILE
 /* Set file access and modification times relative to directory file
    descriptor.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (utimensat, (int __fd, const char *__path,
+           const struct timespec __times[2], int __flags),
+           __utimensat64) __THROW __nonnull((2));
+# else
+# define utimensat __utimensat64
+# endif
+#endif
 extern int utimensat (int __fd, const char *__path,
 		      const struct timespec __times[2],
 		      int __flags)
@@ -365,6 +398,14 @@ extern int utimensat (int __fd, const char *__path,
 
 #ifdef __USE_XOPEN2K8
 /* Set file access and modification times of the file associated with FD.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (futimens, (int __fd, const struct timespec __times[2]),
+           __futimens64) __THROW;
+# else
+# define futimens __futimens64
+# endif
+#endif
 extern int futimens (int __fd, const struct timespec __times[2]) __THROW;
 #endif
 
@@ -403,6 +444,21 @@ extern int __fxstatat (int __ver, int __fildes, const char *__filename,
      __THROW __nonnull ((3, 4));
 #else
 # ifdef __REDIRECT_NTH
+#  ifdef __USE_TIME_BITS64
+extern int __REDIRECT_NTH (__fxstat, (int __ver, int __fildes,
+				      struct stat *__stat_buf), __fxstat64_time64)
+     __nonnull ((3));
+extern int __REDIRECT_NTH (__xstat, (int __ver, const char *__filename,
+				     struct stat *__stat_buf), __xstat64_time64)
+     __nonnull ((2, 3));
+extern int __REDIRECT_NTH (__lxstat, (int __ver, const char *__filename,
+				      struct stat *__stat_buf), __lxstat64_time64)
+     __nonnull ((2, 3));
+extern int __REDIRECT_NTH (__fxstatat, (int __ver, int __fildes,
+					const char *__filename,
+					struct stat *__stat_buf, int __flag),
+			   __fxstatat64_time64) __nonnull ((3, 4));
+#  else
 extern int __REDIRECT_NTH (__fxstat, (int __ver, int __fildes,
 				      struct stat *__stat_buf), __fxstat64)
      __nonnull ((3));
@@ -416,11 +472,18 @@ extern int __REDIRECT_NTH (__fxstatat, (int __ver, int __fildes,
 					const char *__filename,
 					struct stat *__stat_buf, int __flag),
 			   __fxstatat64) __nonnull ((3, 4));
+#  endif
 
 # else
-#  define __fxstat __fxstat64
-#  define __xstat __xstat64
-#  define __lxstat __lxstat64
+#  ifdef __USE_TIME_BITS64
+#   define __fxstat __fxstat64_time64
+#   define __xstat __xstat64_time64
+#   define __lxstat __lxstat64_time64
+#  else
+#   define __fxstat __fxstat64
+#   define __xstat __xstat64
+#   define __lxstat __lxstat64
+#  endif
 # endif
 #endif
 
diff --git a/io/utime.h b/io/utime.h
index 8409ba4..0068e2f 100644
--- a/io/utime.h
+++ b/io/utime.h
@@ -27,20 +27,30 @@
 __BEGIN_DECLS
 
 #include <bits/types.h>
+#include <bits/types/time_t.h>
 
 #if defined __USE_XOPEN || defined __USE_XOPEN2K
 # include <bits/types/time_t.h>
 #endif
 
-/* Structure describing file times.  */
+/* Structure describing file times, 32- or 64-bit time.  */
 struct utimbuf
   {
-    __time_t actime;		/* Access time.  */
-    __time_t modtime;		/* Modification time.  */
+    time_t actime;		/* Access time.  */
+    time_t modtime;		/* Modification time.  */
   };
 
 /* Set the access and modification times of FILE to those given in
    *FILE_TIMES.  If FILE_TIMES is NULL, set them to the current time.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (utime, (const char *__file,
+     const struct utimbuf *__file_times),
+     __utime64) __THROW __nonnull ((1));
+# else
+# define utime __utime64
+# endif
+#endif
 extern int utime (const char *__file,
 		  const struct utimbuf *__file_times)
      __THROW __nonnull ((1));
diff --git a/manual/creature.texi b/manual/creature.texi
index 8876b2a..10b7111 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/sys/select.h b/misc/sys/select.h
index 4183e85..d5ddefd 100644
--- a/misc/sys/select.h
+++ b/misc/sys/select.h
@@ -99,6 +99,18 @@ __BEGIN_DECLS
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#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
 extern int select (int __nfds, fd_set *__restrict __readfds,
 		   fd_set *__restrict __writefds,
 		   fd_set *__restrict __exceptfds,
@@ -111,6 +123,19 @@ extern int select (int __nfds, fd_set *__restrict __readfds,
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#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
 extern int pselect (int __nfds, fd_set *__restrict __readfds,
 		    fd_set *__restrict __writefds,
 		    fd_set *__restrict __exceptfds,
diff --git a/posix/sched.h b/posix/sched.h
index 619b3b3..ea2f0e3 100644
--- a/posix/sched.h
+++ b/posix/sched.h
@@ -74,6 +74,15 @@ extern int sched_get_priority_max (int __algorithm) __THROW;
 extern int sched_get_priority_min (int __algorithm) __THROW;
 
 /* Get the SCHED_RR interval for the named process.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (sched_rr_get_interval,
+                       (__pid_t __pid, struct timespec *__t),
+                       __sched_rr_get_interval_time64) __THROW;
+# else
+# define sched_rr_get_interval __sched_rr_get_interval_time64
+# endif
+#endif
 extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) __THROW;
 
 
diff --git a/resource/sys/resource.h b/resource/sys/resource.h
index 881db39..5363adf 100644
--- a/resource/sys/resource.h
+++ b/resource/sys/resource.h
@@ -84,6 +84,15 @@ extern int setrlimit64 (__rlimit_resource_t __resource,
 
 /* Return resource usage information on process indicated by WHO
    and put it in *USAGE.  Returns 0 for success, -1 for failure.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (getrusage, (__rusage_who_t __who,
+				   struct rusage *__usage),
+     __getrusage64) __THROW;
+# else
+# define getrusage __getrusage64
+# endif
+#endif
 extern int getrusage (__rusage_who_t __who, struct rusage *__usage) __THROW;
 
 /* Return the highest priority of any process specified by WHICH and WHO
diff --git a/rt/mqueue.h b/rt/mqueue.h
index 5f354b4..710b111 100644
--- a/rt/mqueue.h
+++ b/rt/mqueue.h
@@ -73,6 +73,17 @@ extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len,
 #ifdef __USE_XOPEN2K
 /* Receive the oldest from highest priority messages in message queue
    MQDES, stop waiting if ABS_TIMEOUT expires.  */
+# ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern ssize_t __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_timedreceive64) __nonnull((2, 5));
+#  else
+#   define mq_timedreceive __mq_timedreceive64
+#  endif
+# endif
 extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr,
 				size_t __msg_len,
 				unsigned int *__restrict __msg_prio,
@@ -81,6 +92,17 @@ extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr,
 
 /* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
    on full message queue if ABS_TIMEOUT expires.  */
+# 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_timedsend64) __nonnull((2, 5));
+#  else
+#   define mq_timedsend __mq_timedsend64
+#  endif
+# endif
 extern int mq_timedsend (mqd_t __mqdes, const char *__msg_ptr,
 			 size_t __msg_len, unsigned int __msg_prio,
 			 const struct timespec *__abs_timeout)
diff --git a/signal/signal.h b/signal/signal.h
index 87dc82a..3f8c6e1 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -266,6 +266,16 @@ extern int sigwaitinfo (const sigset_t *__restrict __set,
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#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) __nonnull ((1));
+# else
+# define sigtimedwait __sigtimedwait64
+# endif
+#endif
 extern int sigtimedwait (const sigset_t *__restrict __set,
 			 siginfo_t *__restrict __info,
 			 const struct timespec *__restrict __timeout)
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index df049ab..5fb8a3f 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -765,6 +765,17 @@ extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
 
 #ifdef __USE_XOPEN2K
 /* Wait until lock becomes available, or specified time passes. */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (pthread_mutex_timedlock,
+		       (pthread_mutex_t *__restrict __mutex,
+			const struct timespec *__restrict __abstime),
+		       __pthread_mutex_timedlock64)
+	__THROWNL __nonnull ((1, 2));
+# else
+# define pthread_mutex_timedlock __pthread_mutex_timedlock64
+# endif
+#endif
 extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
 				    const struct timespec *__restrict
 				    __abstime) __THROWNL __nonnull ((1, 2));
@@ -904,6 +915,17 @@ extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
 
 # ifdef __USE_XOPEN2K
 /* Try to acquire read lock for RWLOCK or return after specfied time.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (pthread_rwlock_timedrdlock,
+		       (pthread_rwlock_t *__restrict __rwlock,
+			const struct timespec *__restrict __abstime),
+		       __pthread_rwlock_timedrdlock64)
+	__THROWNL __nonnull ((1, 2));
+# else
+# define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock64
+# endif
+#endif
 extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
 				       const struct timespec *__restrict
 				       __abstime) __THROWNL __nonnull ((1, 2));
@@ -919,6 +941,17 @@ extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
 
 # ifdef __USE_XOPEN2K
 /* Try to acquire write lock for RWLOCK or return after specfied time.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (pthread_rwlock_timedwrlock,
+		       (pthread_rwlock_t *__restrict __rwlock,
+			const struct timespec *__restrict __abstime),
+		       __pthread_rwlock_timedwrlock64)
+	__THROWNL __nonnull ((1, 2));
+# else
+# define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock64
+# endif
+#endif
 extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
 				       const struct timespec *__restrict
 				       __abstime) __THROWNL __nonnull ((1, 2));
@@ -998,6 +1031,18 @@ extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#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)
+	__nonnull ((1, 2, 3));
+# else
+# define pthread_cond_timedwait __pthread_cond_timedwait64
+# endif
+#endif
 extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
 				   pthread_mutex_t *__restrict __mutex,
 				   const struct timespec *__restrict __abstime)
diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
index ff672eb..3f8207a 100644
--- a/sysdeps/pthread/semaphore.h
+++ b/sysdeps/pthread/semaphore.h
@@ -57,6 +57,16 @@ extern int sem_wait (sem_t *__sem);
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern struct tm * __REDIRECT (sem_timedwait,
+                               (sem_t *__restrict __sem,
+                                const struct timespec *__restrict __abstime),
+       __sem_timedwait64);
+# else
+# define sem_timedwait __sem_timedwait64
+# endif
+#endif
 extern int sem_timedwait (sem_t *__restrict __sem,
 			  const struct timespec *__restrict __abstime);
 #endif
diff --git a/sysdeps/unix/sysv/linux/bits/msq.h b/sysdeps/unix/sysv/linux/bits/msq.h
index 5f43fa3..3adaf3b 100644
--- a/sysdeps/unix/sysv/linux/bits/msq.h
+++ b/sysdeps/unix/sysv/linux/bits/msq.h
@@ -46,6 +46,22 @@ typedef __syscall_ulong_t msglen_t;
 
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
+#ifdef __USE_TIME_BITS64
+struct msqid_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 msgrcv command */
+  __time64_t msg_ctime;		/* time of last change */
+  unsigned long int __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() */
+  unsigned long int __glibc_reserved4;
+  unsigned long int __glibc_reserved5;
+};
+#else
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
@@ -60,6 +76,7 @@ struct msqid_ds
   __syscall_ulong_t __glibc_reserved4;
   __syscall_ulong_t __glibc_reserved5;
 };
+#endif
 
 #ifdef __USE_MISC
 
diff --git a/sysdeps/unix/sysv/linux/bits/stat.h b/sysdeps/unix/sysv/linux/bits/stat.h
index 48ef82d..fde673e 100644
--- a/sysdeps/unix/sysv/linux/bits/stat.h
+++ b/sysdeps/unix/sysv/linux/bits/stat.h
@@ -119,11 +119,11 @@ struct stat64
     struct timespec st_mtim;		/* Time of last modification.  */
     struct timespec st_ctim;		/* Time of last status change.  */
 # else
-    __time_t st_atime;			/* Time of last access.  */
+    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.  */
+    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.  */
+    time_t st_ctime;			/* Time of last status change.  */
     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
 # endif
     __ino64_t st_ino;			/* File serial number.		*/
diff --git a/sysdeps/unix/sysv/linux/sys/timerfd.h b/sysdeps/unix/sysv/linux/sys/timerfd.h
index 37490cf..58d632e 100644
--- a/sysdeps/unix/sysv/linux/sys/timerfd.h
+++ b/sysdeps/unix/sysv/linux/sys/timerfd.h
@@ -44,11 +44,30 @@ extern int timerfd_create (__clockid_t __clock_id, int __flags) __THROW;
 /* Set next expiration time of interval timer source UFD to UTMR.  If
    FLAGS has the TFD_TIMER_ABSTIME flag set the timeout value is
    absolute.  Optionally return the old expiration time in OTMR.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (timerfd_settime, (int __ufd, int __flags,
+                       const struct itimerspec *__utmr,
+                       struct itimerspec *__otmr),__timerfd_settime64)
+                       __THROW;
+# else
+# define timerfd_settime __timerfd_settime64
+# endif
+#endif
 extern int timerfd_settime (int __ufd, int __flags,
 			    const struct itimerspec *__utmr,
 			    struct itimerspec *__otmr) __THROW;
 
 /* Return the next expiration time of UFD.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (timerfd_gettime, (int __ufd,
+                       struct itimerspec *__otmr),__timerfd_gettime64)
+                       __THROW;
+# else
+# define timerfd_gettime __timerfd_gettime64
+# endif
+#endif
 extern int timerfd_gettime (int __ufd, struct itimerspec *__otmr) __THROW;
 
 __END_DECLS
diff --git a/sysdeps/unix/sysv/linux/sys/timex.h b/sysdeps/unix/sysv/linux/sys/timex.h
index fd45929..d4ddb33 100644
--- a/sysdeps/unix/sysv/linux/sys/timex.h
+++ b/sysdeps/unix/sysv/linux/sys/timex.h
@@ -68,15 +68,43 @@ struct __ntptimeval64
 __BEGIN_DECLS
 
 extern int __adjtimex (struct timex *__ntx) __THROW;
+
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern time_t __REDIRECT (adjtimex, (struct timex *__ntx),
+     __adjtimex64) __THROW;
+# else
+# define adjtimex __adjtimex64
+# endif
+#endif
 extern int adjtimex (struct timex *__ntx) __THROW;
 
-#ifdef __REDIRECT_NTH
+#if __WORDSIZE > 32 || ! defined(__USE_TIME_BITS64)
+# ifdef __REDIRECT_NTH
 extern int __REDIRECT_NTH (ntp_gettime, (struct ntptimeval *__ntv),
 			   ntp_gettimex);
-#else
+# else
 extern int ntp_gettimex (struct ntptimeval *__ntv) __THROW;
+#  define ntp_gettime ntp_gettimex
+# endif
+#else
+# if defined(__REDIRECT)
+extern time_t __REDIRECT (ntp_gettimex, (struct ntptimeval *__ntv),
+                          __ntp_gettimex64) __THROW;
+# else
+# define ntp_gettimex __ntp_gettimex64
+# endif
 # define ntp_gettime ntp_gettimex
 #endif
+
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (ntp_adjtime, (struct timex *__tntx),
+                       __ntp_adjtime64) __THROW;
+# else
+# define ntp_adjtime __ntp_adjtime64
+# endif
+#endif
 extern int ntp_adjtime (struct timex *__tntx) __THROW;
 
 __END_DECLS
diff --git a/sysvipc/sys/msg.h b/sysvipc/sys/msg.h
index 1635839..92ea7ac 100644
--- a/sysvipc/sys/msg.h
+++ b/sysvipc/sys/msg.h
@@ -58,6 +58,15 @@ struct msgbuf
 __BEGIN_DECLS
 
 /* Message queue control operation.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (msgctl, (int __msqid, int __cmd,
+                       struct msqid_ds *__buf),
+                       __msgctl64) __THROW;
+# else
+# define msgctl __msgctl64
+# endif
+#endif
 extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) __THROW;
 
 /* Get messages queue.  */
diff --git a/time/bits/types/struct_itimerspec.h b/time/bits/types/struct_itimerspec.h
index 17cc1ac..2f40406 100644
--- a/time/bits/types/struct_itimerspec.h
+++ b/time/bits/types/struct_itimerspec.h
@@ -4,11 +4,17 @@
 #include <bits/types.h>
 #include <bits/types/struct_timespec.h>
 
+/* Use the original definition for 64-bit arches
+   or when 64-bit-time by default has *not* been requested */ 
+#if __WORDSIZE > 32 || ! defined(__USE_TIME_BITS64)
 /* POSIX.1b structure for timer start values and intervals.  */
 struct itimerspec
   {
     struct timespec it_interval;
     struct timespec it_value;
   };
+#else
+# define itimerspec __itimerspec64
+#endif
 
 #endif
diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h
index 5b77c52..f93557f 100644
--- a/time/bits/types/struct_timespec.h
+++ b/time/bits/types/struct_timespec.h
@@ -4,6 +4,9 @@
 
 #include <bits/types.h>
 
+/* Use the original definition for 64-bit arches
+   or when 64-bit-time by default has *not* been requested */ 
+#if __WORDSIZE > 32 || ! defined(__USE_TIME_BITS64)
 /* POSIX.1b structure for a time value.  This is like a `struct timeval' but
    has nanoseconds instead of microseconds.  */
 struct timespec
@@ -11,5 +14,9 @@ struct timespec
   __time_t tv_sec;		/* Seconds.  */
   __syscall_slong_t tv_nsec;	/* Nanoseconds.  */
 };
+#else
+/* Use the 64-bit-time timespec by default */
+#define timespec __timespec64
+# endif
 
 #endif
diff --git a/time/bits/types/struct_timeval.h b/time/bits/types/struct_timeval.h
index 70394ce..e710b37 100644
--- a/time/bits/types/struct_timeval.h
+++ b/time/bits/types/struct_timeval.h
@@ -3,6 +3,9 @@
 
 #include <bits/types.h>
 
+/* Use the original definition for 64-bit arches
+   or when 64-bit-time by default has *not* been requested */ 
+# if __WORDSIZE > 32 || ! defined(__USE_TIME_BITS64)
 /* A time value that is accurate to the nearest
    microsecond but also has a range of years.  */
 struct timeval
@@ -10,4 +13,9 @@ struct timeval
   __time_t tv_sec;		/* Seconds.  */
   __suseconds_t tv_usec;	/* Microseconds.  */
 };
+# else
+/* Use the 64-bit-time timespec by default */
+# define timeval __timeval64
+# endif
+
 #endif
diff --git a/time/bits/types/time_t.h b/time/bits/types/time_t.h
index ab8287c..84d67f6 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 b7fe339..01ac9b6 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -66,12 +66,31 @@ typedef void *__restrict __timezone_ptr_t;
    Returns 0 on success, -1 on errors.
    NOTE: This form of timezone information is obsolete.
    Use the functions and variables declared in <time.h> instead.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (gettimeofday, (struct timeval *__restrict __tv,
+                                   __timezone_ptr_t __tz),
+                    __gettimeofday64) __THROW __nonnull((1));
+# else
+# define gettimeofday __gettimeofday64
+# endif
+#endif
 extern int gettimeofday (struct timeval *__restrict __tv,
 			 __timezone_ptr_t __tz) __THROW __nonnull ((1));
 
 #ifdef __USE_MISC
 /* Set the current time of day and timezone information.
    This call is restricted to the super-user.  */
+#ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (settimeofday,
+                       (const struct timeval *__tv,
+                        const struct timezone *__tz),
+                    __settimeofday64) __THROW;
+#  else
+#   define settimeofday __settimeofday64
+#  endif
+# endif
 extern int settimeofday (const struct timeval *__tv,
 			 const struct timezone *__tz)
      __THROW;
@@ -80,6 +99,16 @@ extern int settimeofday (const struct timeval *__tv,
    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.  */
+#ifdef __USE_TIME_BITS64
+#  if defined(__REDIRECT)
+extern int __REDIRECT (adjtime,
+                       (const struct timeval *__delta,
+                        struct timeval *__olddelta),
+                    __adjtime64) __THROW;
+#  else
+#   define adjtime __adjtime64
+#  endif
+# endif
 extern int adjtime (const struct timeval *__delta,
 		    struct timeval *__olddelta) __THROW;
 #endif
@@ -130,12 +159,31 @@ typedef int __itimer_which_t;
 
 /* Set *VALUE to the current setting of timer WHICH.
    Return 0 on success, -1 on errors.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (getitimer, (__itimer_which_t __which,
+       struct itimerval *__value), __getitimer64)
+       __THROW;
+# else
+# define getitimer __getitimer64
+# endif
+#endif
 extern int getitimer (__itimer_which_t __which,
 		      struct itimerval *__value) __THROW;
 
 /* 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.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (setitimer, (__itimer_which_t __which,
+       const struct itimerval *__restrict __new,
+       struct itimerval *__restrict __old), __setitimer64)
+       __THROW;
+# else
+# define setitimer __setitimer64
+# endif
+#endif
 extern int setitimer (__itimer_which_t __which,
 		      const struct itimerval *__restrict __new,
 		      struct itimerval *__restrict __old) __THROW;
@@ -143,15 +191,41 @@ extern int setitimer (__itimer_which_t __which,
 /* 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.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (utimes, (const char *__file,
+       const struct timeval __tvp[2]), __utimes64)
+       __THROW __nonnull ((1));
+# else
+# define utimes __utimes64
+# endif
+#endif
 extern int utimes (const char *__file, const struct timeval __tvp[2])
      __THROW __nonnull ((1));
 
 #ifdef __USE_MISC
 /* Same as `utimes', but does not follow symbolic links.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (lutimes, (const char *__file,
+       const struct timeval __tvp[2]), __lutimes64)
+       __THROW __nonnull ((1));
+# else
+# define lutimes __lutimes64
+# endif
+#endif
 extern int lutimes (const char *__file, const struct timeval __tvp[2])
      __THROW __nonnull ((1));
 
 /* Same as `utimes', but takes an open file descriptor instead of a name.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (futimes, (int __fd, const struct timeval __tvp[2]),
+     __futimes64) __THROW;
+# else
+# define futimes __futimes64
+# endif
+#endif
 extern int futimes (int __fd, const struct timeval __tvp[2]) __THROW;
 #endif
 
diff --git a/time/time.h b/time/time.h
index 35012b9..1ff4bb8 100644
--- a/time/time.h
+++ b/time/time.h
@@ -73,16 +73,38 @@ __BEGIN_DECLS
 extern clock_t clock (void) __THROW;
 
 /* Return the current time and put it in *TIMER if TIMER is not NULL.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern time_t __REDIRECT (time, (time_t * __timer),
+     __time64) __THROW;
+# else
+# define time __time64
+# endif
+#endif
 extern time_t time (time_t *__timer) __THROW;
 
 /* Return the difference between TIME1 and TIME0.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern double __REDIRECT (difftime, (time_t __time1, time_t __time0),
+     __difftime64) __THROW;
+# else
+# define difftime __difftime64
+# endif
+#endif
 extern double difftime (time_t __time1, time_t __time0)
      __THROW __attribute__ ((__const__));
 
 /* Return the `time_t' representation of TP and normalize TP.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern time_t __REDIRECT (mktime, (struct tm *__tp), __mktime64) __THROW;
+# else
+# define mktime __mktime64
+# endif
+#endif
 extern time_t mktime (struct tm *__tp) __THROW;
 
-
 /* Format TP into S according to FORMAT.
    Write no more than MAXSIZE characters and return the number
    of characters written, or 0 if it would exceed MAXSIZE.  */
@@ -117,20 +139,52 @@ extern char *strptime_l (const char *__restrict __s,
 
 /* Return the `struct tm' representation of *TIMER
    in Universal Coordinated Time (aka Greenwich Mean Time).  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern struct tm * __REDIRECT (gmtime, (const time_t *__timer),
+       __gmtime64) __THROW;
+# else
+# define gmtime __gmtime64
+# endif
+#endif
 extern struct tm *gmtime (const time_t *__timer) __THROW;
 
 /* Return the `struct tm' representation
    of *TIMER in the local timezone.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern struct tm * __REDIRECT (localtime, (const time_t *__timer),
+       __localtime64) __THROW;
+# else
+# define localtime __localtime64
+# endif
+#endif
 extern struct tm *localtime (const time_t *__timer) __THROW;
 
 #ifdef __USE_POSIX
 /* Return the `struct tm' representation of *TIMER in UTC,
    using *TP to store the result.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern struct tm * __REDIRECT (gmtime_r, (const time_t *__restrict
+       __timer, struct tm *__restrict __tp), __gmtime64_r) __THROW;
+# else
+# define gmtime_r __gmtime64_r
+# endif
+#endif
 extern struct tm *gmtime_r (const time_t *__restrict __timer,
 			    struct tm *__restrict __tp) __THROW;
 
 /* Return the `struct tm' representation of *TIMER in local time,
    using *TP to store the result.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern struct tm * __REDIRECT (localtime_r, (const time_t *__restrict
+       __timer, struct tm *__restrict __tp), __localtime64_r) __THROW;
+# else
+# define localtime_r __localtime64_r
+# endif
+#endif
 extern struct tm *localtime_r (const time_t *__restrict __timer,
 			       struct tm *__restrict __tp) __THROW;
 #endif	/* POSIX */
@@ -140,6 +194,14 @@ extern struct tm *localtime_r (const time_t *__restrict __timer,
 extern char *asctime (const struct tm *__tp) __THROW;
 
 /* Equivalent to `asctime (localtime (timer))'.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern char * __REDIRECT (ctime, (const time_t *__timer),
+       __ctime64) __THROW;
+# else
+# define ctime __ctime64
+# endif
+#endif
 extern char *ctime (const time_t *__timer) __THROW;
 
 #ifdef __USE_POSIX
@@ -151,6 +213,14 @@ extern char *asctime_r (const struct tm *__restrict __tp,
 			char *__restrict __buf) __THROW;
 
 /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern char * __REDIRECT (ctime_r, (const time_t *__restrict __timer,
+       char *__restrict __buf), __ctime64_r) __THROW;
+# else
+# define ctime_r __ctime64_r
+# endif
+#endif
 extern char *ctime_r (const time_t *__restrict __timer,
 		      char *__restrict __buf) __THROW;
 #endif	/* POSIX */
@@ -179,6 +249,14 @@ extern long int timezone;
 #ifdef __USE_MISC
 /* Set the system time to *WHEN.
    This call is restricted to the superuser.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (stime, (const time_t *__when), __stime64)
+           __THROW;
+# else
+# define stime __stime64
+# endif
+#endif
 extern int stime (const time_t *__when) __THROW;
 #endif
 
@@ -194,9 +272,23 @@ extern int stime (const time_t *__when) __THROW;
    localtime package.  These are included only for compatibility.  */
 
 /* Like `mktime', but for TP represents Universal Time, not local time.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern time_t __REDIRECT (timegm, (struct tm *__tp), __timegm64) __THROW;
+# else
+# define timegm __timegm64
+# endif
+#endif
 extern time_t timegm (struct tm *__tp) __THROW;
 
 /* Another name for `mktime'.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern time_t __REDIRECT (timelocal, (struct tm *__tp), __timelocal64) __THROW;
+# else
+# define timelocal __timelocal64
+# endif
+#endif
 extern time_t timelocal (struct tm *__tp) __THROW;
 
 /* Return the number of days in YEAR.  */
@@ -209,17 +301,49 @@ extern int dysize (int __year) __THROW  __attribute__ ((__const__));
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#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
 extern int nanosleep (const struct timespec *__requested_time,
 		      struct timespec *__remaining);
 
 
 /* Get resolution of clock CLOCK_ID.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (clock_getres, (clockid_t __clock_id, struct
+     timespec *__res), __clock_getres64) __THROW;
+# else
+# define clock_getres __clock_getres64
+# endif
+#endif
 extern int clock_getres (clockid_t __clock_id, struct timespec *__res) __THROW;
 
 /* Get current value of clock CLOCK_ID and store it in TP.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (clock_gettime, (clockid_t __clock_id, struct
+     timespec *__tp), __clock_gettime64) __THROW;
+# else
+# define clock_gettime __clock_gettime64
+# endif
+#endif
 extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
 
 /* Set clock CLOCK_ID to value TP.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (clock_settime, (clockid_t __clock_id, const struct
+     timespec *__tp), __clock_settime64) __THROW;
+# else
+# define clock_settime __clock_settime64
+# endif
+#endif
 extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp)
      __THROW;
 
@@ -228,6 +352,15 @@ extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp)
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#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_nanosleep64) __THROW;
+# else
+# define clock_nanosleep __clock_nanosleep64
+# endif
+#endif
 extern int clock_nanosleep (clockid_t __clock_id, int __flags,
 			    const struct timespec *__req,
 			    struct timespec *__rem);
@@ -246,11 +379,29 @@ extern int timer_create (clockid_t __clock_id,
 extern int timer_delete (timer_t __timerid) __THROW;
 
 /* Set timer TIMERID to VALUE, returning old value in OVALUE.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (timer_settime, (timer_t __timerid, int __flags,
+			  const struct itimerspec *__restrict __value,
+			  struct itimerspec *__restrict __ovalue),
+                          __timer_settime64) __THROW;
+# else
+# define timer_settime __timer_settime64
+# endif
+#endif
 extern int timer_settime (timer_t __timerid, int __flags,
 			  const struct itimerspec *__restrict __value,
 			  struct itimerspec *__restrict __ovalue) __THROW;
 
 /* Get current value of timer TIMERID and store it in VALUE.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (timer_gettime, (timer_t __timerid, struct
+     itimerspec *__value), __timer_gettime64) __THROW __nonnull ((1));
+# else
+# define timer_gettime __timer_gettime64
+# endif
+#endif
 extern int timer_gettime (timer_t __timerid, struct itimerspec *__value)
      __THROW;
 
@@ -261,6 +412,14 @@ extern int timer_getoverrun (timer_t __timerid) __THROW;
 
 #ifdef __USE_ISOC11
 /* Set TS to calendar time based in time base BASE.  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern int __REDIRECT (timespec_get, (struct timespec *__ts, int __base),
+     __timespec_get64) __THROW __nonnull ((1));
+# else
+# define timespec_get __timespec_get64
+# endif
+#endif
 extern int timespec_get (struct timespec *__ts, int __base)
      __THROW __nonnull ((1));
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7b7fa19fd8506e90bf2920603855130052a74bbc

commit 7b7fa19fd8506e90bf2920603855130052a74bbc
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Thu Apr 12 20:50:21 2018 +0200

    Y2038: add function __pmap_rmtcall64

diff --git a/sunrpc/pmap_rmt.c b/sunrpc/pmap_rmt.c
index 6b142e5..501da4f 100644
--- a/sunrpc/pmap_rmt.c
+++ b/sunrpc/pmap_rmt.c
@@ -390,3 +390,26 @@ done_broad:
   return stat;
 }
 libc_hidden_nolink_sunrpc (clnt_broadcast, GLIBC_2_0)
+
+/* 64-bit-time version */
+
+/* The 64-bit-time version of pmap_rmtcall.
+ * Only handles 64-bit-time timeouts smaller than 2^^31 seconds.
+ */
+enum clnt_stat
+__pmap_rmtcall64 (struct sockaddr_in *addr, u_long prog, u_long vers,
+		  u_long proc, xdrproc_t xdrargs, caddr_t argsp,
+		  xdrproc_t xdrres, caddr_t resp,
+		  struct __timeval64 tout, u_long *port_ptr)
+{
+  struct timeval tout32;
+  if (tout.tv_sec > INT_MAX)
+  {
+    return RPC_SYSTEMERROR;
+  }
+  tout32.tv_sec = tout.tv_sec;
+  tout32.tv_usec = tout.tv_usec;
+  
+  return pmap_rmtcall (addr, prog, vers, proc, xdrargs, argsp, xdrres,
+                       resp, tout32, port_ptr);
+}
diff --git a/sunrpc/rpc/pmap_clnt.h b/sunrpc/rpc/pmap_clnt.h
index 1cc94b8..b436ebb 100644
--- a/sunrpc/rpc/pmap_clnt.h
+++ b/sunrpc/rpc/pmap_clnt.h
@@ -71,6 +71,21 @@ extern bool_t pmap_set (const u_long __program, const u_long __vers,
 extern bool_t pmap_unset (const u_long __program, const u_long __vers)
      __THROW;
 extern struct pmaplist *pmap_getmaps (struct sockaddr_in *__address) __THROW;
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern enum clnt_stat __REDIRECT (pmap_rmtcall, (struct sockaddr_in *__addr,
+                                                 const u_long __prog,
+                                                 const u_long __vers,
+                                                 const u_long __proc,
+                                                 xdrproc_t __xdrargs,
+                                                 caddr_t __argsp, xdrproc_t __xdrres,
+                                                 caddr_t __resp, struct timeval __tout,
+                                                 u_long *__port_ptr),
+                                  __pmap_rmtcall64) __THROW;
+# else
+# define pmap_rmtcall __pmap_rmtcall64
+# endif
+#endif
 extern enum clnt_stat pmap_rmtcall (struct sockaddr_in *__addr,
 				    const u_long __prog,
 				    const u_long __vers,

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=811c3e9e66cc3ffba591327e70a7bca240bccddb

commit 811c3e9e66cc3ffba591327e70a7bca240bccddb
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Thu Apr 12 20:49:49 2018 +0200

    Y2038: add function __clntudp_bufcreate64

diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
index 27a3244..0892ae3 100644
--- a/sunrpc/clnt_udp.c
+++ b/sunrpc/clnt_udp.c
@@ -663,3 +663,21 @@ __clntudp_create64 (struct sockaddr_in *raddr, u_long program, u_long version,
 
   return clntudp_create (raddr, program, version, wait32, sockp);
 }
+
+CLIENT *
+__clntudp_bufcreate64 (struct sockaddr_in *raddr, u_long program, u_long version,
+		       struct __timeval64 wait, int *sockp, u_int sendsz,
+		       u_int recvsz)
+{
+  struct timeval wait32;
+
+  if (wait.tv_sec > INT_MAX)
+  {
+    return NULL;
+  }
+
+  wait32.tv_sec = wait.tv_sec;
+  wait32.tv_usec = wait.tv_usec;
+
+  return clntudp_bufcreate (raddr, program, version, wait32, sockp, sendsz, recvsz);
+}
diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h
index b24b5cc..a6dff89 100644
--- a/sunrpc/rpc/clnt.h
+++ b/sunrpc/rpc/clnt.h
@@ -344,6 +344,18 @@ extern CLIENT * __REDIRECT (clntudp_create,(struct sockaddr_in *__raddr,
 extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, u_long __program,
 			       u_long __version, struct timeval __wait_resend,
 			       int *__sockp) __THROW;
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern CLIENT * __REDIRECT (clntudp_bufcreate,(struct sockaddr_in *__raddr,
+				               u_long __program, u_long __version,
+				               struct __timeval64 __wait_resend,
+					       int *__sockp, u_int __sendsz,
+					       u_int __recvsz),
+                            __clntudp_bufcreate64) __THROW;
+# else
+# define clntudp_bufcreate __clntudp_bufcreate64
+# endif
+#endif
 extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr,
 				  u_long __program, u_long __version,
 				  struct timeval __wait_resend, int *__sockp,

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f13c0a3681ebfa7a2200a910059bb03f20051793

commit f13c0a3681ebfa7a2200a910059bb03f20051793
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Thu Apr 12 20:46:27 2018 +0200

    Y2038: add function __clntudp_create64

diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
index c2436e3..27a3244 100644
--- a/sunrpc/clnt_udp.c
+++ b/sunrpc/clnt_udp.c
@@ -644,3 +644,22 @@ clntudp_destroy (CLIENT *cl)
   mem_free ((caddr_t) cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));
   mem_free ((caddr_t) cl, sizeof (CLIENT));
 }
+
+/* 64-bit time versions */
+
+CLIENT *
+__clntudp_create64 (struct sockaddr_in *raddr, u_long program, u_long version,
+		    struct __timeval64 wait, int *sockp)
+{
+  struct timeval wait32;
+
+  if (wait.tv_sec > INT32_MAX || wait.tv_sec < INT32_MIN)
+  {
+    return NULL;
+  }  
+
+  wait32.tv_sec = wait.tv_sec;
+  wait32.tv_usec = wait.tv_usec;
+
+  return clntudp_create (raddr, program, version, wait32, sockp);
+}
diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h
index f4d4a94..b24b5cc 100644
--- a/sunrpc/rpc/clnt.h
+++ b/sunrpc/rpc/clnt.h
@@ -329,6 +329,18 @@ extern CLIENT *clnttcp_create (struct sockaddr_in *__raddr, u_long __prog,
  *	u_int sendsz;
  *	u_int recvsz;
  */
+#ifdef __USE_TIME_BITS64
+# if defined(__REDIRECT)
+extern CLIENT * __REDIRECT (clntudp_create,(struct sockaddr_in *__raddr,
+                                            u_long __program,
+					    u_long __version,
+					    struct timeval __wait_resend,
+					    int *__sockp),
+                            __clntudp_create64) __THROW;
+# else
+# define clntudp_create __clntudp_create64
+# endif
+#endif
 extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, u_long __program,
 			       u_long __version, struct timeval __wait_resend,
 			       int *__sockp) __THROW;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=726618aeb3d16b51a3cb101128c774136714bbea

commit 726618aeb3d16b51a3cb101128c774136714bbea
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 19:49:07 2017 +0200

    Y2038: add function select64

diff --git a/include/sys/select.h b/include/sys/select.h
index ba013a3..9c58a15 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -22,5 +22,10 @@ extern int __pselect64 (int __nfds, fd_set *__readfds,
 			const struct __timespec64 *__timeout,
 			const __sigset_t *__sigmask);
 
+extern int __select64 (int __nfds, fd_set *__restrict __readfds,
+		       fd_set *__restrict __writefds,
+		       fd_set *__restrict __exceptfds,
+		       struct __timeval64 *__restrict __timeout);
+
 #endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index e4124a1..ba17746 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -21,6 +21,7 @@
 #include <sys/select.h>
 #include <errno.h>
 #include <sysdep-cancel.h>
+#include <y2038-support.h>
 
 /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
    readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
@@ -69,3 +70,73 @@ libc_hidden_def (__select)
 
 weak_alias (__select, select)
 weak_alias (__select, __libc_select)
+
+/* 64-bit time version */
+
+int
+__select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+	      struct __timeval64 *timeout)
+{
+#ifdef __NR_select
+  struct timeval tval32, *timeout32 = NULL;
+#else
+  int result;
+  struct timespec ts32, *tsp32 = NULL;
+#endif
+
+#ifdef __NR_pselect6_time64
+  int res;
+  if (__y2038_linux_support > 0)
+  {
+    res = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
+			  exceptfds, timeout, NULL);
+    if (res == 0 || errno != ENOSYS)
+      return res;
+    __y2038_linux_support = -1;
+  }
+#endif
+
+#ifdef __NR_select
+  if (timeout != NULL)
+    {
+      if (timeout->tv_sec > INT_MAX)
+      {
+        errno = EOVERFLOW;
+        return -1;
+      }
+      tval32.tv_sec = timeout->tv_sec;
+      tval32.tv_usec = timeout->tv_usec;
+      timeout32 = &tval32;
+    }
+
+  return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds,
+			 timeout32);
+#else
+  if (timeout)
+    {
+      if (timeout->tv_sec > INT_MAX)
+      {
+        errno = EOVERFLOW;
+        return -1;
+      }
+      ts32.tv_sec = timeout->tv_sec;
+      ts32.tv_nsec = timeout->tv_usec * 1000;
+      tsp32 = &ts32;
+    }
+
+  result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp32,
+			   NULL);
+
+  if (timeout)
+    {
+      /* Linux by default will update the timeout after a pselect6 syscall
+         (though the pselect() glibc call suppresses this behavior).
+         Since select() on Linux has the same behavior as the pselect6
+         syscall, we update the timeout here.  */
+      timeout->tv_sec = ts32.tv_sec;
+      timeout->tv_usec = ts32.tv_nsec / 1000;
+    }
+
+  return result;
+#endif
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=461e9a4bd975432465f1d20e1f480a4edebdb6e9

commit 461e9a4bd975432465f1d20e1f480a4edebdb6e9
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:16 2017 +0200

    Y2038: add function pselect64

diff --git a/include/sys/select.h b/include/sys/select.h
index 07bb49b..ba013a3 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -3,6 +3,7 @@
 
 #ifndef _ISOMAC
 /* Now define the internal interfaces.  */
+
 extern int __pselect (int __nfds, fd_set *__readfds,
 		      fd_set *__writefds, fd_set *__exceptfds,
 		      const struct timespec *__timeout,
@@ -14,5 +15,12 @@ extern int __select (int __nfds, fd_set *__restrict __readfds,
 		     struct timeval *__restrict __timeout);
 libc_hidden_proto (__select)
 
+/* 64-bit time version */
+
+extern int __pselect64 (int __nfds, fd_set *__readfds,
+			fd_set *__writefds, fd_set *__exceptfds,
+			const struct __timespec64 *__timeout,
+			const __sigset_t *__sigmask);
+
 #endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index 2b052e7..8a77036 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -22,6 +22,7 @@
 #include <sys/poll.h>
 #include <kernel-features.h>
 #include <sysdep-cancel.h>
+#include <y2038-support.h>
 
 
 #ifdef __NR_pselect6
@@ -79,6 +80,71 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 }
 weak_alias (__pselect, pselect)
 
+/* 64-bit time version */
+
+int
+__pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+	       const struct __timespec64 *timeout, const sigset_t *sigmask)
+{
+  struct timespec tval32, *timeout32 = NULL;
+
+  /* Note: the system call expects 7 values but on most architectures
+     we can only pass in 6 directly.  If there is an architecture with
+     support for more parameters a new version of this file needs to
+     be created.  */
+  struct
+  {
+    __syscall_ulong_t ss;
+    __syscall_ulong_t ss_len;
+  } data;
+
+  data.ss = (__syscall_ulong_t) (uintptr_t) sigmask;
+  data.ss_len = _NSIG / 8;
+
+  int result;
+
+#ifdef __NR_pselect6_time64
+  if (__y2038_linux_support > 0)
+  {
+    result = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds,
+			     exceptfds, timeout, &data);
+    if (result == 0 || errno != ENOSYS)
+      return result;
+    __y2038_linux_support = -1;
+  }
+#endif
+
+  /* The Linux kernel can in some situations update the timeout value.
+     We do not want that so use a local variable.  */
+  if (timeout != NULL)
+    {
+      if (timeout->tv_sec > INT_MAX)
+      {
+        errno = EOVERFLOW;
+        return -1;
+      }
+      tval32.tv_sec = timeout->tv_sec;
+      tval32.tv_nsec = timeout->tv_nsec;
+      timeout32 = &tval32;
+    }
+
+#ifndef CALL_PSELECT6
+# define CALL_PSELECT6(nfds, readfds, writefds, exceptfds, timeout, data) \
+  SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,	timeout32, data)
+#endif
+
+  result = CALL_PSELECT6 (nfds, readfds, writefds, exceptfds, timeout32,
+			  &data);
+
+# ifndef __ASSUME_PSELECT
+  if (result == -1 && errno == ENOSYS)
+    result = __generic_pselect (nfds, readfds, writefds, exceptfds, timeout32,
+				sigmask);
+# endif
+
+  return result;
+}
+
 # ifndef __ASSUME_PSELECT
 #  define __pselect static __generic_pselect
 # endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=656b2615839380c4aac97d423d5bcd51dfcf1f21

commit 656b2615839380c4aac97d423d5bcd51dfcf1f21
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:15 2017 +0200

    Y2038: add struct __timex64

diff --git a/include/time.h b/include/time.h
index 70af625..90940dd 100644
--- a/include/time.h
+++ b/include/time.h
@@ -4,6 +4,7 @@
 #ifndef _ISOMAC
 # include <bits/types/locale_t.h>
 # include <bits/types/struct___timespec64.h>
+# include <bits/types/struct___timeval64.h>
 # include <stdbool.h>
 
 extern __typeof (strftime_l) __strftime_l;
@@ -18,6 +19,37 @@ libc_hidden_proto (localtime)
 libc_hidden_proto (strftime)
 libc_hidden_proto (strptime)
 
+/* 64-bit time version of the current struct timex */
+struct __timex64
+{
+  unsigned int modes;		/* mode selector */
+  __syscall_slong_t offset;	/* time offset (usec) */
+  __syscall_slong_t freq;	/* frequency offset (scaled ppm) */
+  __syscall_slong_t maxerror;	/* maximum error (usec) */
+  __syscall_slong_t esterror;	/* estimated error (usec) */
+  int status;			/* clock command/status */
+  __syscall_slong_t constant;	/* pll time constant */
+  __syscall_slong_t precision;	/* clock precision (usec) (ro) */
+  __syscall_slong_t tolerance;	/* clock frequency tolerance (ppm) (ro) */
+  struct __timeval64 time;	/* (read only, except for ADJ_SETOFFSET) */
+  __syscall_slong_t tick;	/* (modified) usecs between clock ticks */
+  __syscall_slong_t ppsfreq;	/* pps frequency (scaled ppm) (ro) */
+  __syscall_slong_t jitter;	/* pps jitter (us) (ro) */
+  int shift;			/* interval duration (s) (shift) (ro) */
+  __syscall_slong_t stabil;	/* pps stability (scaled ppm) (ro) */
+  __syscall_slong_t jitcnt;	/* jitter limit exceeded (ro) */
+  __syscall_slong_t calcnt;	/* calibration intervals (ro) */
+  __syscall_slong_t errcnt;	/* calibration errors (ro) */
+  __syscall_slong_t 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;
+};
+
 extern __typeof (clock_getres) __clock_getres;
 extern __typeof (clock_gettime) __clock_gettime;
 libc_hidden_proto (__clock_gettime)
diff --git a/time/Makefile b/time/Makefile
index a502c8d..d054bb9 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -28,6 +28,8 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 	   bits/types/struct_timespec.h bits/types/struct_timeval.h	\
 	   bits/types/struct_tm.h bits/types/timer_t.h			\
 	   bits/types/time_t.h						\
+	   bits/types/struct_timespec64.h>				\
+	   bits/types/struct_timeval64.h>				\
 
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=68f8e342b37c5e09759664833b75fa5ba776e1ec

commit 68f8e342b37c5e09759664833b75fa5ba776e1ec
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:14 2017 +0200

    Y2038: add function __ntp_gettimex64

diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 07a36e8..955d158 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -171,6 +171,7 @@ libc {
     mlock2;
     pkey_alloc; pkey_free; pkey_set; pkey_get; pkey_mprotect;
     __ntp_gettime64;
+    __ntp_gettimex64;
   }
   GLIBC_PRIVATE {
     # functions used in other libraries
diff --git a/sysdeps/unix/sysv/linux/ntp_gettimex.c b/sysdeps/unix/sysv/linux/ntp_gettimex.c
index e491549..abd1c7e 100644
--- a/sysdeps/unix/sysv/linux/ntp_gettimex.c
+++ b/sysdeps/unix/sysv/linux/ntp_gettimex.c
@@ -16,6 +16,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sys/timex.h>
+#include <include/time.h>
 
 #ifndef MOD_OFFSET
 # define modes mode
@@ -40,3 +41,26 @@ ntp_gettimex (struct ntptimeval *ntv)
   ntv->__glibc_reserved4 = 0;
   return result;
 }
+
+/* The 64-bit-time version */
+
+int
+__ntp_gettimex64 (struct __ntptimeval64 *ntv)
+{
+  struct timex tntx;
+  int result;
+
+  tntx.modes = 0;
+  result = __adjtimex (&tntx);
+  ntv->time.tv_sec = tntx.time.tv_sec;
+  ntv->time.tv_usec = tntx.time.tv_usec;
+  ntv->maxerror = tntx.maxerror;
+  ntv->maxerror = tntx.maxerror;
+  ntv->esterror = tntx.esterror;
+  ntv->tai = tntx.tai;
+  ntv->__glibc_reserved1 = 0;
+  ntv->__glibc_reserved2 = 0;
+  ntv->__glibc_reserved3 = 0;
+  ntv->__glibc_reserved4 = 0;
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a098096e0915a33a13ef2c9e8c70856e80112c83

commit a098096e0915a33a13ef2c9e8c70856e80112c83
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:13 2017 +0200

    Y2038: add function __ntp_gettime64

diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 336c13b..07a36e8 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -170,6 +170,7 @@ libc {
     memfd_create;
     mlock2;
     pkey_alloc; pkey_free; pkey_set; pkey_get; pkey_mprotect;
+    __ntp_gettime64;
   }
   GLIBC_PRIVATE {
     # functions used in other libraries
diff --git a/sysdeps/unix/sysv/linux/ntp_gettime.c b/sysdeps/unix/sysv/linux/ntp_gettime.c
index 18650da..f025263 100644
--- a/sysdeps/unix/sysv/linux/ntp_gettime.c
+++ b/sysdeps/unix/sysv/linux/ntp_gettime.c
@@ -18,6 +18,7 @@
 #define ntp_gettime ntp_gettime_redirect
 
 #include <sys/timex.h>
+#include <include/time.h>
 
 #undef ntp_gettime
 
@@ -39,3 +40,20 @@ ntp_gettime (struct ntptimeval *ntv)
   ntv->esterror = tntx.esterror;
   return result;
 }
+
+/* The 64-bit-time version */
+
+int
+__ntp_gettime64 (struct __ntptimeval64 *ntv)
+{
+  struct timex tntx;
+  int result;
+
+  tntx.modes = 0;
+  result = __adjtimex (&tntx);
+  ntv->time.tv_sec = tntx.time.tv_sec;
+  ntv->time.tv_usec = tntx.time.tv_usec;
+  ntv->maxerror = tntx.maxerror;
+  ntv->esterror = tntx.esterror;
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7ea0b6a9467e3f50725c882eeb753e4af75376f2

commit 7ea0b6a9467e3f50725c882eeb753e4af75376f2
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:12 2017 +0200

    Y2038: add struct __ntp_timeval64

diff --git a/sysdeps/unix/sysv/linux/sys/timex.h b/sysdeps/unix/sysv/linux/sys/timex.h
index 0d652c8..fd45929 100644
--- a/sysdeps/unix/sysv/linux/sys/timex.h
+++ b/sysdeps/unix/sysv/linux/sys/timex.h
@@ -40,6 +40,19 @@ struct ntptimeval
   long int __glibc_reserved4;
 };
 
+struct __ntptimeval64
+{
+  struct __timeval64 time;	/* current time (ro) */
+  long int maxerror;	/* maximum error (us) (ro) */
+  long int esterror;	/* estimated error (us) (ro) */
+  long int tai;		/* TAI offset (ro) */
+
+  long int __glibc_reserved1;
+  long int __glibc_reserved2;
+  long int __glibc_reserved3;
+  long int __glibc_reserved4;
+};
+
 /* Clock states (time_state) */
 #define TIME_OK		0	/* clock synchronized, no leap second */
 #define TIME_INS	1	/* insert leap second */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=98de2d89b12f166c8bfbd1d5a3845c54de7f2fb4

commit 98de2d89b12f166c8bfbd1d5a3845c54de7f2fb4
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:11 2017 +0200

    Y2038: add function __getrusage64

diff --git a/resource/Makefile b/resource/Makefile
index bf66294..c482e82 100644
--- a/resource/Makefile
+++ b/resource/Makefile
@@ -23,7 +23,7 @@ headers	  := sys/resource.h bits/resource.h sys/vlimit.h sys/vtimes.h	\
 	     ulimit.h bits/types/struct_rusage.h
 
 routines := getrlimit setrlimit getrlimit64 setrlimit64 getrusage ulimit      \
-	    vlimit vtimes getpriority setpriority nice
+	    vlimit vtimes getpriority setpriority nice getrusage64
 
 tests = tst-getrlimit bug-ulimit1
 
diff --git a/resource/Versions b/resource/Versions
index d6c2cce..a45e684 100644
--- a/resource/Versions
+++ b/resource/Versions
@@ -22,6 +22,9 @@ libc {
     # s*
     setrlimit64;
   }
+  GLIBC_2.29 {
+    __getrusage64;
+  }
   GLIBC_PRIVATE {
     __getrlimit;
   }
diff --git a/resource/getrusage64.c b/resource/getrusage64.c
new file mode 100644
index 0000000..f7edb97
--- /dev/null
+++ b/resource/getrusage64.c
@@ -0,0 +1,181 @@
+/* Return resource usage for the current process.
+   
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/resource.h>
+#include <include/time.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+/* Structure which says how much of each resource has been used.  */
+/* 64-bit time version */
+/* The purpose of all the unions is to have the kernel-compatible layout
+   while keeping the API type as 'long int', and among machines where
+   __syscall_slong_t is not 'long int', this only does the right thing
+   for little-endian ones, like x32.  */
+struct __rusage64
+  {
+    /* Total amount of user time used.  */
+    struct __timeval64 ru_utime;
+    /* Total amount of system time used.  */
+    struct __timeval64 ru_stime;
+    /* Maximum resident set size (in kilobytes).  */
+    __extension__ union
+      {
+	long int ru_maxrss;
+	__syscall_slong_t __ru_maxrss_word;
+      };
+    /* Amount of sharing of text segment memory
+       with other processes (kilobyte-seconds).  */
+    /* Maximum resident set size (in kilobytes).  */
+    __extension__ union
+      {
+	long int ru_ixrss;
+	__syscall_slong_t __ru_ixrss_word;
+      };
+    /* Amount of data segment memory used (kilobyte-seconds).  */
+    __extension__ union
+      {
+	long int ru_idrss;
+	__syscall_slong_t __ru_idrss_word;
+      };
+    /* Amount of stack memory used (kilobyte-seconds).  */
+    __extension__ union
+      {
+	long int ru_isrss;
+	 __syscall_slong_t __ru_isrss_word;
+      };
+    /* Number of soft page faults (i.e. those serviced by reclaiming
+       a page from the list of pages awaiting reallocation.  */
+    __extension__ union
+      {
+	long int ru_minflt;
+	__syscall_slong_t __ru_minflt_word;
+      };
+    /* Number of hard page faults (i.e. those that required I/O).  */
+    __extension__ union
+      {
+	long int ru_majflt;
+	__syscall_slong_t __ru_majflt_word;
+      };
+    /* Number of times a process was swapped out of physical memory.  */
+    __extension__ union
+      {
+	long int ru_nswap;
+	__syscall_slong_t __ru_nswap_word;
+      };
+    /* Number of input operations via the file system.  Note: This
+       and `ru_oublock' do not include operations with the cache.  */
+    __extension__ union
+      {
+	long int ru_inblock;
+	__syscall_slong_t __ru_inblock_word;
+      };
+    /* Number of output operations via the file system.  */
+    __extension__ union
+      {
+	long int ru_oublock;
+	__syscall_slong_t __ru_oublock_word;
+      };
+    /* Number of IPC messages sent.  */
+    __extension__ union
+      {
+	long int ru_msgsnd;
+	__syscall_slong_t __ru_msgsnd_word;
+      };
+    /* Number of IPC messages received.  */
+    __extension__ union
+      {
+	long int ru_msgrcv;
+	__syscall_slong_t __ru_msgrcv_word;
+      };
+    /* Number of signals delivered.  */
+    __extension__ union
+      {
+	long int ru_nsignals;
+	__syscall_slong_t __ru_nsignals_word;
+      };
+    /* Number of voluntary context switches, i.e. because the process
+       gave up the process before it had to (usually to wait for some
+       resource to be available).  */
+    __extension__ union
+      {
+	long int ru_nvcsw;
+	__syscall_slong_t __ru_nvcsw_word;
+      };
+    /* Number of involuntary context switches, i.e. a higher priority process
+       became runnable or the current process used up its time slice.  */
+    __extension__ union
+      {
+	long int ru_nivcsw;
+	__syscall_slong_t __ru_nivcsw_word;
+      };
+  };
+
+int __getrusage64 (__rusage_who_t __who, struct __rusage64 *__usage)
+{
+  int result;
+  struct rusage usage32;
+
+  result = INLINE_SYSCALL(getrusage, 2, __who, &usage32);
+  /* Copy fields from 32-bit into 64-bit rusage structure */
+  /* Total amount of user time used.  */
+  __usage->ru_utime.tv_sec = usage32.ru_utime.tv_sec;
+  __usage->ru_utime.tv_usec = usage32.ru_utime.tv_usec;
+  /* Total amount of system time used.  */
+  __usage->ru_stime.tv_sec = usage32.ru_stime.tv_sec;
+  __usage->ru_stime.tv_usec = usage32.ru_stime.tv_usec;
+  /* Maximum resident set size (in kilobytes).  */
+  __usage->ru_maxrss = usage32.ru_maxrss;
+  /* Amount of sharing of text segment memory
+     with other processes (kilobyte-seconds).  */
+  /* Maximum resident set size (in kilobytes).  */
+  __usage->ru_ixrss = usage32.ru_ixrss;
+  /* Amount of data segment memory used (kilobyte-seconds).  */
+  __usage->ru_idrss = usage32.ru_idrss;
+  /* Amount of stack memory used (kilobyte-seconds).  */
+  __usage->ru_isrss = usage32.ru_isrss;
+  /* Number of soft page faults (i.e. those serviced by reclaiming
+     a page from the list of pages awaiting reallocation.  */
+  __usage->ru_minflt = usage32.ru_minflt;
+  /* Number of hard page faults (i.e. those that required I/O).  */
+  __usage->ru_majflt = usage32.ru_majflt;
+  /* Number of times a process was swapped out of physical memory.  */
+  __usage->ru_nswap = usage32.ru_nswap;
+  /* Number of input operations via the file system.  Note: This
+     and `ru_oublock' do not include operations with the cache.  */
+  __usage->ru_inblock = usage32.ru_inblock;
+  /* Number of output operations via the file system.  */
+  __usage->ru_oublock = usage32.ru_oublock;
+  /* Number of IPC messages sent.  */
+  __usage->ru_msgsnd = usage32.ru_msgsnd;
+  /* Number of IPC messages received.  */
+  __usage->ru_msgrcv = usage32.ru_msgrcv;
+  /* Number of signals delivered.  */
+  __usage->ru_nsignals = usage32.ru_nsignals;
+  /* Number of voluntary context switches, i.e. because the process
+     gave up the process before it had to (usually to wait for some
+     resource to be available).  */
+  __usage->ru_nvcsw = usage32.ru_nvcsw;
+  /* Number of involuntary context switches, i.e. a higher priority process
+     became runnable or the current process used up its time slice.  */
+  __usage->ru_nivcsw = usage32.ru_nivcsw;
+
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=573399ac6152de12e71feb52272f6ac9e194598d

commit 573399ac6152de12e71feb52272f6ac9e194598d
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:10 2017 +0200

    Y2038: add functions using futexes
    
    This creates 64-bit time versions of the following APIs:
    - pthread_rwlock_timedrdlock
    - pthread_rwlock_timedwrlock
    - pthread_mutex_timedlock
    - pthread_cond_timedwait
    - sem_timedwait
    - aio_suspend
    
    It also creates 64-bit time versions of the following
    functions or macros:
    - lll_timedlock_elision
    - lll_timedlock
    - __lll_timedlock_wait
    - futex_reltimed_wait_cancelable
    - lll_futex_timed_wait
    - __pthread_cond_wait_common
    - futex_abstimed_wait_cancelable
    - lll_futex_timed_wait_bitset
    - do_aio_misc_wait
    - AIO_MISC_WAIT
    - __new_sem_wait_slow
    - do_futex_wait
    - __pthread_rwlock_wrlock_full
    - __pthread_rwlock_rdlock_full
    - futex_abstimed_wait

diff --git a/nptl/Versions b/nptl/Versions
index e7f691d..a205706 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -269,6 +269,7 @@ libpthread {
   GLIBC_2.22 {
   }
 
+<<<<<<< HEAD
   # C11 thread symbols.
   GLIBC_2.28 {
     thrd_create; thrd_detach; thrd_exit; thrd_join;
@@ -277,6 +278,14 @@ libpthread {
     cnd_timedwait; cnd_wait; tss_create; tss_delete; tss_get; tss_set;
   }
 
+  GLIBC_2.29 {
+    __pthread_rwlock_rdlock64;
+    __pthread_rwlock_wrlock64;
+    __pthread_mutex_timedlock64;
+    __sem_timedwait64;
+    __pthread_cond_timedwait64;
+  }
+
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
     __pthread_clock_gettime; __pthread_clock_settime;
diff --git a/nptl/lll_timedlock_wait.c b/nptl/lll_timedlock_wait.c
index 91bf963..6d3aecb 100644
--- a/nptl/lll_timedlock_wait.c
+++ b/nptl/lll_timedlock_wait.c
@@ -57,3 +57,40 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
 
   return 0;
 }
+
+/* 64-bit time version */
+
+int
+__lll_timedlock_wait64 (int *futex, const struct __timespec64 *abstime, int private)
+{
+  /* Reject invalid timeouts.  */
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  /* Try locking.  */
+  while (atomic_exchange_acq (futex, 2) != 0)
+    {
+      struct timeval tv;
+
+      /* Get the current time.  */
+      (void) __gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      struct timespec rt;
+      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (rt.tv_nsec < 0)
+        {
+          rt.tv_nsec += 1000000000;
+          --rt.tv_sec;
+        }
+
+      if (rt.tv_sec < 0)
+        return ETIMEDOUT;
+
+      /* If *futex == 2, wait until woken or timeout.  */
+      lll_futex_timed_wait (futex, 2, &rt, private);
+    }
+
+  return 0;
+}
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index ebf07ca..072375c 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -647,6 +647,280 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
   return (err != 0) ? err : result;
 }
 
+/* 64-bit time variant */
+
+static __always_inline int
+__pthread_cond_wait_common64 (pthread_cond_t *cond, pthread_mutex_t *mutex,
+    const struct __timespec64 *abstime)
+{
+  const int maxspin = 0;
+  int err;
+  int result = 0;
+
+  LIBC_PROBE (cond_wait, 2, cond, mutex);
+
+  /* Acquire a position (SEQ) in the waiter sequence (WSEQ).  We use an
+     atomic operation because signals and broadcasts may update the group
+     switch without acquiring the mutex.  We do not need release MO here
+     because we do not need to establish any happens-before relation with
+     signalers (see __pthread_cond_signal); modification order alone
+     establishes a total order of waiters/signals.  We do need acquire MO
+     to synchronize with group reinitialization in
+     __condvar_quiesce_and_switch_g1.  */
+  uint64_t wseq = __condvar_fetch_add_wseq_acquire (cond, 2);
+  /* Find our group's index.  We always go into what was G2 when we acquired
+     our position.  */
+  unsigned int g = wseq & 1;
+  uint64_t seq = wseq >> 1;
+
+  /* Increase the waiter reference count.  Relaxed MO is sufficient because
+     we only need to synchronize when decrementing the reference count.  */
+  unsigned int flags = atomic_fetch_add_relaxed (&cond->__data.__wrefs, 8);
+  int private = __condvar_get_private (flags);
+
+  /* Now that we are registered as a waiter, we can release the mutex.
+     Waiting on the condvar must be atomic with releasing the mutex, so if
+     the mutex is used to establish a happens-before relation with any
+     signaler, the waiter must be visible to the latter; thus, we release the
+     mutex after registering as waiter.
+     If releasing the mutex fails, we just cancel our registration as a
+     waiter and confirm that we have woken up.  */
+  err = __pthread_mutex_unlock_usercnt (mutex, 0);
+  if (__glibc_unlikely (err != 0))
+    {
+      __condvar_cancel_waiting (cond, seq, g, private);
+      __condvar_confirm_wakeup (cond, private);
+      return err;
+    }
+
+  /* Now wait until a signal is available in our group or it is closed.
+     Acquire MO so that if we observe a value of zero written after group
+     switching in __condvar_quiesce_and_switch_g1, we synchronize with that
+     store and will see the prior update of __g1_start done while switching
+     groups too.  */
+  unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
+
+  do
+    {
+      while (1)
+	{
+	  /* Spin-wait first.
+	     Note that spinning first without checking whether a timeout
+	     passed might lead to what looks like a spurious wake-up even
+	     though we should return ETIMEDOUT (e.g., if the caller provides
+	     an absolute timeout that is clearly in the past).  However,
+	     (1) spurious wake-ups are allowed, (2) it seems unlikely that a
+	     user will (ab)use pthread_cond_wait as a check for whether a
+	     point in time is in the past, and (3) spinning first without
+	     having to compare against the current time seems to be the right
+	     choice from a performance perspective for most use cases.  */
+	  unsigned int spin = maxspin;
+	  while (signals == 0 && spin > 0)
+	    {
+	      /* Check that we are not spinning on a group that's already
+		 closed.  */
+	      if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))
+		goto done;
+
+	      /* TODO Back off.  */
+
+	      /* Reload signals.  See above for MO.  */
+	      signals = atomic_load_acquire (cond->__data.__g_signals + g);
+	      spin--;
+	    }
+
+	  /* If our group will be closed as indicated by the flag on signals,
+	     don't bother grabbing a signal.  */
+	  if (signals & 1)
+	    goto done;
+
+	  /* If there is an available signal, don't block.  */
+	  if (signals != 0)
+	    break;
+
+	  /* No signals available after spinning, so prepare to block.
+	     We first acquire a group reference and use acquire MO for that so
+	     that we synchronize with the dummy read-modify-write in
+	     __condvar_quiesce_and_switch_g1 if we read from that.  In turn,
+	     in this case this will make us see the closed flag on __g_signals
+	     that designates a concurrent attempt to reuse the group's slot.
+	     We use acquire MO for the __g_signals check to make the
+	     __g1_start check work (see spinning above).
+	     Note that the group reference acquisition will not mask the
+	     release MO when decrementing the reference count because we use
+	     an atomic read-modify-write operation and thus extend the release
+	     sequence.  */
+	  atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
+	  if (((atomic_load_acquire (cond->__data.__g_signals + g) & 1) != 0)
+	      || (seq < (__condvar_load_g1_start_relaxed (cond) >> 1)))
+	    {
+	      /* Our group is closed.  Wake up any signalers that might be
+		 waiting.  */
+	      __condvar_dec_grefs (cond, g, private);
+	      goto done;
+	    }
+
+	  // Now block.
+	  struct _pthread_cleanup_buffer buffer;
+	  struct _condvar_cleanup_buffer cbuffer;
+	  cbuffer.wseq = wseq;
+	  cbuffer.cond = cond;
+	  cbuffer.mutex = mutex;
+	  cbuffer.private = private;
+	  __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
+
+	  if (abstime == NULL)
+	    {
+	      /* Block without a timeout.  */
+	      err = futex_wait_cancelable (
+		  cond->__data.__g_signals + g, 0, private);
+	    }
+	  else
+	    {
+	      /* Block, but with a timeout.
+		 Work around the fact that the kernel rejects negative timeout
+		 values despite them being valid.  */
+	      if (__glibc_unlikely (abstime->tv_sec < 0))
+	        err = ETIMEDOUT;
+
+	      else if ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0)
+		{
+		  /* CLOCK_MONOTONIC is requested.  */
+		  struct timespec rt;
+		  struct __timespec64 rt64;
+		  if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
+		    __libc_fatal ("clock_gettime does not support "
+				  "CLOCK_MONOTONIC");
+		  /* Convert the absolute timeout value to a relative
+		     timeout.  */
+		  rt64.tv_sec = abstime->tv_sec - rt.tv_sec;
+		  rt64.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
+		  if (rt64.tv_nsec < 0)
+		    {
+		      rt64.tv_nsec += 1000000000;
+		      --rt64.tv_sec;
+		    }
+		  /* Did we already time out?  */
+		  if (__glibc_unlikely (rt64.tv_sec < 0))
+		    err = ETIMEDOUT;
+		  else
+		    err = futex_reltimed_wait_cancelable64
+			(cond->__data.__g_signals + g, 0, &rt64, private);
+		}
+	      else
+		{
+		  /* Use CLOCK_REALTIME.  */
+		  err = futex_abstimed_wait_cancelable64
+		      (cond->__data.__g_signals + g, 0, abstime, private);
+		}
+	    }
+
+	  __pthread_cleanup_pop (&buffer, 0);
+
+	  if (__glibc_unlikely (err == ETIMEDOUT))
+	    {
+	      __condvar_dec_grefs (cond, g, private);
+	      /* If we timed out, we effectively cancel waiting.  Note that
+		 we have decremented __g_refs before cancellation, so that a
+		 deadlock between waiting for quiescence of our group in
+		 __condvar_quiesce_and_switch_g1 and us trying to acquire
+		 the lock during cancellation is not possible.  */
+	      __condvar_cancel_waiting (cond, seq, g, private);
+	      result = ETIMEDOUT;
+	      goto done;
+	    }
+	  else
+	    __condvar_dec_grefs (cond, g, private);
+
+	  /* Reload signals.  See above for MO.  */
+	  signals = atomic_load_acquire (cond->__data.__g_signals + g);
+	}
+
+    }
+  /* Try to grab a signal.  Use acquire MO so that we see an up-to-date value
+     of __g1_start below (see spinning above for a similar case).  In
+     particular, if we steal from a more recent group, we will also see a
+     more recent __g1_start below.  */
+  while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
+						&signals, signals - 2));
+
+  /* We consumed a signal but we could have consumed from a more recent group
+     that aliased with ours due to being in the same group slot.  If this
+     might be the case our group must be closed as visible through
+     __g1_start.  */
+  uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
+  if (seq < (g1_start >> 1))
+    {
+      /* We potentially stole a signal from a more recent group but we do not
+	 know which group we really consumed from.
+	 We do not care about groups older than current G1 because they are
+	 closed; we could have stolen from these, but then we just add a
+	 spurious wake-up for the current groups.
+	 We will never steal a signal from current G2 that was really intended
+	 for G2 because G2 never receives signals (until it becomes G1).  We
+	 could have stolen a signal from G2 that was conservatively added by a
+	 previous waiter that also thought it stole a signal -- but given that
+	 that signal was added unnecessarily, it's not a problem if we steal
+	 it.
+	 Thus, the remaining case is that we could have stolen from the current
+	 G1, where "current" means the __g1_start value we observed.  However,
+	 if the current G1 does not have the same slot index as we do, we did
+	 not steal from it and do not need to undo that.  This is the reason
+	 for putting a bit with G2's index into__g1_start as well.  */
+      if (((g1_start & 1) ^ 1) == g)
+	{
+	  /* We have to conservatively undo our potential mistake of stealing
+	     a signal.  We can stop trying to do that when the current G1
+	     changes because other spinning waiters will notice this too and
+	     __condvar_quiesce_and_switch_g1 has checked that there are no
+	     futex waiters anymore before switching G1.
+	     Relaxed MO is fine for the __g1_start load because we need to
+	     merely be able to observe this fact and not have to observe
+	     something else as well.
+	     ??? Would it help to spin for a little while to see whether the
+	     current G1 gets closed?  This might be worthwhile if the group is
+	     small or close to being closed.  */
+	  unsigned int s = atomic_load_relaxed (cond->__data.__g_signals + g);
+	  while (__condvar_load_g1_start_relaxed (cond) == g1_start)
+	    {
+	      /* Try to add a signal.  We don't need to acquire the lock
+		 because at worst we can cause a spurious wake-up.  If the
+		 group is in the process of being closed (LSB is true), this
+		 has an effect similar to us adding a signal.  */
+	      if (((s & 1) != 0)
+		  || atomic_compare_exchange_weak_relaxed
+		       (cond->__data.__g_signals + g, &s, s + 2))
+		{
+		  /* If we added a signal, we also need to add a wake-up on
+		     the futex.  We also need to do that if we skipped adding
+		     a signal because the group is being closed because
+		     while __condvar_quiesce_and_switch_g1 could have closed
+		     the group, it might stil be waiting for futex waiters to
+		     leave (and one of those waiters might be the one we stole
+		     the signal from, which cause it to block using the
+		     futex).  */
+		  futex_wake (cond->__data.__g_signals + g, 1, private);
+		  break;
+		}
+	      /* TODO Back off.  */
+	    }
+	}
+    }
+
+ done:
+
+  /* Confirm that we have been woken.  We do that before acquiring the mutex
+     to allow for execution of pthread_cond_destroy while having acquired the
+     mutex.  */
+  __condvar_confirm_wakeup (cond, private);
+
+  /* Woken up; now re-acquire the mutex.  If this doesn't fail, return RESULT,
+     which is set to ETIMEDOUT if a timeout occured, or zero otherwise.  */
+  err = __pthread_mutex_cond_lock (mutex);
+  /* XXX Abort on errors that are disallowed by POSIX?  */
+  return (err != 0) ? err : result;
+}
+
 
 /* See __pthread_cond_wait_common.  */
 int
@@ -667,6 +941,17 @@ __pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
   return __pthread_cond_wait_common (cond, mutex, abstime);
 }
 
+int
+__pthread_cond_timedwait64 (pthread_cond_t *cond, pthread_mutex_t *mutex,
+    const struct __timespec64 *abstime)
+{
+  /* Check parameter validity.  This should also tell the compiler that
+     it can assume that abstime is not NULL.  */
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+  return __pthread_cond_wait_common64 (cond, mutex, abstime);
+}
+
 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
 		  GLIBC_2_3_2);
 versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 28237b0..9d9dfdf 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -25,6 +25,7 @@
 #include <atomic.h>
 #include <lowlevellock.h>
 #include <not-cancel.h>
+#include <y2038-support.h>
 
 #include <stap-probe.h>
 
@@ -32,6 +33,10 @@
 #define lll_timedlock_elision(a,dummy,b,c) lll_timedlock(a, b, c)
 #endif
 
+#ifndef lll_timedlock_elision64
+#define lll_timedlock_elision64(a,dummy,b,c) lll_timedlock64(a, b, c)
+#endif
+
 #ifndef lll_trylock_elision
 #define lll_trylock_elision(a,t) lll_trylock(a)
 #endif
@@ -638,3 +643,635 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
   return result;
 }
 weak_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock)
+
+/* 64-bit time version */
+
+int
+__pthread_mutex_timedlock64 (pthread_mutex_t *mutex,
+			 const struct __timespec64 *abstime)
+{
+/* Only compile this function if kernel provides clock_gettime64 */
+#ifdef __NR_clock_gettime64
+  int oldval;
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+  int result = 0;
+#endif
+  struct timespec abstime32;
+
+  LIBC_PROBE (mutex_timedlock_entry, 2, mutex, abstime);
+
+/* Only compile this function if kernel provides clock_gettime64 */
+#ifdef __NR_clock_gettime64
+  if (__y2038_get_kernel_support())
+    {
+
+      /* We must not check ABSTIME here.  If the thread does not block
+         abstime must not be checked for a valid value.  */
+
+      switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
+                    PTHREAD_MUTEX_TIMED_NP))
+        {
+          /* Recursive mutex.  */
+        case PTHREAD_MUTEX_RECURSIVE_NP|PTHREAD_MUTEX_ELISION_NP:
+        case PTHREAD_MUTEX_RECURSIVE_NP:
+          /* Check whether we already hold the mutex.  */
+          if (mutex->__data.__owner == id)
+        {
+          /* Just bump the counter.  */
+          if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
+            /* Overflow of the counter.  */
+            return EAGAIN;
+
+          ++mutex->__data.__count;
+
+          goto out;
+        }
+
+          /* We have to get the mutex.  */
+          result = lll_timedlock64 (mutex->__data.__lock, abstime,
+                          PTHREAD_MUTEX_PSHARED (mutex));
+
+          if (result != 0)
+        goto out;
+
+          /* Only locked once so far.  */
+          mutex->__data.__count = 1;
+          break;
+
+          /* Error checking mutex.  */
+        case PTHREAD_MUTEX_ERRORCHECK_NP:
+          /* Check whether we already hold the mutex.  */
+          if (__glibc_unlikely (mutex->__data.__owner == id))
+        return EDEADLK;
+
+          /* Don't do lock elision on an error checking mutex.  */
+          goto simple;
+
+        case PTHREAD_MUTEX_TIMED_NP:
+          FORCE_ELISION (mutex, goto elision);
+        simple:
+          /* Normal mutex.  */
+          result = lll_timedlock64 (mutex->__data.__lock, abstime,
+                          PTHREAD_MUTEX_PSHARED (mutex));
+          break;
+
+        case PTHREAD_MUTEX_TIMED_ELISION_NP:
+        elision: __attribute__((unused))
+          /* Don't record ownership */
+          return lll_timedlock_elision64 (mutex->__data.__lock,
+                        mutex->__data.__spins,
+                        abstime,
+                        PTHREAD_MUTEX_PSHARED (mutex));
+
+
+        case PTHREAD_MUTEX_ADAPTIVE_NP:
+          if (! __is_smp)
+        goto simple;
+
+          if (lll_trylock (mutex->__data.__lock) != 0)
+        {
+          int cnt = 0;
+          int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
+                     mutex->__data.__spins * 2 + 10);
+          do
+            {
+              if (cnt++ >= max_cnt)
+            {
+              result = lll_timedlock64 (mutex->__data.__lock, abstime,
+                              PTHREAD_MUTEX_PSHARED (mutex));
+              break;
+            }
+              atomic_spin_nop ();
+            }
+          while (lll_trylock (mutex->__data.__lock) != 0);
+
+          mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
+        }
+          break;
+
+        case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+        case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+        case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+        case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+          THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                 &mutex->__data.__list.__next);
+          /* We need to set op_pending before starting the operation.  Also
+         see comments at ENQUEUE_MUTEX.  */
+          __asm ("" ::: "memory");
+
+          oldval = mutex->__data.__lock;
+          /* This is set to FUTEX_WAITERS iff we might have shared the
+         FUTEX_WAITERS flag with other threads, and therefore need to keep it
+         set to avoid lost wake-ups.  We have the same requirement in the
+         simple mutex algorithm.  */
+          unsigned int assume_other_futex_waiters = 0;
+          while (1)
+        {
+          /* Try to acquire the lock through a CAS from 0 (not acquired) to
+             our TID | assume_other_futex_waiters.  */
+          if (__glibc_likely (oldval == 0))
+            {
+              oldval
+                = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                    id | assume_other_futex_waiters, 0);
+              if (__glibc_likely (oldval == 0))
+            break;
+            }
+
+          if ((oldval & FUTEX_OWNER_DIED) != 0)
+            {
+              /* The previous owner died.  Try locking the mutex.  */
+              int newval = id | (oldval & FUTEX_WAITERS)
+              | assume_other_futex_waiters;
+
+              newval
+            = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                   newval, oldval);
+              if (newval != oldval)
+            {
+              oldval = newval;
+              continue;
+            }
+
+              /* We got the mutex.  */
+              mutex->__data.__count = 1;
+              /* But it is inconsistent unless marked otherwise.  */
+              mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+              /* We must not enqueue the mutex before we have acquired it.
+             Also see comments at ENQUEUE_MUTEX.  */
+              __asm ("" ::: "memory");
+              ENQUEUE_MUTEX (mutex);
+              /* We need to clear op_pending after we enqueue the mutex.  */
+              __asm ("" ::: "memory");
+              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+              /* Note that we deliberately exit here.  If we fall
+             through to the end of the function __nusers would be
+             incremented which is not correct because the old
+             owner has to be discounted.  */
+              return EOWNERDEAD;
+            }
+
+          /* Check whether we already hold the mutex.  */
+          if (__glibc_unlikely ((oldval & FUTEX_TID_MASK) == id))
+            {
+              int kind = PTHREAD_MUTEX_TYPE (mutex);
+              if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+            {
+              /* We do not need to ensure ordering wrt another memory
+                 access.  Also see comments at ENQUEUE_MUTEX. */
+              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                     NULL);
+              return EDEADLK;
+            }
+
+              if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+            {
+              /* We do not need to ensure ordering wrt another memory
+                 access.  */
+              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                     NULL);
+
+              /* Just bump the counter.  */
+              if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
+                /* Overflow of the counter.  */
+                return EAGAIN;
+
+              ++mutex->__data.__count;
+
+              LIBC_PROBE (mutex_timedlock_acquired, 1, mutex);
+
+              return 0;
+            }
+            }
+
+          /* We are about to block; check whether the timeout is invalid.  */
+          if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+            return EINVAL;
+          /* Work around the fact that the kernel rejects negative timeout
+             values despite them being valid.  */
+          if (__glibc_unlikely (abstime->tv_sec < 0))
+            return ETIMEDOUT;
+    #if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+         || !defined lll_futex_timed_wait_bitset)
+          struct timeval tv;
+          struct timespec rt;
+
+          /* Get the current time.  */
+          (void) __gettimeofday (&tv, NULL);
+
+          /* Compute relative timeout.  */
+          rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+          rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+          if (rt.tv_nsec < 0)
+            {
+              rt.tv_nsec += 1000000000;
+              --rt.tv_sec;
+            }
+
+          /* Already timed out?  */
+          if (rt.tv_sec < 0)
+            return ETIMEDOUT;
+    #endif
+
+          /* We cannot acquire the mutex nor has its owner died.  Thus, try
+             to block using futexes.  Set FUTEX_WAITERS if necessary so that
+             other threads are aware that there are potentially threads
+             blocked on the futex.  Restart if oldval changed in the
+             meantime.  */
+          if ((oldval & FUTEX_WAITERS) == 0)
+            {
+              if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
+                                oldval | FUTEX_WAITERS,
+                                oldval)
+              != 0)
+            {
+              oldval = mutex->__data.__lock;
+              continue;
+            }
+              oldval |= FUTEX_WAITERS;
+            }
+
+          /* It is now possible that we share the FUTEX_WAITERS flag with
+             another thread; therefore, update assume_other_futex_waiters so
+             that we do not forget about this when handling other cases
+             above and thus do not cause lost wake-ups.  */
+          assume_other_futex_waiters |= FUTEX_WAITERS;
+
+          /* Block using the futex.  */
+    #if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+         || !defined lll_futex_timed_wait_bitset)
+          lll_futex_timed wait_64 (&mutex->__data.__lock, oldval,
+                    &rt, PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+    #else
+          int err = lll_futex_timed_wait_bitset64 (&mutex->__data.__lock,
+              oldval, abstime, FUTEX_CLOCK_REALTIME,
+              PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+          /* The futex call timed out.  */
+          if (err == -ETIMEDOUT)
+            return -err;
+    #endif
+          /* Reload current lock value.  */
+          oldval = mutex->__data.__lock;
+        }
+
+          /* We have acquired the mutex; check if it is still consistent.  */
+          if (__builtin_expect (mutex->__data.__owner
+                    == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+        {
+          /* This mutex is now not recoverable.  */
+          mutex->__data.__count = 0;
+          int private = PTHREAD_ROBUST_MUTEX_PSHARED (mutex);
+          lll_unlock (mutex->__data.__lock, private);
+          /* FIXME This violates the mutex destruction requirements.  See
+             __pthread_mutex_unlock_full.  */
+          THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+          return ENOTRECOVERABLE;
+        }
+
+          mutex->__data.__count = 1;
+          /* We must not enqueue the mutex before we have acquired it.
+         Also see comments at ENQUEUE_MUTEX.  */
+          __asm ("" ::: "memory");
+          ENQUEUE_MUTEX (mutex);
+          /* We need to clear op_pending after we enqueue the mutex.  */
+          __asm ("" ::: "memory");
+          THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+          break;
+
+        /* The PI support requires the Linux futex system call.  If that's not
+           available, pthread_mutex_init should never have allowed the type to
+           be set.  So it will get the default case for an invalid type.  */
+    #ifdef __NR_futex
+        case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+        case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+        case PTHREAD_MUTEX_PI_NORMAL_NP:
+        case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+        case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+        case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+        case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+        case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+          {
+        int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+        int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+        if (robust)
+          {
+            /* Note: robust PI futexes are signaled by setting bit 0.  */
+            THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                   (void *) (((uintptr_t) &mutex->__data.__list.__next)
+                         | 1));
+            /* We need to set op_pending before starting the operation.  Also
+               see comments at ENQUEUE_MUTEX.  */
+            __asm ("" ::: "memory");
+          }
+
+        oldval = mutex->__data.__lock;
+
+        /* Check whether we already hold the mutex.  */
+        if (__glibc_unlikely ((oldval & FUTEX_TID_MASK) == id))
+          {
+            if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+              {
+            /* We do not need to ensure ordering wrt another memory
+               access.  */
+            THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+            return EDEADLK;
+              }
+
+            if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+              {
+            /* We do not need to ensure ordering wrt another memory
+               access.  */
+            THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+            /* Just bump the counter.  */
+            if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
+              /* Overflow of the counter.  */
+              return EAGAIN;
+
+            ++mutex->__data.__count;
+
+            LIBC_PROBE (mutex_timedlock_acquired, 1, mutex);
+
+            return 0;
+              }
+          }
+
+        oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                  id, 0);
+
+        if (oldval != 0)
+          {
+            /* The mutex is locked.  The kernel will now take care of
+               everything.  The timeout value must be a relative value.
+               Convert it.  */
+            int private = (robust
+                   ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+                   : PTHREAD_MUTEX_PSHARED (mutex));
+            INTERNAL_SYSCALL_DECL (__err);
+
+            int e;
+            
+            if (abstime->tv_sec > INT_MAX)
+            {
+              e = EOVERFLOW;
+            }
+            else
+            {
+              struct timespec ts;
+              ts.tv_sec = abstime->tv_sec;
+              ts.tv_nsec = abstime->tv_nsec;
+              e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                          __lll_private_flag (FUTEX_LOCK_PI,
+                                  private), 1,
+                          &ts);
+            }
+            if (INTERNAL_SYSCALL_ERROR_P (e, __err))
+              {
+            if (INTERNAL_SYSCALL_ERRNO (e, __err) == ETIMEDOUT)
+              return ETIMEDOUT;
+
+            if (INTERNAL_SYSCALL_ERRNO (e, __err) == ESRCH
+                || INTERNAL_SYSCALL_ERRNO (e, __err) == EDEADLK)
+              {
+                assert (INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK
+                    || (kind != PTHREAD_MUTEX_ERRORCHECK_NP
+                    && kind != PTHREAD_MUTEX_RECURSIVE_NP));
+                /* ESRCH can happen only for non-robust PI mutexes where
+                   the owner of the lock died.  */
+                assert (INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH
+                    || !robust);
+
+                /* Delay the thread until the timeout is reached.
+                   Then return ETIMEDOUT.  */
+                struct timespec reltime;
+                struct __timespec64 now;
+
+                INTERNAL_SYSCALL (clock_gettime64, __err, 2, CLOCK_REALTIME,
+                          &now);
+                reltime.tv_sec = abstime->tv_sec - now.tv_sec;
+                reltime.tv_nsec = abstime->tv_nsec - now.tv_nsec;
+                if (reltime.tv_nsec < 0)
+                  {
+                reltime.tv_nsec += 1000000000;
+                --reltime.tv_sec;
+                  }
+                if (reltime.tv_sec >= 0)
+                  while (__nanosleep_nocancel (&reltime, &reltime) != 0)
+                continue;
+
+                return ETIMEDOUT;
+              }
+
+            return INTERNAL_SYSCALL_ERRNO (e, __err);
+              }
+
+            oldval = mutex->__data.__lock;
+
+            assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
+          }
+
+        if (__glibc_unlikely (oldval & FUTEX_OWNER_DIED))
+          {
+            atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+            /* We got the mutex.  */
+            mutex->__data.__count = 1;
+            /* But it is inconsistent unless marked otherwise.  */
+            mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+            /* We must not enqueue the mutex before we have acquired it.
+               Also see comments at ENQUEUE_MUTEX.  */
+            __asm ("" ::: "memory");
+            ENQUEUE_MUTEX_PI (mutex);
+            /* We need to clear op_pending after we enqueue the mutex.  */
+            __asm ("" ::: "memory");
+            THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+            /* Note that we deliberately exit here.  If we fall
+               through to the end of the function __nusers would be
+               incremented which is not correct because the old owner
+               has to be discounted.  */
+            return EOWNERDEAD;
+          }
+
+        if (robust
+            && __builtin_expect (mutex->__data.__owner
+                     == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+          {
+            /* This mutex is now not recoverable.  */
+            mutex->__data.__count = 0;
+
+            INTERNAL_SYSCALL_DECL (__err);
+            INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                      __lll_private_flag (FUTEX_UNLOCK_PI,
+                              PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+                      0, 0);
+
+            /* To the kernel, this will be visible after the kernel has
+               acquired the mutex in the syscall.  */
+            THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+            return ENOTRECOVERABLE;
+          }
+
+        mutex->__data.__count = 1;
+        if (robust)
+          {
+            /* We must not enqueue the mutex before we have acquired it.
+               Also see comments at ENQUEUE_MUTEX.  */
+            __asm ("" ::: "memory");
+            ENQUEUE_MUTEX_PI (mutex);
+            /* We need to clear op_pending after we enqueue the mutex.  */
+            __asm ("" ::: "memory");
+            THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+          }
+        }
+          break;
+    #endif  /* __NR_futex.  */
+
+        case PTHREAD_MUTEX_PP_RECURSIVE_NP:
+        case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
+        case PTHREAD_MUTEX_PP_NORMAL_NP:
+        case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
+          {
+        int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+
+        oldval = mutex->__data.__lock;
+
+        /* Check whether we already hold the mutex.  */
+        if (mutex->__data.__owner == id)
+          {
+            if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+              return EDEADLK;
+
+            if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+              {
+            /* Just bump the counter.  */
+            if (__glibc_unlikely (mutex->__data.__count + 1 == 0))
+              /* Overflow of the counter.  */
+              return EAGAIN;
+
+            ++mutex->__data.__count;
+
+            LIBC_PROBE (mutex_timedlock_acquired, 1, mutex);
+
+            return 0;
+              }
+          }
+
+        int oldprio = -1, ceilval;
+        do
+          {
+            int ceiling = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK)
+                  >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+
+            if (__pthread_current_priority () > ceiling)
+              {
+            result = EINVAL;
+              failpp:
+            if (oldprio != -1)
+              __pthread_tpp_change_priority (oldprio, -1);
+            return result;
+              }
+
+            result = __pthread_tpp_change_priority (oldprio, ceiling);
+            if (result)
+              return result;
+
+            ceilval = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+            oldprio = ceiling;
+
+            oldval
+              = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                 ceilval | 1, ceilval);
+
+            if (oldval == ceilval)
+              break;
+
+            do
+              {
+            oldval
+              = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                 ceilval | 2,
+                                 ceilval | 1);
+
+            if ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval)
+              break;
+
+            if (oldval != ceilval)
+              {
+                /* Reject invalid timeouts.  */
+                if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+                  {
+                result = EINVAL;
+                goto failpp;
+                  }
+
+                struct timeval tv;
+                struct timespec rt;
+
+                /* Get the current time.  */
+                (void) __gettimeofday (&tv, NULL);
+
+                /* Compute relative timeout.  */
+                rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+                rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+                if (rt.tv_nsec < 0)
+                  {
+                rt.tv_nsec += 1000000000;
+                --rt.tv_sec;
+                  }
+
+                /* Already timed out?  */
+                if (rt.tv_sec < 0)
+                  {
+                result = ETIMEDOUT;
+                goto failpp;
+                  }
+
+                lll_futex_timed_wait (&mutex->__data.__lock,
+                          ceilval | 2, &rt,
+                          PTHREAD_MUTEX_PSHARED (mutex));
+              }
+              }
+            while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                ceilval | 2, ceilval)
+               != ceilval);
+          }
+        while ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval);
+
+        assert (mutex->__data.__owner == 0);
+        mutex->__data.__count = 1;
+          }
+          break;
+
+        default:
+          /* Correct code cannot set any other type.  */
+          return EINVAL;
+        }
+
+      if (result == 0)
+        {
+          /* Record the ownership.  */
+          mutex->__data.__owner = id;
+          ++mutex->__data.__nusers;
+
+          LIBC_PROBE (mutex_timedlock_acquired, 1, mutex);
+        }
+     out:
+      return result;
+    }
+#endif
+
+  if (abstime->tv_sec > INT_MAX || abstime->tv_sec < INT_MIN)
+    {
+      return EOVERFLOW;
+    }
+
+  abstime32.tv_sec = (time_t) (abstime->tv_sec);
+  abstime32.tv_nsec = abstime->tv_nsec;
+
+  return __pthread_mutex_timedlock (mutex, &abstime32);
+}
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index a290d08..f34750e 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -507,6 +507,240 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
   return 0;
 }
 
+/* 64-bit time version */
+
+static __always_inline int
+__pthread_rwlock_rdlock_full64 (pthread_rwlock_t *rwlock,
+    const struct __timespec64 *abstime)
+{
+  unsigned int r;
+
+  /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
+     situation we recognize and report.  */
+  if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
+      == THREAD_GETMEM (THREAD_SELF, tid)))
+    return EDEADLK;
+
+  /* If we prefer writers, recursive rdlock is disallowed, we are in a read
+     phase, and there are other readers present, we try to wait without
+     extending the read phase.  We will be unblocked by either one of the
+     other active readers, or if the writer gives up WRLOCKED (e.g., on
+     timeout).
+     If there are no other readers, we simply race with any existing primary
+     writer; it would have been a race anyway, and changing the odds slightly
+     will likely not make a big difference.  */
+  if (rwlock->__data.__flags == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
+    {
+      r = atomic_load_relaxed (&rwlock->__data.__readers);
+      while (((r & PTHREAD_RWLOCK_WRPHASE) == 0)
+	      && ((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
+	      && ((r >> PTHREAD_RWLOCK_READER_SHIFT) > 0))
+	{
+	  /* TODO Spin first.  */
+	  /* Try setting the flag signaling that we are waiting without having
+	     incremented the number of readers.  Relaxed MO is fine because
+	     this is just about waiting for a state change in __readers.  */
+	  if (atomic_compare_exchange_weak_relaxed
+	      (&rwlock->__data.__readers, &r, r | PTHREAD_RWLOCK_RWAITING))
+	    {
+	      /* Wait for as long as the flag is set.  An ABA situation is
+		 harmless because the flag is just about the state of
+		 __readers, and all threads set the flag under the same
+		 conditions.  */
+	      while ((atomic_load_relaxed (&rwlock->__data.__readers)
+		  & PTHREAD_RWLOCK_RWAITING) != 0)
+		{
+		  int private = __pthread_rwlock_get_private (rwlock);
+		  int err = futex_abstimed_wait64 (&rwlock->__data.__readers,
+		      r, abstime, private);
+		  /* We ignore EAGAIN and EINTR.  On time-outs, we can just
+		     return because we don't need to clean up anything.  */
+		  if (err == ETIMEDOUT)
+		    return err;
+		}
+	      /* It makes sense to not break out of the outer loop here
+		 because we might be in the same situation again.  */
+	    }
+	  else
+	    {
+	      /* TODO Back-off.  */
+	    }
+	}
+    }
+  /* Register as a reader, using an add-and-fetch so that R can be used as
+     expected value for future operations.  Acquire MO so we synchronize with
+     prior writers as well as the last reader of the previous read phase (see
+     below).  */
+  r = atomic_fetch_add_acquire (&rwlock->__data.__readers,
+      (1 << PTHREAD_RWLOCK_READER_SHIFT)) + (1 << PTHREAD_RWLOCK_READER_SHIFT);
+
+  /* Check whether there is an overflow in the number of readers.  We assume
+     that the total number of threads is less than half the maximum number
+     of readers that we have bits for in __readers (i.e., with 32-bit int and
+     PTHREAD_RWLOCK_READER_SHIFT of 3, we assume there are less than
+     1 << (32-3-1) concurrent threads).
+     If there is an overflow, we use a CAS to try to decrement the number of
+     readers if there still is an overflow situation.  If so, we return
+     EAGAIN; if not, we are not a thread causing an overflow situation, and so
+     we just continue.  Using a fetch-add instead of the CAS isn't possible
+     because other readers might release the lock concurrently, which could
+     make us the last reader and thus responsible for handing ownership over
+     to writers (which requires a CAS too to make the decrement and ownership
+     transfer indivisible).  */
+  while (__glibc_unlikely (r >= PTHREAD_RWLOCK_READER_OVERFLOW))
+    {
+      /* Relaxed MO is okay because we just want to undo our registration and
+	 cannot have changed the rwlock state substantially if the CAS
+	 succeeds.  */
+      if (atomic_compare_exchange_weak_relaxed (&rwlock->__data.__readers, &r,
+	  r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
+	return EAGAIN;
+    }
+
+  /* We have registered as a reader, so if we are in a read phase, we have
+     acquired a read lock.  This is also the reader--reader fast-path.
+     Even if there is a primary writer, we just return.  If writers are to
+     be preferred and we are the only active reader, we could try to enter a
+     write phase to let the writer proceed.  This would be okay because we
+     cannot have acquired the lock previously as a reader (which could result
+     in deadlock if we would wait for the primary writer to run).  However,
+     this seems to be a corner case and handling it specially not be worth the
+     complexity.  */
+  if (__glibc_likely ((r & PTHREAD_RWLOCK_WRPHASE) == 0))
+    return 0;
+
+  /* If there is no primary writer but we are in a write phase, we can try
+     to install a read phase ourself.  */
+  while (((r & PTHREAD_RWLOCK_WRPHASE) != 0)
+      && ((r & PTHREAD_RWLOCK_WRLOCKED) == 0))
+    {
+       /* Try to enter a read phase: If the CAS below succeeds, we have
+	 ownership; if it fails, we will simply retry and reassess the
+	 situation.
+	 Acquire MO so we synchronize with prior writers.  */
+      if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
+	  r ^ PTHREAD_RWLOCK_WRPHASE))
+	{
+	  /* We started the read phase, so we are also responsible for
+	     updating the write-phase futex.  Relaxed MO is sufficient.
+	     Note that there can be no other reader that we have to wake
+	     because all other readers will see the read phase started by us
+	     (or they will try to start it themselves); if a writer started
+	     the read phase, we cannot have started it.  Furthermore, we
+	     cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will
+	     overwrite the value set by the most recent writer (or the readers
+	     before it in case of explicit hand-over) and we know that there
+	     are no waiting readers.  */
+	  atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
+	  return 0;
+	}
+      else
+	{
+	  /* TODO Back off before retrying.  Also see above.  */
+	}
+    }
+
+  if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
+    {
+      /* We are in a write phase, and there must be a primary writer because
+	 of the previous loop.  Block until the primary writer gives up the
+	 write phase.  This case requires explicit hand-over using
+	 __wrphase_futex.
+	 However, __wrphase_futex might not have been set to 1 yet (either
+	 because explicit hand-over to the writer is still ongoing, or because
+	 the writer has started the write phase but does not yet have updated
+	 __wrphase_futex).  The least recent value of __wrphase_futex we can
+	 read from here is the modification of the last read phase (because
+	 we synchronize with the last reader in this read phase through
+	 __readers; see the use of acquire MO on the fetch_add above).
+	 Therefore, if we observe a value of 0 for __wrphase_futex, we need
+	 to subsequently check that __readers now indicates a read phase; we
+	 need to use acquire MO for this so that if we observe a read phase,
+	 we will also see the modification of __wrphase_futex by the previous
+	 writer.  We then need to load __wrphase_futex again and continue to
+	 wait if it is not 0, so that we do not skip explicit hand-over.
+	 Relaxed MO is sufficient for the load from __wrphase_futex because
+	 we just use it as an indicator for when we can proceed; we use
+	 __readers and the acquire MO accesses to it to eventually read from
+	 the proper stores to __wrphase_futex.  */
+      unsigned int wpf;
+      bool ready = false;
+      for (;;)
+	{
+	  while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
+	      | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
+	    {
+	      int private = __pthread_rwlock_get_private (rwlock);
+	      if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
+		  && !atomic_compare_exchange_weak_relaxed
+		      (&rwlock->__data.__wrphase_futex,
+		       &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))
+		continue;
+	      int err = futex_abstimed_wait64 (&rwlock->__data.__wrphase_futex,
+		  1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
+	      if (err == ETIMEDOUT)
+		{
+		  /* If we timed out, we need to unregister.  If no read phase
+		     has been installed while we waited, we can just decrement
+		     the number of readers.  Otherwise, we just acquire the
+		     lock, which is allowed because we give no precise timing
+		     guarantees, and because the timeout is only required to
+		     be in effect if we would have had to wait for other
+		     threads (e.g., if futex_wait would time-out immediately
+		     because the given absolute time is in the past).  */
+		  r = atomic_load_relaxed (&rwlock->__data.__readers);
+		  while ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
+		    {
+		      /* We don't need to make anything else visible to
+			 others besides unregistering, so relaxed MO is
+			 sufficient.  */
+		      if (atomic_compare_exchange_weak_relaxed
+			  (&rwlock->__data.__readers, &r,
+			   r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
+			return ETIMEDOUT;
+		      /* TODO Back-off.  */
+		    }
+		  /* Use the acquire MO fence to mirror the steps taken in the
+		     non-timeout case.  Note that the read can happen both
+		     in the atomic_load above as well as in the failure case
+		     of the CAS operation.  */
+		  atomic_thread_fence_acquire ();
+		  /* We still need to wait for explicit hand-over, but we must
+		     not use futex_wait anymore because we would just time out
+		     in this case and thus make the spin-waiting we need
+		     unnecessarily expensive.  */
+		  while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex)
+		      | PTHREAD_RWLOCK_FUTEX_USED)
+		      == (1 | PTHREAD_RWLOCK_FUTEX_USED))
+		    {
+		      /* TODO Back-off?  */
+		    }
+		  ready = true;
+		  break;
+		}
+	      /* If we got interrupted (EINTR) or the futex word does not have the
+		 expected value (EAGAIN), retry.  */
+	    }
+	  if (ready)
+	    /* See below.  */
+	    break;
+	  /* We need acquire MO here so that we synchronize with the lock
+	     release of the writer, and so that we observe a recent value of
+	     __wrphase_futex (see below).  */
+	  if ((atomic_load_acquire (&rwlock->__data.__readers)
+	      & PTHREAD_RWLOCK_WRPHASE) == 0)
+	    /* We are in a read phase now, so the least recent modification of
+	       __wrphase_futex we can read from is the store by the writer
+	       with value 1.  Thus, only now we can assume that if we observe
+	       a value of 0, explicit hand-over is finished. Retry the loop
+	       above one more time.  */
+	    ready = true;
+	}
+    }
+
+  return 0;
+}
+
 
 static __always_inline void
 __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock)
@@ -924,3 +1158,360 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
       THREAD_GETMEM (THREAD_SELF, tid));
   return 0;
 }
+
+/* 64-bit time version */
+
+static __always_inline int
+__pthread_rwlock_wrlock_full64 (pthread_rwlock_t *rwlock,
+    const struct __timespec64 *abstime)
+{
+  /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
+     situation we recognize and report.  */
+  if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
+      == THREAD_GETMEM (THREAD_SELF, tid)))
+    return EDEADLK;
+
+  /* First we try to acquire the role of primary writer by setting WRLOCKED;
+     if it was set before, there already is a primary writer.  Acquire MO so
+     that we synchronize with previous primary writers.
+
+     We do not try to change to a write phase right away using a fetch_or
+     because we would have to reset it again and wake readers if there are
+     readers present (some readers could try to acquire the lock more than
+     once, so setting a write phase in the middle of this could cause
+     deadlock).  Changing to a write phase eagerly would only speed up the
+     transition from a read phase to a write phase in the uncontended case,
+     but it would slow down the contended case if readers are preferred (which
+     is the default).
+     We could try to CAS from a state with no readers to a write phase, but
+     this could be less scalable if readers arrive and leave frequently.  */
+  bool may_share_futex_used_flag = false;
+  unsigned int r = atomic_fetch_or_acquire (&rwlock->__data.__readers,
+      PTHREAD_RWLOCK_WRLOCKED);
+  if (__glibc_unlikely ((r & PTHREAD_RWLOCK_WRLOCKED) != 0))
+    {
+      /* There is another primary writer.  */
+      bool prefer_writer =
+	  (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP);
+      if (prefer_writer)
+	{
+	  /* We register as a waiting writer, so that we can make use of
+	     writer--writer hand-over.  Relaxed MO is fine because we just
+	     want to register.  We assume that the maximum number of threads
+	     is less than the capacity in __writers.  */
+	  atomic_fetch_add_relaxed (&rwlock->__data.__writers, 1);
+	}
+      for (;;)
+	{
+	  /* TODO Spin until WRLOCKED is 0 before trying the CAS below.
+	     But pay attention to not delay trying writer--writer hand-over
+	     for too long (which we must try eventually anyway).  */
+	  if ((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
+	    {
+	      /* Try to become the primary writer or retry.  Acquire MO as in
+		 the fetch_or above.  */
+	      if (atomic_compare_exchange_weak_acquire
+		  (&rwlock->__data.__readers, &r,
+		      r | PTHREAD_RWLOCK_WRLOCKED))
+		{
+		  if (prefer_writer)
+		    {
+		      /* Unregister as a waiting writer.  Note that because we
+			 acquired WRLOCKED, WRHANDOVER will not be set.
+			 Acquire MO on the CAS above ensures that
+			 unregistering happens after the previous writer;
+			 this sorts the accesses to __writers by all
+			 primary writers in a useful way (e.g., any other
+			 primary writer acquiring after us or getting it from
+			 us through WRHANDOVER will see both our changes to
+			 __writers).
+			 ??? Perhaps this is not strictly necessary for
+			 reasons we do not yet know of.  */
+		      atomic_fetch_add_relaxed (&rwlock->__data.__writers,
+			  -1);
+		    }
+		  break;
+		}
+	      /* Retry if the CAS fails (r will have been updated).  */
+	      continue;
+	    }
+	  /* If writer--writer hand-over is available, try to become the
+	     primary writer this way by grabbing the WRHANDOVER token.  If we
+	     succeed, we own WRLOCKED.  */
+	  if (prefer_writer)
+	    {
+	      unsigned int w = atomic_load_relaxed
+		  (&rwlock->__data.__writers);
+	      if ((w & PTHREAD_RWLOCK_WRHANDOVER) != 0)
+		{
+		  /* Acquire MO is required here so that we synchronize with
+		     the writer that handed over WRLOCKED.  We also need this
+		     for the reload of __readers below because our view of
+		     __readers must be at least as recent as the view of the
+		     writer that handed over WRLOCKED; we must avoid an ABA
+		     through WRHANDOVER, which could, for example, lead to us
+		     assuming we are still in a write phase when in fact we
+		     are not.  */
+		  if (atomic_compare_exchange_weak_acquire
+		      (&rwlock->__data.__writers,
+		       &w, (w - PTHREAD_RWLOCK_WRHANDOVER - 1)))
+		    {
+		      /* Reload so our view is consistent with the view of
+			 the previous owner of WRLOCKED.  See above.  */
+		      r = atomic_load_relaxed (&rwlock->__data.__readers);
+		      break;
+		    }
+		  /* We do not need to reload __readers here.  We should try
+		     to perform writer--writer hand-over if possible; if it
+		     is not possible anymore, we will reload __readers
+		     elsewhere in this loop.  */
+		  continue;
+		}
+	    }
+	  /* We did not acquire WRLOCKED nor were able to use writer--writer
+	     hand-over, so we block on __writers_futex.  */
+	  int private = __pthread_rwlock_get_private (rwlock);
+	  unsigned int wf = atomic_load_relaxed
+	      (&rwlock->__data.__writers_futex);
+	  if (((wf & ~(unsigned int) PTHREAD_RWLOCK_FUTEX_USED) != 1)
+	      || ((wf != (1 | PTHREAD_RWLOCK_FUTEX_USED))
+		  && !atomic_compare_exchange_weak_relaxed
+		      (&rwlock->__data.__writers_futex, &wf,
+		       1 | PTHREAD_RWLOCK_FUTEX_USED)))
+	    {
+	      /* If we cannot block on __writers_futex because there is no
+		 primary writer, or we cannot set PTHREAD_RWLOCK_FUTEX_USED,
+		 we retry.  We must reload __readers here in case we cannot
+		 block on __writers_futex so that we can become the primary
+		 writer and are not stuck in a loop that just continuously
+		 fails to block on __writers_futex.  */
+	      r = atomic_load_relaxed (&rwlock->__data.__readers);
+	      continue;
+	    }
+	  /* We set the flag that signals that the futex is used, or we could
+	     have set it if we had been faster than other waiters.  As a
+	     result, we may share the flag with an unknown number of other
+	     writers.  Therefore, we must keep this flag set when we acquire
+	     the lock.  We do not need to do this when we do not reach this
+	     point here because then we are not part of the group that may
+	     share the flag, and another writer will wake one of the writers
+	     in this group.  */
+	  may_share_futex_used_flag = true;
+	  int err = futex_abstimed_wait64 (&rwlock->__data.__writers_futex,
+	      1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
+	  if (err == ETIMEDOUT)
+	    {
+	      if (prefer_writer)
+		{
+		  /* We need to unregister as a waiting writer.  If we are the
+		     last writer and writer--writer hand-over is available,
+		     we must make use of it because nobody else will reset
+		     WRLOCKED otherwise.  (If we use it, we simply pretend
+		     that this happened before the timeout; see
+		     pthread_rwlock_rdlock_full for the full reasoning.)
+		     Also see the similar code above.  */
+		  unsigned int w = atomic_load_relaxed
+		      (&rwlock->__data.__writers);
+		  while (!atomic_compare_exchange_weak_acquire
+		      (&rwlock->__data.__writers, &w,
+			  (w == PTHREAD_RWLOCK_WRHANDOVER + 1 ? 0 : w - 1)))
+		    {
+		      /* TODO Back-off.  */
+		    }
+		  if (w == PTHREAD_RWLOCK_WRHANDOVER + 1)
+		    {
+		      /* We must continue as primary writer.  See above.  */
+		      r = atomic_load_relaxed (&rwlock->__data.__readers);
+		      break;
+		    }
+		}
+	      /* We cleaned up and cannot have stolen another waiting writer's
+		 futex wake-up, so just return.  */
+	      return ETIMEDOUT;
+	    }
+	  /* If we got interrupted (EINTR) or the futex word does not have the
+	     expected value (EAGAIN), retry after reloading __readers.  */
+	  r = atomic_load_relaxed (&rwlock->__data.__readers);
+	}
+      /* Our snapshot of __readers is up-to-date at this point because we
+	 either set WRLOCKED using a CAS or were handed over WRLOCKED from
+	 another writer whose snapshot of __readers we inherit.  */
+    }
+
+  /* If we are in a read phase and there are no readers, try to start a write
+     phase.  */
+  while (((r & PTHREAD_RWLOCK_WRPHASE) == 0)
+      && ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0))
+    {
+      /* Acquire MO so that we synchronize with prior writers and do
+	 not interfere with their updates to __writers_futex, as well
+	 as regarding prior readers and their updates to __wrphase_futex,
+	 respectively.  */
+      if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
+	  &r, r | PTHREAD_RWLOCK_WRPHASE))
+	{
+	  /* We have started a write phase, so need to enable readers to wait.
+	     See the similar case in__pthread_rwlock_rdlock_full.  */
+	  atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
+	  /* Make sure we fall through to the end of the function.  */
+	  r |= PTHREAD_RWLOCK_WRPHASE;
+	  break;
+	}
+      /* TODO Back-off.  */
+    }
+
+  /* We are the primary writer; enable blocking on __writers_futex.  Relaxed
+     MO is sufficient for futex words; acquire MO on the previous
+     modifications of __readers ensures that this store happens after the
+     store of value 0 by the previous primary writer.  */
+  atomic_store_relaxed (&rwlock->__data.__writers_futex,
+      1 | (may_share_futex_used_flag ? PTHREAD_RWLOCK_FUTEX_USED : 0));
+
+  if (__glibc_unlikely ((r & PTHREAD_RWLOCK_WRPHASE) == 0))
+    {
+      /* We are not in a read phase and there are readers (because of the
+	 previous loop).  Thus, we have to wait for explicit hand-over from
+	 one of these readers.
+	 We basically do the same steps as for the similar case in
+	 __pthread_rwlock_rdlock_full, except that we additionally might try
+	 to directly hand over to another writer and need to wake up
+	 other writers or waiting readers (i.e., PTHREAD_RWLOCK_RWAITING).  */
+      unsigned int wpf;
+      bool ready = false;
+      for (;;)
+	{
+	  while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
+	      | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED)
+	    {
+	      int private = __pthread_rwlock_get_private (rwlock);
+	      if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
+		  && !atomic_compare_exchange_weak_relaxed
+		      (&rwlock->__data.__wrphase_futex, &wpf,
+		       PTHREAD_RWLOCK_FUTEX_USED))
+		continue;
+	      int err = futex_abstimed_wait64 (&rwlock->__data.__wrphase_futex,
+		  PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
+	      if (err == ETIMEDOUT)
+		{
+		  if (rwlock->__data.__flags
+		      != PTHREAD_RWLOCK_PREFER_READER_NP)
+		    {
+		      /* We try writer--writer hand-over.  */
+		      unsigned int w = atomic_load_relaxed
+			  (&rwlock->__data.__writers);
+		      if (w != 0)
+			{
+			  /* We are about to hand over WRLOCKED, so we must
+			     release __writers_futex too; otherwise, we'd have
+			     a pending store, which could at least prevent
+			     other threads from waiting using the futex
+			     because it could interleave with the stores
+			     by subsequent writers.  In turn, this means that
+			     we have to clean up when we do not hand over
+			     WRLOCKED.
+			     Release MO so that another writer that gets
+			     WRLOCKED from us can take over our view of
+			     __readers.  */
+			  unsigned int wf = atomic_exchange_relaxed
+			      (&rwlock->__data.__writers_futex, 0);
+			  while (w != 0)
+			    {
+			      if (atomic_compare_exchange_weak_release
+				  (&rwlock->__data.__writers, &w,
+				      w | PTHREAD_RWLOCK_WRHANDOVER))
+				{
+				  /* Wake other writers.  */
+				  if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0)
+				    futex_wake
+					(&rwlock->__data.__writers_futex, 1,
+					 private);
+				  return ETIMEDOUT;
+				}
+			      /* TODO Back-off.  */
+			    }
+			  /* We still own WRLOCKED and someone else might set
+			     a write phase concurrently, so enable waiting
+			     again.  Make sure we don't loose the flag that
+			     signals whether there are threads waiting on
+			     this futex.  */
+			  atomic_store_relaxed
+			      (&rwlock->__data.__writers_futex, wf);
+			}
+		    }
+		  /* If we timed out and we are not in a write phase, we can
+		     just stop being a primary writer.  Otherwise, we just
+		     acquire the lock.  */
+		  r = atomic_load_relaxed (&rwlock->__data.__readers);
+		  if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
+		    {
+		      /* We are about to release WRLOCKED, so we must release
+			 __writers_futex too; see the handling of
+			 writer--writer hand-over above.  */
+		      unsigned int wf = atomic_exchange_relaxed
+			  (&rwlock->__data.__writers_futex, 0);
+		      while ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
+			{
+			  /* While we don't need to make anything from a
+			     caller's critical section visible to other
+			     threads, we need to ensure that our changes to
+			     __writers_futex are properly ordered.
+			     Therefore, use release MO to synchronize with
+			     subsequent primary writers.  Also wake up any
+			     waiting readers as they are waiting because of
+			     us.  */
+			  if (atomic_compare_exchange_weak_release
+			      (&rwlock->__data.__readers, &r,
+			       (r ^ PTHREAD_RWLOCK_WRLOCKED)
+			       & ~(unsigned int) PTHREAD_RWLOCK_RWAITING))
+			    {
+			      /* Wake other writers.  */
+			      if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0)
+				futex_wake (&rwlock->__data.__writers_futex,
+				    1, private);
+			      /* Wake waiting readers.  */
+			      if ((r & PTHREAD_RWLOCK_RWAITING) != 0)
+				futex_wake (&rwlock->__data.__readers,
+				    INT_MAX, private);
+			      return ETIMEDOUT;
+			    }
+			}
+		      /* We still own WRLOCKED and someone else might set a
+			 write phase concurrently, so enable waiting again.
+			 Make sure we don't loose the flag that signals
+			 whether there are threads waiting on this futex.  */
+		      atomic_store_relaxed (&rwlock->__data.__writers_futex,
+			  wf);
+		    }
+		  /* Use the acquire MO fence to mirror the steps taken in the
+		     non-timeout case.  Note that the read can happen both
+		     in the atomic_load above as well as in the failure case
+		     of the CAS operation.  */
+		  atomic_thread_fence_acquire ();
+		  /* We still need to wait for explicit hand-over, but we must
+		     not use futex_wait anymore.  */
+		  while ((atomic_load_relaxed
+		      (&rwlock->__data.__wrphase_futex)
+		       | PTHREAD_RWLOCK_FUTEX_USED)
+		      == PTHREAD_RWLOCK_FUTEX_USED)
+		    {
+		      /* TODO Back-off.  */
+		    }
+		  ready = true;
+		  break;
+		}
+	      /* If we got interrupted (EINTR) or the futex word does not have
+		 the expected value (EAGAIN), retry.  */
+	    }
+	  /* See pthread_rwlock_rdlock_full.  */
+	  if (ready)
+	    break;
+	  if ((atomic_load_acquire (&rwlock->__data.__readers)
+	      & PTHREAD_RWLOCK_WRPHASE) != 0)
+	    ready = true;
+	}
+    }
+
+  atomic_store_relaxed (&rwlock->__data.__cur_writer,
+      THREAD_GETMEM (THREAD_SELF, tid));
+  return 0;
+}
diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
index 383e41e..90e8eaa 100644
--- a/nptl/pthread_rwlock_timedrdlock.c
+++ b/nptl/pthread_rwlock_timedrdlock.c
@@ -35,3 +35,22 @@ pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
 
   return __pthread_rwlock_rdlock_full (rwlock, abstime);
 }
+
+/* 64-bit time version */
+
+int
+__pthread_rwlock_timedrdlock64 (pthread_rwlock_t *rwlock,
+    const struct __timespec64 *abstime)
+{
+  /* Make sure the passed in timeout value is valid.  Note that the previous
+     implementation assumed that this check *must* not be performed if there
+     would in fact be no blocking; however, POSIX only requires that "the
+     validity of the abstime parameter need not be checked if the lock can be
+     immediately acquired" (i.e., we need not but may check it).  */
+  /* ??? Just move this to __pthread_rwlock_rdlock_full?  */
+  if (__glibc_unlikely (abstime->tv_nsec >= 1000000000
+      || abstime->tv_nsec < 0))
+    return EINVAL;
+
+  return __pthread_rwlock_rdlock_full64 (rwlock, abstime);
+}
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
index 7a3d2ec..d4b32aa 100644
--- a/nptl/pthread_rwlock_timedwrlock.c
+++ b/nptl/pthread_rwlock_timedwrlock.c
@@ -35,3 +35,22 @@ pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
 
   return __pthread_rwlock_wrlock_full (rwlock, abstime);
 }
+
+/* 64-bit time version */
+
+int
+__pthread_rwlock_timedwrlock64 (pthread_rwlock_t *rwlock,
+    const struct __timespec64 *abstime)
+{
+  /* Make sure the passed in timeout value is valid.  Note that the previous
+     implementation assumed that this check *must* not be performed if there
+     would in fact be no blocking; however, POSIX only requires that "the
+     validity of the abstime parameter need not be checked if the lock can be
+     immediately acquired" (i.e., we need not but may check it).  */
+  /* ??? Just move this to __pthread_rwlock_wrlock_full?  */
+  if (__glibc_unlikely (abstime->tv_nsec >= 1000000000
+      || abstime->tv_nsec < 0))
+    return EINVAL;
+
+  return __pthread_rwlock_wrlock_full64 (rwlock, abstime);
+}
diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c
index 8886ea2..8a6bfba 100644
--- a/nptl/sem_timedwait.c
+++ b/nptl/sem_timedwait.c
@@ -38,3 +38,21 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
   else
     return __new_sem_wait_slow((struct new_sem *) sem, abstime);
 }
+
+int
+__sem_timedwait64 (sem_t *sem, const struct __timespec64 *abstime)
+{
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* Check sem_wait.c for a more detailed explanation why it is required.  */
+  __pthread_testcancel ();
+
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
+    return 0;
+  else
+    return __new_sem_wait_slow64 ((struct new_sem *) sem, abstime);
+}
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index e7d9106..f59f7f4 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -43,6 +43,30 @@ __new_sem_wait (sem_t *sem)
 }
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
 
+/* 64-bit time version */
+
+int
+__new_sem_wait64 (sem_t *sem)
+{
+  /* We need to check whether we need to act upon a cancellation request here
+     because POSIX specifies that cancellation points "shall occur" in
+     sem_wait and sem_timedwait, which also means that they need to check
+     this regardless whether they block or not (unlike "may occur"
+     functions).  See the POSIX Rationale for this requirement: Section
+     "Thread Cancellation Overview" [1] and austin group issue #1076 [2]
+     for thoughs on why this may be a suboptimal design.
+
+     [1] http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html
+     [2] http://austingroupbugs.net/view.php?id=1076 for thoughts on why this
+   */
+  __pthread_testcancel ();
+
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
+    return 0;
+  else
+    return __new_sem_wait_slow64 ((struct new_sem *) sem, NULL);
+}
+
 #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
 int
 attribute_compat_text_section
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
index 30984be..c75c74b 100644
--- a/nptl/sem_waitcommon.c
+++ b/nptl/sem_waitcommon.c
@@ -119,6 +119,24 @@ do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
   return err;
 }
 
+static int
+__attribute__ ((noinline))
+do_futex_wait64 (struct new_sem *sem, const struct __timespec64 *abstime)
+{
+  int err;
+
+#if __HAVE_64B_ATOMICS
+  err = futex_abstimed_wait_cancelable64 (
+      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, abstime,
+      sem->private);
+#else
+  err = futex_abstimed_wait_cancelable64 (&sem->value, SEM_NWAITERS_MASK,
+					abstime, sem->private);
+#endif
+
+  return err;
+}
+
 /* Fast path: Try to grab a token without blocking.  */
 static int
 __new_sem_wait_fast (struct new_sem *sem, int definitive_result)
@@ -310,6 +328,160 @@ error:
   return err;
 }
 
+/* 64-bit time version */
+
+static int
+__attribute__ ((noinline))
+__new_sem_wait_slow64 (struct new_sem *sem, const struct __timespec64 *abstime)
+{
+  int err = 0;
+
+#if __HAVE_64B_ATOMICS
+  /* Add a waiter.  Relaxed MO is sufficient because we can rely on the
+     ordering provided by the RMW operations we use.  */
+  uint64_t d = atomic_fetch_add_relaxed (&sem->data,
+      (uint64_t) 1 << SEM_NWAITERS_SHIFT);
+
+  pthread_cleanup_push (__sem_wait_cleanup, sem);
+
+  /* Wait for a token to be available.  Retry until we can grab one.  */
+  for (;;)
+    {
+      /* If there is no token available, sleep until there is.  */
+      if ((d & SEM_VALUE_MASK) == 0)
+	{
+	  err = do_futex_wait64 (sem, abstime);
+	  /* A futex return value of 0 or EAGAIN is due to a real or spurious
+	     wake-up, or due to a change in the number of tokens.  We retry in
+	     these cases.
+	     If we timed out, forward this to the caller.
+	     EINTR is returned if we are interrupted by a signal; we
+	     forward this to the caller.  (See futex_wait and related
+	     documentation.  Before Linux 2.6.22, EINTR was also returned on
+	     spurious wake-ups; we only support more recent Linux versions,
+	     so do not need to consider this here.)  */
+	  if (err == ETIMEDOUT || err == EINTR)
+	    {
+	      __set_errno (err);
+	      err = -1;
+	      /* Stop being registered as a waiter.  */
+	      atomic_fetch_add_relaxed (&sem->data,
+		  -((uint64_t) 1 << SEM_NWAITERS_SHIFT));
+	      break;
+	    }
+	  /* Relaxed MO is sufficient; see below.  */
+	  d = atomic_load_relaxed (&sem->data);
+	}
+      else
+	{
+	  /* Try to grab both a token and stop being a waiter.  We need
+	     acquire MO so this synchronizes with all token providers (i.e.,
+	     the RMW operation we read from or all those before it in
+	     modification order; also see sem_post).  On the failure path,
+	     relaxed MO is sufficient because we only eventually need the
+	     up-to-date value; the futex_wait or the CAS perform the real
+	     work.  */
+	  if (atomic_compare_exchange_weak_acquire (&sem->data,
+	      &d, d - 1 - ((uint64_t) 1 << SEM_NWAITERS_SHIFT)))
+	    {
+	      err = 0;
+	      break;
+	    }
+	}
+    }
+
+  pthread_cleanup_pop (0);
+#else
+  /* The main difference to the 64b-atomics implementation is that we need to
+     access value and nwaiters in separate steps, and that the nwaiters bit
+     in the value can temporarily not be set even if nwaiters is nonzero.
+     We work around incorrectly unsetting the nwaiters bit by letting sem_wait
+     set the bit again and waking the number of waiters that could grab a
+     token.  There are two additional properties we need to ensure:
+     (1) We make sure that whenever unsetting the bit, we see the increment of
+     nwaiters by the other thread that set the bit.  IOW, we will notice if
+     we make a mistake.
+     (2) When setting the nwaiters bit, we make sure that we see the unsetting
+     of the bit by another waiter that happened before us.  This avoids having
+     to blindly set the bit whenever we need to block on it.  We set/unset
+     the bit while having incremented nwaiters (i.e., are a registered
+     waiter), and the problematic case only happens when one waiter indeed
+     followed another (i.e., nwaiters was never larger than 1); thus, this
+     works similarly as with a critical section using nwaiters (see the MOs
+     and related comments below).
+
+     An alternative approach would be to unset the bit after decrementing
+     nwaiters; however, that would result in needing Dekker-like
+     synchronization and thus full memory barriers.  We also would not be able
+     to prevent misspeculation, so this alternative scheme does not seem
+     beneficial.  */
+  unsigned int v;
+
+  /* Add a waiter.  We need acquire MO so this synchronizes with the release
+     MO we use when decrementing nwaiters below; it ensures that if another
+     waiter unset the bit before us, we see that and set it again.  Also see
+     property (2) above.  */
+  atomic_fetch_add_acquire (&sem->nwaiters, 1);
+
+  pthread_cleanup_push (__sem_wait_cleanup, sem);
+
+  /* Wait for a token to be available.  Retry until we can grab one.  */
+  /* We do not need any ordering wrt. to this load's reads-from, so relaxed
+     MO is sufficient.  The acquire MO above ensures that in the problematic
+     case, we do see the unsetting of the bit by another waiter.  */
+  v = atomic_load_relaxed (&sem->value);
+  do
+    {
+      do
+	{
+	  /* We are about to block, so make sure that the nwaiters bit is
+	     set.  We need release MO on the CAS to ensure that when another
+	     waiter unsets the nwaiters bit, it will also observe that we
+	     incremented nwaiters in the meantime (also see the unsetting of
+	     the bit below).  Relaxed MO on CAS failure is sufficient (see
+	     above).  */
+	  do
+	    {
+	      if ((v & SEM_NWAITERS_MASK) != 0)
+		break;
+	    }
+	  while (!atomic_compare_exchange_weak_release (&sem->value,
+	      &v, v | SEM_NWAITERS_MASK));
+	  /* If there is no token, wait.  */
+	  if ((v >> SEM_VALUE_SHIFT) == 0)
+	    {
+	      /* See __HAVE_64B_ATOMICS variant.  */
+	      err = do_futex_wait64 (sem, abstime);
+	      if (err == ETIMEDOUT || err == EINTR)
+		{
+		  __set_errno (err);
+		  err = -1;
+		  goto error;
+		}
+	      err = 0;
+	      /* We blocked, so there might be a token now.  Relaxed MO is
+		 sufficient (see above).  */
+	      v = atomic_load_relaxed (&sem->value);
+	    }
+	}
+      /* If there is no token, we must not try to grab one.  */
+      while ((v >> SEM_VALUE_SHIFT) == 0);
+    }
+  /* Try to grab a token.  We need acquire MO so this synchronizes with
+     all token providers (i.e., the RMW operation we read from or all those
+     before it in modification order; also see sem_post).  */
+  while (!atomic_compare_exchange_weak_acquire (&sem->value,
+      &v, v - (1 << SEM_VALUE_SHIFT)));
+
+error:
+  pthread_cleanup_pop (0);
+
+  __sem_wait_32_finish (sem);
+#endif
+
+  return err;
+}
+
 /* Stop being a registered waiter (non-64b-atomics code only).  */
 #if !__HAVE_64B_ATOMICS
 static void
diff --git a/rt/Versions b/rt/Versions
index 4844d6b..e57de23 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -44,5 +44,6 @@ librt {
    __timerfd_settime64;
    __mq_timedreceive64;
    __mq_timedsend_time64;
+   __aio_suspend64;
   }
 }
diff --git a/sysdeps/nptl/aio_misc.h b/sysdeps/nptl/aio_misc.h
index 206d8e1..24c2852 100644
--- a/sysdeps/nptl/aio_misc.h
+++ b/sysdeps/nptl/aio_misc.h
@@ -71,4 +71,43 @@
       }									      \
   } while (0)
 
+#define AIO_MISC_WAIT_T64(result, futex, timeout, cancel)		      \
+  do {									      \
+    volatile unsigned int *futexaddr = &futex;				      \
+    unsigned int oldval = futex;					      \
+									      \
+    if (oldval != 0)							      \
+      {									      \
+	pthread_mutex_unlock (&__aio_requests_mutex);			      \
+									      \
+	int oldtype;							      \
+	if (cancel)							      \
+	  oldtype = LIBC_CANCEL_ASYNC ();				      \
+									      \
+	int status;							      \
+	do								      \
+	  {								      \
+	    status = futex_reltimed_wait64 ((unsigned int *) futexaddr,     \
+					      oldval, timeout, FUTEX_PRIVATE);\
+	    if (status != EAGAIN)					      \
+	      break;							      \
+									      \
+	    oldval = *futexaddr;					      \
+	  }								      \
+	while (oldval != 0);						      \
+									      \
+	if (cancel)							      \
+	  LIBC_CANCEL_RESET (oldtype);					      \
+									      \
+	if (status == EINTR)						      \
+	  result = EINTR;						      \
+	else if (status == ETIMEDOUT)					      \
+	  result = EAGAIN;						      \
+	else								      \
+	  assert (status == 0 || status == EAGAIN);			      \
+									      \
+	pthread_mutex_lock (&__aio_requests_mutex);			      \
+      }									      \
+  } while (0)
+
 #include_next <aio_misc.h>
diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h
index bfbda99..7784ce7 100644
--- a/sysdeps/nptl/lowlevellock.h
+++ b/sysdeps/nptl/lowlevellock.h
@@ -122,6 +122,10 @@ extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
 extern int __lll_timedlock_wait (int *futex, const struct timespec *,
 				 int private) attribute_hidden;
 
+extern int __lll_timedlock_wait64 (int *futex,
+                                     const struct __timespec64 *,
+				     int private) attribute_hidden;
+
 
 /* As __lll_lock, but with a timeout.  If the timeout occurs then return
    ETIMEDOUT.  If ABSTIME is invalid, return EINVAL.  */
@@ -138,6 +142,19 @@ extern int __lll_timedlock_wait (int *futex, const struct timespec *,
 #define lll_timedlock(futex, abstime, private)  \
   __lll_timedlock (&(futex), abstime, private)
 
+#define __lll_timedlock64(futex, abstime, private)                \
+  ({                                                                \
+    int *__futex = (futex);                                         \
+    int __val = 0;                                                  \
+                                                                    \
+    if (__glibc_unlikely                                            \
+        (atomic_compare_and_exchange_bool_acq (__futex, 1, 0)))     \
+      __val = __lll_timedlock_wait64 (__futex, abstime, private); \
+    __val;                                                          \
+  })
+#define lll_timedlock64(futex, abstime, private)  \
+  __lll_timedlock64 (&(futex), abstime, private)
+
 
 /* This is an expression rather than a statement even though its value is
    void, so that it can be used in a comma expression or as an expression
diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c
index 010cbf8..a14263d 100644
--- a/sysdeps/pthread/aio_suspend.c
+++ b/sysdeps/pthread/aio_suspend.c
@@ -251,3 +251,167 @@ aio_suspend (const struct aiocb *const list[], int nent,
 }
 
 weak_alias (aio_suspend, aio_suspend64)
+
+#ifdef DONT_NEED_AIO_MISC_COND
+static int
+__attribute__ ((noinline))
+do_aio_misc_wait64 (unsigned int *cntr, 
+		      const struct __timespec64 *timeout)
+{
+  int result = 0;
+
+  AIO_MISC_WAIT_T64 (result, *cntr, timeout, 1);
+
+  return result;
+}
+#endif
+
+int
+__aio_suspend64 (const struct aiocb *const list[], int nent,
+	         const struct __timespec64 *timeout)
+{
+  if (__glibc_unlikely (nent < 0))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  struct waitlist waitlist[nent];
+  struct requestlist *requestlist[nent];
+#ifndef DONT_NEED_AIO_MISC_COND
+  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+#endif
+  int cnt;
+  bool any = false;
+  int result = 0;
+  unsigned int cntr = 1;
+
+  /* Request the mutex.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
+
+  /* There is not yet a finished request.  Signal the request that
+     we are working for it.  */
+  for (cnt = 0; cnt < nent; ++cnt)
+    if (list[cnt] != NULL)
+      {
+	if (list[cnt]->__error_code == EINPROGRESS)
+	  {
+	    requestlist[cnt] = __aio_find_req ((aiocb_union *) list[cnt]);
+
+	    if (requestlist[cnt] != NULL)
+	      {
+#ifndef DONT_NEED_AIO_MISC_COND
+		waitlist[cnt].cond = &cond;
+#endif
+		waitlist[cnt].result = NULL;
+		waitlist[cnt].next = requestlist[cnt]->waiting;
+		waitlist[cnt].counterp = &cntr;
+		waitlist[cnt].sigevp = NULL;
+#ifdef BROKEN_THREAD_SIGNALS
+		waitlist[cnt].caller_pid = 0;	/* Not needed.  */
+#endif
+		requestlist[cnt]->waiting = &waitlist[cnt];
+		any = true;
+	      }
+	    else
+	      /* We will never suspend.  */
+	      break;
+	  }
+	else
+	  /* We will never suspend.  */
+	  break;
+      }
+
+
+  /* Only if none of the entries is NULL or finished to be wait.  */
+  if (cnt == nent && any)
+    {
+      struct clparam clparam =
+	{
+	  .list = list,
+	  .waitlist = waitlist,
+	  .requestlist = requestlist,
+#ifndef DONT_NEED_AIO_MISC_COND
+	  .cond = &cond,
+#endif
+	  .nent = nent
+	};
+
+      pthread_cleanup_push (cleanup, &clparam);
+
+#ifdef DONT_NEED_AIO_MISC_COND
+      result = do_aio_misc_wait64 (&cntr, timeout);
+#else
+      if (timeout == NULL)
+	result = pthread_cond_wait (&cond, &__aio_requests_mutex);
+      else
+	{
+	  /* We have to convert the relative timeout value into an
+	     absolute time value with pthread_cond_timedwait expects.  */
+	  struct timeval now;
+	  struct timespec abstime;
+
+	  __gettimeofday (&now, NULL);
+	  abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
+	  abstime.tv_sec = timeout->tv_sec + now.tv_sec;
+	  if (abstime.tv_nsec >= 1000000000)
+	    {
+	      abstime.tv_nsec -= 1000000000;
+	      abstime.tv_sec += 1;
+	    }
+
+	  result = __pthread_cond_timedwait64 (&cond,
+					       &__aio_requests_mutex,
+					       &abstime);
+	}
+#endif
+
+      pthread_cleanup_pop (0);
+    }
+
+  /* Now remove the entry in the waiting list for all requests
+     which didn't terminate.  */
+  while (cnt-- > 0)
+    if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS)
+      {
+	struct waitlist **listp;
+
+	assert (requestlist[cnt] != NULL);
+
+	/* There is the chance that we cannot find our entry anymore. This
+	   could happen if the request terminated and restarted again.  */
+	listp = &requestlist[cnt]->waiting;
+	while (*listp != NULL && *listp != &waitlist[cnt])
+	  listp = &(*listp)->next;
+
+	if (*listp != NULL)
+	  *listp = (*listp)->next;
+      }
+
+#ifndef DONT_NEED_AIO_MISC_COND
+  /* Release the conditional variable.  */
+  if (__glibc_unlikely (pthread_cond_destroy (&cond) != 0))
+    /* This must never happen.  */
+    abort ();
+#endif
+
+  if (result != 0)
+    {
+#ifndef DONT_NEED_AIO_MISC_COND
+      /* An error occurred.  Possibly it's ETIMEDOUT.  We have to translate
+	 the timeout error report of `pthread_cond_timedwait' to the
+	 form expected from `aio_suspend'.  */
+      if (result == ETIMEDOUT)
+	__set_errno (EAGAIN);
+      else
+#endif
+	__set_errno (result);
+
+      result = -1;
+    }
+
+  /* Release the mutex.  */
+  pthread_mutex_unlock (&__aio_requests_mutex);
+
+  return result;
+}
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index af82a4c..e1a2ade 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -27,6 +27,9 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.29 __pthread_cond_timedwait64 F
+GLIBC_2.29 __pthread_mutex_timedlock64 F
+GLIBC_2.29 __sem_timedwait64 F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
 GLIBC_2.4 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index 58e5f4b..88b61f3 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.29 __aio_suspend64 F
 GLIBC_2.29 __mq_timedreceive64 F
 GLIBC_2.29 __mq_timedsend_time64 F
 GLIBC_2.29 __timer_gettime64 F
diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
index 96a07b0..484c8be 100644
--- a/sysdeps/unix/sysv/linux/futex-internal.h
+++ b/sysdeps/unix/sysv/linux/futex-internal.h
@@ -131,6 +131,32 @@ futex_reltimed_wait (unsigned int *futex_word, unsigned int expected,
     }
 }
 
+/* 64-bit time version */
+static __always_inline int
+futex_reltimed_wait64 (unsigned int *futex_word, unsigned int expected,
+		         const struct __timespec64 *reltime, int private)
+{
+  int err = lll_futex_timed_wait64 (futex_word, expected, reltime,
+                                      private);
+  switch (err)
+    {
+    case 0:
+    case -EAGAIN:
+    case -EINTR:
+    case -ETIMEDOUT:
+      return -err;
+
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
+    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
+		     being normalized.  Must have been caused by a glibc or
+		     application bug.  */
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      futex_fatal_error ();
+    }
+}
+
 /* See sysdeps/nptl/futex-internal.h for details.  */
 static __always_inline int
 futex_reltimed_wait_cancelable (unsigned int *futex_word,
@@ -160,6 +186,37 @@ futex_reltimed_wait_cancelable (unsigned int *futex_word,
     }
 }
 
+/* 64-bit time version */
+
+static __always_inline int
+futex_reltimed_wait_cancelable64 (unsigned int *futex_word,
+				    unsigned int expected,
+			            const struct __timespec64 *reltime,
+                                    int private)
+{
+  int oldtype;
+  oldtype = __pthread_enable_asynccancel ();
+  int err = lll_futex_timed_wait64 (futex_word, expected, reltime, private);
+  __pthread_disable_asynccancel (oldtype);
+  switch (err)
+    {
+    case 0:
+    case -EAGAIN:
+    case -EINTR:
+    case -ETIMEDOUT:
+      return -err;
+
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
+    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
+		     being normalized.  Must have been caused by a glibc or
+		     application bug.  */
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      futex_fatal_error ();
+    }
+}
+
 /* See sysdeps/nptl/futex-internal.h for details.  */
 static __always_inline int
 futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
@@ -190,6 +247,36 @@ futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
     }
 }
 
+/* 64-bit time version */
+static __always_inline int
+futex_abstimed_wait64 (unsigned int *futex_word, unsigned int expected,
+		         const struct __timespec64 *abstime, int private)
+{
+  /* Work around the fact that the kernel rejects negative timeout values
+     despite them being valid.  */
+  if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
+    return ETIMEDOUT;
+  int err = lll_futex_timed_wait_bitset64 (futex_word, expected, abstime,
+					     FUTEX_CLOCK_REALTIME, private);
+  switch (err)
+    {
+    case 0:
+    case -EAGAIN:
+    case -EINTR:
+    case -ETIMEDOUT:
+      return -err;
+
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
+    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
+		     being normalized.  Must have been caused by a glibc or
+		     application bug.  */
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      futex_fatal_error ();
+    }
+}
+
 /* See sysdeps/nptl/futex-internal.h for details.  */
 static __always_inline int
 futex_abstimed_wait_cancelable (unsigned int *futex_word,
@@ -224,6 +311,42 @@ futex_abstimed_wait_cancelable (unsigned int *futex_word,
     }
 }
 
+/* 64-bit time version */
+
+static __always_inline int
+futex_abstimed_wait_cancelable64 (unsigned int *futex_word,
+				    unsigned int expected,
+			            const struct __timespec64 *abstime,
+                                    int private)
+{
+  /* Work around the fact that the kernel rejects negative timeout values
+     despite them being valid.  */
+  if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
+    return ETIMEDOUT;
+  int oldtype;
+  oldtype = __pthread_enable_asynccancel ();
+  int err = lll_futex_timed_wait_bitset64 (futex_word, expected, abstime,
+					     FUTEX_CLOCK_REALTIME, private);
+  __pthread_disable_asynccancel (oldtype);
+  switch (err)
+    {
+    case 0:
+    case -EAGAIN:
+    case -EINTR:
+    case -ETIMEDOUT:
+      return -err;
+
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
+    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
+		     being normalized.  Must have been caused by a glibc or
+		     application bug.  */
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      futex_fatal_error ();
+    }
+}
+
 /* See sysdeps/nptl/futex-internal.h for details.  */
 static __always_inline void
 futex_wake (unsigned int *futex_word, int processes_to_wake, int private)
diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
index fc834ed..02fc2a5 100644
--- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
+++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
@@ -82,6 +82,16 @@
 		     __lll_private_flag (FUTEX_WAIT, private),  \
 		     val, timeout)
 
+#define lll_futex_timed_wait64(futexp, val, timeout, private)     \
+  ({                                                                       \
+    struct timespec ts;                                                    \
+    ts.tv_sec = timeout->tv_sec;                                           \
+    ts.tv_nsec = timeout->tv_nsec;                                         \
+    lll_futex_syscall (4, futexp,                                 	   \
+		       __lll_private_flag (FUTEX_WAIT, private),  	   \
+		       val, &ts);					   \
+  })
+
 #define lll_futex_timed_wait_bitset(futexp, val, timeout, clockbit, private) \
   lll_futex_syscall (6, futexp,                                         \
 		     __lll_private_flag (FUTEX_WAIT_BITSET | (clockbit), \
@@ -89,6 +99,18 @@
 		     val, timeout, NULL /* Unused.  */,                 \
 		     FUTEX_BITSET_MATCH_ANY)
 
+#define lll_futex_timed_wait_bitset64(futexp, val, timeout, clockbit, private) \
+  ({                                                                       \
+    struct timespec ts;                                                    \
+    ts.tv_sec = timeout->tv_sec;                                           \
+    ts.tv_nsec = timeout->tv_nsec;                                         \
+    lll_futex_syscall (6, futexp,                                          \
+		       __lll_private_flag (FUTEX_WAIT_BITSET | (clockbit), \
+		                           private),                       \
+		       val, &ts, NULL /* Unused.  */,                      \
+		       FUTEX_BITSET_MATCH_ANY);                            \
+  })
+
 #define lll_futex_wake(futexp, nr, private)                             \
   lll_futex_syscall (4, futexp,                                         \
 		     __lll_private_flag (FUTEX_WAKE, private), nr, 0)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index 09e8447..228d45c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -227,6 +227,9 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.29 __pthread_cond_timedwait64 F
+GLIBC_2.29 __pthread_mutex_timedlock64 F
+GLIBC_2.29 __sem_timedwait64 F
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
 GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index 7027d8a..d384de8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -27,6 +27,7 @@ GLIBC_2.2 timer_delete F
 GLIBC_2.2 timer_getoverrun F
 GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
+GLIBC_2.29 __aio_suspend64 F
 GLIBC_2.29 __mq_timedreceive64 F
 GLIBC_2.29 __mq_timedsend_time64 F
 GLIBC_2.29 __timer_gettime64 F

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=799a4c7e8e3a2c2dc03c27a40dae8d0fa4898a88

commit 799a4c7e8e3a2c2dc03c27a40dae8d0fa4898a88
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:09 2017 +0200

    Y2038: add function __setitimer64

diff --git a/time/Makefile b/time/Makefile
index 3e7f008..a502c8d 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -35,7 +35,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    gettimeofday settimeofday adjtime tzset	 \
 	    gettimeofday64 settimeofday64		 \
 	    tzfile getitimer setitimer			 \
-	    getitimer64					 \
+	    getitimer64 setitimer64			 \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
diff --git a/time/Versions b/time/Versions
index 155180e..e7368ac 100644
--- a/time/Versions
+++ b/time/Versions
@@ -88,5 +88,6 @@ libc {
     __adjtime64;
     __adjtimex64;
     __getitimer64;
+    __setitimer64;
   }
 }
diff --git a/time/setitimer64.c b/time/setitimer64.c
new file mode 100644
index 0000000..13133ad
--- /dev/null
+++ b/time/setitimer64.c
@@ -0,0 +1,64 @@
+/* Set an interval timer
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+
+/* 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.  */
+int
+__setitimer64 (enum __itimer_which which,
+                 const struct __itimerval64 *new,
+                 struct __itimerval64 *old)
+{
+  struct itimerval new32, *new32p = NULL;
+  struct itimerval old32, *old32p = NULL;
+
+  if (new != NULL)
+    {
+      if (new->it_interval.tv_sec > INT_MAX ||
+          new->it_value.tv_sec > INT_MAX)
+        {
+          __set_errno (EOVERFLOW);
+          return -1;
+        }
+      new32.it_interval.tv_sec = new->it_interval.tv_sec;
+      new32.it_interval.tv_usec = new->it_interval.tv_usec;
+      new32.it_value.tv_sec = new->it_value.tv_sec;
+      new32.it_value.tv_usec = new->it_value.tv_usec;
+      new32p = &new32;
+    }
+
+  if (old != NULL)
+    old32p = &old32;
+
+  int result = __setitimer(which, new32p, old32p);
+
+  if (old)
+    {
+      old->it_interval.tv_sec = old32.it_interval.tv_sec;
+      old->it_interval.tv_usec = old32.it_interval.tv_usec;
+      old->it_value.tv_sec = old32.it_value.tv_sec;
+      old->it_value.tv_usec = old32.it_value.tv_usec;
+    }
+
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=02c3df4d2df6eed2996b77140dc7d1b186e2f2c5

commit 02c3df4d2df6eed2996b77140dc7d1b186e2f2c5
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:08 2017 +0200

    Y2038: add function __getitimer64

diff --git a/time/Makefile b/time/Makefile
index b8ad2f9..3e7f008 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -35,6 +35,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    gettimeofday settimeofday adjtime tzset	 \
 	    gettimeofday64 settimeofday64		 \
 	    tzfile getitimer setitimer			 \
+	    getitimer64					 \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
diff --git a/time/Versions b/time/Versions
index a965b69..155180e 100644
--- a/time/Versions
+++ b/time/Versions
@@ -87,5 +87,6 @@ libc {
     __utimes64;
     __adjtime64;
     __adjtimex64;
+    __getitimer64;
   }
 }
diff --git a/time/getitimer64.c b/time/getitimer64.c
new file mode 100644
index 0000000..68bcaef
--- /dev/null
+++ b/time/getitimer64.c
@@ -0,0 +1,46 @@
+/* Get the current value of an interval timer
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+
+/* Set *VALUE to the current setting of timer WHICH.
+   Return 0 on success, -1 on errors.  */
+int
+__getitimer64 (enum __itimer_which which,
+                 struct __itimerval64 *value)
+{
+  struct itimerval value32, *value32p= NULL;
+
+  if (value != NULL)
+    value32p = &value32;
+
+  int result = __getitimer(which, value32p);
+
+  if (result == 0 && value != NULL)
+    {
+      value->it_interval.tv_sec = value32.it_interval.tv_sec;
+      value->it_interval.tv_usec = value32.it_interval.tv_usec;
+      value->it_value.tv_sec = value32.it_value.tv_sec;
+      value->it_value.tv_usec = value32.it_value.tv_usec;
+    }
+
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=414831507ab56a5a5248ba5eb57cff0859d10b24

commit 414831507ab56a5a5248ba5eb57cff0859d10b24
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:07 2017 +0200

    Y2038: add struct __itimerval64

diff --git a/time/sys/time.h b/time/sys/time.h
index 4e6255e..b7fe339 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -110,6 +110,16 @@ struct itimerval
     struct timeval it_value;
   };
 
+/* 64-BIT-TIME Type of the second argument to `getitimer' and
+   the second and third arguments `setitimer'.  */
+struct __itimerval64
+  {
+    /* Value to put into `it_value' when the timer expires.  */
+    struct __timeval64 it_interval;
+    /* Time to the next timer expiration.  */
+    struct __timeval64 it_value;
+  };
+
 #if defined __USE_GNU && !defined __cplusplus
 /* Use the nicer parameter type only in GNU mode and not for C++ since the
    strict C++ rules prevent the automatic promotion.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=eb3902cff57710eb5cc64b9bcf6c5b73f2167b73

commit eb3902cff57710eb5cc64b9bcf6c5b73f2167b73
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:06 2017 +0200

    Y2038: add function __utime64

diff --git a/include/utime.h b/include/utime.h
index 5049251..eb907f7 100644
--- a/include/utime.h
+++ b/include/utime.h
@@ -6,4 +6,11 @@
 libc_hidden_proto (utime)
 #endif
 
+/* Structure describing file times, 64-bit time version.  */
+struct __utimbuf64
+  {
+    __time64_t actime;		/* Access time.  */
+    __time64_t modtime;		/* Modification time.  */
+  };
+
 #endif /* utime.h */
diff --git a/io/Makefile b/io/Makefile
index ec5c6d7..34075a8 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -28,7 +28,7 @@ headers := sys/stat.h bits/stat.h sys/statfs.h bits/statfs.h sys/vfs.h \
 	   bits/statx.h utime.h ftw.h fts.h sys/sendfile.h
 
 routines :=								\
-	utime								\
+	utime utime64							\
 	mkfifo mkfifoat							\
 	stat fstat lstat stat64 fstat64 lstat64 fstatat fstatat64	\
 	xstat fxstat lxstat xstat64 fxstat64 lxstat64 statx		\
diff --git a/io/Versions b/io/Versions
index 90956fe..58dca72 100644
--- a/io/Versions
+++ b/io/Versions
@@ -137,6 +137,7 @@ libc {
     __xstat64_time64;
     __lxstat64_time64;
     __fxstatat64_time64;
+    __utime64;
   }
   GLIBC_PRIVATE {
     __libc_fcntl64;
diff --git a/io/utime.c b/io/utime.c
index 3f3c03c..b33296b 100644
--- a/io/utime.c
+++ b/io/utime.c
@@ -38,3 +38,19 @@ utime (const char *file, const struct utimbuf *times)
 libc_hidden_def (utime)
 
 stub_warning (utime)
+
+/* 64-bit time version */
+
+int
+__utime64 (const char *file, const struct __utimbuf64 *times)
+{
+  if (file == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__utime64)
diff --git a/io/utime.c b/sysdeps/posix/utime64.c
similarity index 63%
copy from io/utime.c
copy to sysdeps/posix/utime64.c
index 3f3c03c..1f043da 100644
--- a/io/utime.c
+++ b/sysdeps/posix/utime64.c
@@ -1,5 +1,4 @@
-/* utime -- change access and modification times of file.  Stub version.
-   Copyright (C) 1991-2018 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -16,25 +15,32 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sysdep.h>
 #include <errno.h>
-#include <stddef.h>
 #include <utime.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
 
 
 /* Set the access and modification times of FILE to those given in TIMES.
    If TIMES is NULL, set them to the current time.  */
 int
-utime (const char *file, const struct utimbuf *times)
+__utime64 (const char *file, const struct __utimbuf64 *times)
 {
-  if (file == NULL)
+  struct __timeval64 timevals[2];
+  struct __timeval64 *tvp;
+
+  if (times != NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+      timevals[0].tv_sec = (time_t) times->actime;
+      timevals[0].tv_usec = 0L;
+      timevals[1].tv_sec = (time_t) times->modtime;
+      timevals[1].tv_usec = 0L;
+      tvp = timevals;
     }
+  else
+    tvp = NULL;
 
-  __set_errno (ENOSYS);
-  return -1;
+  return __utimes64 (file, tvp);
 }
-libc_hidden_def (utime)
-
-stub_warning (utime)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1faba5c4e6db6320e8034f5ca0c7fc2ad05de67e

commit 1faba5c4e6db6320e8034f5ca0c7fc2ad05de67e
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:05 2017 +0200

    Y2038: add function __adjtime64, __adjtimex64 and __ntp_adjtime64

diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
index 6edecb7..4238abd 100644
--- a/sysdeps/unix/sysv/linux/adjtime.c
+++ b/sysdeps/unix/sysv/linux/adjtime.c
@@ -19,6 +19,7 @@
 #include <limits.h>
 #include <sys/time.h>
 #include <sys/timex.h>
+#include <include/time.h>
 
 #define MAX_SEC	(INT_MAX / 1000000L - 2)
 #define MIN_SEC	(INT_MIN / 1000000L + 2)
diff --git a/sysdeps/unix/sysv/linux/adjtime64.c b/sysdeps/unix/sysv/linux/adjtime64.c
new file mode 100644
index 0000000..c305717
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/adjtime64.c
@@ -0,0 +1,164 @@
+/* Copyright (C) 1995-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <include/time.h>
+
+#define MAX_SEC	(INT_MAX / 1000000L - 2)
+#define MIN_SEC	(INT_MIN / 1000000L + 2)
+
+#ifndef MOD_OFFSET
+#define modes mode
+#endif
+
+#ifndef TIMEVAL
+#define TIMEVAL timeval
+#endif
+
+#ifndef TIMEX
+#define TIMEX timex
+#endif
+
+#ifndef ADJTIME
+#define ADJTIME __adjtime
+#endif
+
+#ifndef ADJTIMEX
+#define NO_LOCAL_ADJTIME
+#define ADJTIMEX(x) __adjtimex (x)
+#endif
+
+#ifndef LINKAGE
+#define LINKAGE
+#endif
+
+int __adjtime64 (const struct __timeval64 *itv,
+                 struct __timeval64 *otv)
+{
+  struct TIMEX tntx;
+
+  if (itv)
+    {
+      struct TIMEVAL tmp;
+
+      /* We will do some check here. */
+      tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
+      tmp.tv_usec = itv->tv_usec % 1000000L;
+      if (tmp.tv_sec > MAX_SEC || tmp.tv_sec < MIN_SEC)
+	return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+      tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
+      tntx.modes = ADJ_OFFSET_SINGLESHOT;
+    }
+  else
+    tntx.modes = ADJ_OFFSET_SS_READ;
+
+  if (__glibc_unlikely (ADJTIMEX (&tntx) < 0))
+    return -1;
+
+  if (otv)
+    {
+      if (tntx.offset < 0)
+	{
+	  otv->tv_usec = -(-tntx.offset % 1000000);
+	  otv->tv_sec  = -(-tntx.offset / 1000000);
+	}
+      else
+	{
+	  otv->tv_usec = tntx.offset % 1000000;
+	  otv->tv_sec  = tntx.offset / 1000000;
+	}
+    }
+  return 0;
+}
+
+int
+__adjtimex64(struct __timex64 *tx)
+{
+  struct timex tx32;
+
+  if (tx == NULL)
+    {
+      __set_errno (EFAULT);
+      return -1;
+    }
+
+  if ((tx->modes & ADJ_SETOFFSET) != 0 && tx->time.tv_sec > INT_MAX)
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  /* Implement with existing 32-bit time syscall */
+
+  /* Just copy everything */
+  tx32.modes = tx->modes;
+  tx32.offset = tx->offset;
+  tx32.freq = tx->freq;
+  tx32.maxerror = tx->maxerror;
+  tx32.esterror = tx->esterror;
+  tx32.status = tx->status;
+  tx32.constant = tx->constant;
+  tx32.precision = tx->precision;
+  tx32.tolerance = tx->tolerance;
+  tx32.time.tv_sec = tx->time.tv_sec;
+  tx32.time.tv_usec = tx->time.tv_usec;
+  tx32.tick = tx->tick;
+  tx32.ppsfreq = tx->ppsfreq;
+  tx32.jitter = tx->jitter;
+  tx32.shift = tx->shift;
+  tx32.stabil = tx->stabil;
+  tx32.jitcnt = tx->jitcnt;
+  tx32.calcnt = tx->calcnt;
+  tx32.errcnt = tx->errcnt;
+  tx32.stbcnt = tx->stbcnt;
+
+  tx32.tai = tx->tai;
+  /* WARNING -- anonymous fields after TAI are not copied. */
+
+  int result = ADJTIMEX(&tx32);
+
+  if (result == 0)
+    {
+      /* Just copy back everything */
+      tx->modes = tx32.modes;
+      tx->offset = tx32.offset;
+      tx->freq = tx32.freq;
+      tx->maxerror = tx32.maxerror;
+      tx->esterror = tx32.esterror;
+      tx->status = tx32.status;
+      tx->constant = tx32.constant;
+      tx->precision = tx32.precision;
+      tx->tolerance = tx32.tolerance;
+      tx->time.tv_sec = tx32.time.tv_sec;
+      tx->time.tv_usec = tx32.time.tv_usec;
+      tx->tick = tx32.tick;
+      tx->ppsfreq = tx32.ppsfreq;
+      tx->jitter = tx32.jitter;
+      tx->shift = tx32.shift;
+      tx->stabil = tx32.stabil;
+      tx->jitcnt = tx32.jitcnt;
+      tx->calcnt = tx32.calcnt;
+      tx->errcnt = tx32.errcnt;
+      tx->stbcnt = tx32.stbcnt;
+    }
+
+  return result;
+}
+weak_alias (__adjtimex64, __ntp_adjtime64);
diff --git a/time/Versions b/time/Versions
index c28dab6..a965b69 100644
--- a/time/Versions
+++ b/time/Versions
@@ -85,5 +85,7 @@ libc {
     __time64;
     __stime64;
     __utimes64;
+    __adjtime64;
+    __adjtimex64;
   }
 }
diff --git a/time/adjtime.c b/time/adjtime.c
index 4a972d6..800715c 100644
--- a/time/adjtime.c
+++ b/time/adjtime.c
@@ -31,3 +31,13 @@ __adjtime (const struct timeval *delta, struct timeval *olddelta)
 stub_warning (adjtime)
 
 weak_alias (__adjtime, adjtime)
+
+/* 64-bit time version */
+
+int
+__adjtime64 (const struct __timeval64 *delta, struct __timeval64 *olddelta)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__adjtime64)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b0cd7e929c5d8b809ec523eec408336ff78f1cb2

commit b0cd7e929c5d8b809ec523eec408336ff78f1cb2
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:04 2017 +0200

    Y2038: add function __nanosleep64

diff --git a/posix/Makefile b/posix/Makefile
index a66d6db..f40096c 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -63,7 +63,7 @@ routines :=								      \
 	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree	      \
-	sched_rr_gi64
+	sched_rr_gi64 nanosleep64
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
diff --git a/posix/Versions b/posix/Versions
index deb1be1..56b8f6f 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -139,6 +139,7 @@ libc {
   }
   GLIBC_2.29 {
     __sched_rr_get_interval_time64;
+    __nanosleep64;
   }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
diff --git a/posix/nanosleep64.c b/posix/nanosleep64.c
new file mode 100644
index 0000000..ae4805d
--- /dev/null
+++ b/posix/nanosleep64.c
@@ -0,0 +1,56 @@
+/* Pause execution for a number of nanoseconds
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+
+/* Pause execution for a number of nanoseconds.  */
+int
+__nanosleep64 (const struct __timespec64 *requested_time,
+	         struct __timespec64 *remaining)
+{
+  struct timespec treq32, *treqp32 = NULL;
+  struct timespec trem32, *tremp32 = NULL;
+
+  if (requested_time)
+    {
+      if (requested_time->tv_sec > INT_MAX)
+        {
+          __set_errno(EOVERFLOW);
+          return -1;
+        }
+      treq32.tv_sec = requested_time->tv_sec;
+      treq32.tv_nsec = requested_time->tv_nsec;
+      treqp32 = & treq32;
+    }
+
+  if (remaining)
+    tremp32 = &trem32;
+
+  int result = __nanosleep(treqp32, tremp32);
+
+  if (result == 1 && errno == EINTR && remaining)
+    {
+      remaining->tv_sec = trem32.tv_sec;
+      remaining->tv_nsec = trem32.tv_nsec;
+      remaining->tv_pad = 0;
+    }
+
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c284a9894f43bc668363b8d6a790554ab32e51ec

commit c284a9894f43bc668363b8d6a790554ab32e51ec
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:03 2017 +0200

    Y2038: add function __sched_rr_get_interval64

diff --git a/posix/Makefile b/posix/Makefile
index 8316212..a66d6db 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -62,7 +62,8 @@ routines :=								      \
 	spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \
 	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
 	posix_madvise							      \
-	get_child_max sched_cpucount sched_cpualloc sched_cpufree
+	get_child_max sched_cpucount sched_cpualloc sched_cpufree	      \
+	sched_rr_gi64
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
diff --git a/posix/Versions b/posix/Versions
index cad4c23..deb1be1 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -137,6 +137,9 @@ libc {
   GLIBC_2.27 {
     glob; glob64;
   }
+  GLIBC_2.29 {
+    __sched_rr_get_interval_time64;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/sched_rr_gi64.c b/posix/sched_rr_gi64.c
new file mode 100644
index 0000000..35dc938
--- /dev/null
+++ b/posix/sched_rr_gi64.c
@@ -0,0 +1,55 @@
+/* Get the SCHED_RR interval for the named process.
+  
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sched.h>
+#include <sys/types.h>
+#include <y2038-support.h>
+
+int
+__sched_rr_get_interval_time64 (pid_t pid, struct __timespec64 *t)
+{
+  struct timespec ts32;
+  int result;
+
+  if (t == NULL)
+    {
+      __set_errno(EINVAL);
+      return -1;
+    }
+
+#ifdef __NR_sched_rr_get_interval_time64
+  if (__y2038_linux_support > 0)
+    {
+      result = INLINE_SYSCALL(sched_rr_get_interval_time64, 2, pid, t);
+      if (result == 0 || errno != ENOSYS)
+        return result;
+      __y2038_linux_support = -1;
+    }
+#endif
+
+  result = __sched_rr_get_interval(pid, &ts32);
+  if (result == 0)
+    {
+      t->tv_sec = ts32.tv_sec;
+      t->tv_nsec = ts32.tv_nsec;
+      t->tv_pad = 0;
+    }
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4ad7d283660e18fb796e1a959cc99b55fd25c5c9

commit 4ad7d283660e18fb796e1a959cc99b55fd25c5c9
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:02 2017 +0200

    Y2038: add function __msgctl64

diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
index 7280cba..f785804 100644
--- a/sysdeps/unix/sysv/linux/msgctl.c
+++ b/sysdeps/unix/sysv/linux/msgctl.c
@@ -69,3 +69,60 @@ __old_msgctl (int msqid, int cmd, struct __old_msqid_ds *buf)
 }
 compat_symbol (libc, __old_msgctl, msgctl, GLIBC_2_0);
 #endif
+
+/* 64-bit time version */
+
+struct __msqid_ds64
+{
+  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 msgrcv command */
+  __time64_t msg_ctime;		/* time of last change */
+  unsigned long int __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() */
+  unsigned long int __glibc_reserved4;
+  unsigned long int __glibc_reserved5;
+};
+
+int
+__msgctl64 (int msqid, int cmd, struct __msqid_ds64 *buf)
+{
+  int result;
+  struct msqid_ds buf32, *pbuf32 = NULL;
+
+  if (cmd == IPC_SET && buf != NULL)
+    {
+      buf32.msg_qbytes = buf->msg_qbytes;
+      buf32.msg_perm.uid = buf->msg_perm.uid;
+      buf32.msg_perm.gid = buf->msg_perm.gid;
+      buf32.msg_perm.mode = buf->msg_perm.mode;
+    }
+
+  if (cmd == IPC_SET || cmd == IPC_STAT)
+    pbuf32 = &buf32;
+
+#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+  result = INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, pbuf32);
+#else
+  result = INLINE_SYSCALL_CALL (ipc, IPCOP_msgctl, msqid, cmd | __IPC_64,
+                                0, pbuf32);
+#endif
+
+  if (cmd == IPC_STAT && result == 0 && buf != NULL)
+    {
+      buf->msg_perm = buf32.msg_perm;
+      buf->msg_stime = buf32.msg_stime;
+      buf->msg_rtime = buf32.msg_rtime;
+      buf->msg_ctime = buf32.msg_ctime;
+      buf->__msg_cbytes = buf32.__msg_cbytes;
+      buf->msg_qnum = buf32.msg_qnum;
+      buf->msg_qbytes = buf32.msg_qbytes;
+      buf->msg_lspid = buf32.msg_lspid;
+      buf->msg_lrpid = buf32.msg_lrpid;
+    }
+
+  return result;
+}
diff --git a/sysvipc/Versions b/sysvipc/Versions
index 4c797e2..0e7f297 100644
--- a/sysvipc/Versions
+++ b/sysvipc/Versions
@@ -13,6 +13,9 @@ libc {
     # Non-standard function.
     semtimedop;
   }
+  GLIBC_2.28 {
+    __msgctl64;
+  }
   GLIBC_PRIVATE {
     # Cancellation point entries.
     __libc_msgrcv; __libc_msgsnd;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=19b79c87090802853d38c3bccf929942ab7d532a

commit 19b79c87090802853d38c3bccf929942ab7d532a
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:01 2017 +0200

    Y2038: add function __mq_timedsend_time64

diff --git a/rt/Makefile b/rt/Makefile
index 928f90e..f6011f4 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -38,7 +38,7 @@ shm-routines   := shm_open shm_unlink
 mq-routines    := mq_open mq_close mq_unlink mq_getattr mq_setattr	\
 		  mq_notify mq_send mq_receive mq_timedsend		\
 		  mq_timedreceive					\
-		  mq_timedreceiv_time64
+		  mq_timedreceiv_time64 mq_timedsend_time64
 
 routines = $(clock-routines)
 
diff --git a/rt/Versions b/rt/Versions
index 25202cf..4844d6b 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -43,5 +43,6 @@ librt {
    __timerfd_gettime64;
    __timerfd_settime64;
    __mq_timedreceive64;
+   __mq_timedsend_time64;
   }
 }
diff --git a/rt/mq_timedsend_time64.c b/rt/mq_timedsend_time64.c
new file mode 100644
index 0000000..7459d94
--- /dev/null
+++ b/rt/mq_timedsend_time64.c
@@ -0,0 +1,52 @@
+/* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
+   on full message queue if ABS_TIMEOUT expires.
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <y2038-support.h>
+
+/* 64-bit time version */
+
+int
+__mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+		  unsigned int msg_prio, const struct __timespec64 *abs_timeout)
+{
+  struct timespec ts32, *tsp32 = NULL;
+#ifdef __NR_mq_timedsend_time64
+  int result;
+  
+  if (__y2038_get_kernel_support () > 0)
+    {
+      result = INLINE_SYSCALL (mq_timedsend_time64, 5, mqdes, msg_ptr,
+			       msg_len, msg_prio, abs_timeout);
+      if (result == 0 || errno != ENOSYS)
+        return result;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  if (abs_timeout)
+    {
+      ts32.tv_sec = abs_timeout->tv_sec;
+      ts32.tv_nsec = abs_timeout->tv_nsec;
+      tsp32 = &ts32;
+    }
+  return mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, tsp32);
+}
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index a056a93..58e5f4b 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,4 +1,5 @@
 GLIBC_2.29 __mq_timedreceive64 F
+GLIBC_2.29 __mq_timedsend_time64 F
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
 GLIBC_2.29 __timerfd_gettime64 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index 8142325..7027d8a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -28,6 +28,7 @@ GLIBC_2.2 timer_getoverrun F
 GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
 GLIBC_2.29 __mq_timedreceive64 F
+GLIBC_2.29 __mq_timedsend_time64 F
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
 GLIBC_2.29 __timerfd_gettime64 F

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=462d3f076eaf77f5b2c2c8ca36d1509bd063c933

commit 462d3f076eaf77f5b2c2c8ca36d1509bd063c933
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:42:00 2017 +0200

    Y2038: add function __mq_timedreceiv_time64

diff --git a/rt/Makefile b/rt/Makefile
index 994891e..928f90e 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -37,7 +37,8 @@ timer-routines := timer_create timer_delete timer_getoverr		\
 shm-routines   := shm_open shm_unlink
 mq-routines    := mq_open mq_close mq_unlink mq_getattr mq_setattr	\
 		  mq_notify mq_send mq_receive mq_timedsend		\
-		  mq_timedreceive
+		  mq_timedreceive					\
+		  mq_timedreceiv_time64
 
 routines = $(clock-routines)
 
diff --git a/rt/Versions b/rt/Versions
index 8f757ed..25202cf 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -42,5 +42,6 @@ librt {
    __timer_settime64;
    __timerfd_gettime64;
    __timerfd_settime64;
+   __mq_timedreceive64;
   }
 }
diff --git a/rt/mq_timedreceiv_time64.c b/rt/mq_timedreceiv_time64.c
new file mode 100644
index 0000000..6d94efe
--- /dev/null
+++ b/rt/mq_timedreceiv_time64.c
@@ -0,0 +1,54 @@
+/* Receive the oldest from highest priority messages in message queue
+   MQDES, stop waiting if ABS_TIMEOUT expires.
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <y2038-support.h>
+
+/* 64-bit time version */
+
+ssize_t
+__mq_timedreceiv_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
+			 unsigned int *__restrict msg_prio,
+			 const struct __timespec64 *__restrict abs_timeout)
+{
+  struct timespec ts32, *tsp32 = NULL;
+
+#ifdef __NR_timedreceiv_time64
+  int result;
+
+  if (__y2038_get_kernel_support () > 0)
+    {
+      result = INLINE_SYSCALL (mq_timedreceiv_time64, 5, mqdes, msg_ptr, msg_len,
+			       msg_prio, abs_timeout);
+      if (result == 0 || errno != ENOSYS)
+	return result;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  if (abs_timeout)
+    {
+      ts32.tv_sec = abs_timeout->tv_sec;
+      ts32.tv_nsec = abs_timeout->tv_nsec;
+      tsp32 = &ts32;
+    }
+  return mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, tsp32);
+}
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index 344fa5b..a056a93 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.29 __mq_timedreceive64 F
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
 GLIBC_2.29 __timerfd_gettime64 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index f34ae35..8142325 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -27,6 +27,7 @@ GLIBC_2.2 timer_delete F
 GLIBC_2.2 timer_getoverrun F
 GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
+GLIBC_2.29 __mq_timedreceive64 F
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
 GLIBC_2.29 __timerfd_gettime64 F

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=40f904cd8244379f20520a405fef7a4da4b139a3

commit 40f904cd8244379f20520a405fef7a4da4b139a3
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:57 2017 +0200

    Y2038: add function __utimes64

diff --git a/include/time.h b/include/time.h
index b482ac3..70af625 100644
--- a/include/time.h
+++ b/include/time.h
@@ -35,6 +35,9 @@ extern int __clock_nanosleep64 (clockid_t __clock_id, int __flags,
 				const struct __timespec64 *__req,
 				struct __timespec64 *__rem);
 
+extern int __utimes64 (const char *file,
+                       const struct __timeval64 tvp[2]);
+
 /* Now define the internal interfaces.  */
 struct tm;
 
diff --git a/misc/Makefile b/misc/Makefile
index 7ced1ea..e306850 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -71,7 +71,7 @@ routines := brk sbrk sstk ioctl \
 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
 	    removexattr setxattr getauxval ifunc-impl-list makedev \
-	    allocate_once y2038-support
+	    allocate_once y2038-support utimes64
 
 generated += tst-error1.mtrace tst-error1-mem.out \
   tst-allocate_once.mtrace tst-allocate_once-mem.out
diff --git a/misc/utimes.c b/misc/utimes.c
index 0ae6946..cdb43f6 100644
--- a/misc/utimes.c
+++ b/misc/utimes.c
@@ -38,3 +38,18 @@ __utimes (const char *file, const struct timeval tvp[2])
 weak_alias (__utimes, utimes)
 
 stub_warning (utimes)
+
+int
+__utimes64 (const char *file, const struct __timeval64 tvp[2])
+{
+  if (file == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__utimes64)
diff --git a/misc/utimes.c b/sysdeps/unix/sysv/linux/utimes64.c
similarity index 52%
copy from misc/utimes.c
copy to sysdeps/unix/sysv/linux/utimes64.c
index 0ae6946..b17f997 100644
--- a/misc/utimes.c
+++ b/sysdeps/unix/sysv/linux/utimes64.c
@@ -1,5 +1,4 @@
-/* utimes -- Change access and modification times of file.  Stub version.
-   Copyright (C) 1991-2018 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2018 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
@@ -16,25 +15,34 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sys/time.h>
 #include <errno.h>
 #include <stddef.h>
+#include <utime.h>
+#include <sys/time.h>
+#include <sysdep.h>
+#include <fcntl.h>
+
+/* 64-bit-time variant */
 
-/* Change the access time of FILE to TVP[0] and
-   the modification time of FILE to TVP[1].  */
 int
-__utimes (const char *file, const struct timeval tvp[2])
+__utimes64 (const char *file, const struct __timeval64 tvp[2])
 {
-  if (file == NULL)
+  struct timespec ts32[2], *tsp32 = NULL;
+
+  if (tvp != NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+      if (tvp[0].tv_sec > INT_MAX || tvp[1].tv_sec > INT_MAX)
+        {
+          __set_errno(EOVERFLOW);
+          return -1;
+        }
+      ts32[0].tv_sec = tvp[0].tv_sec;
+      ts32[0].tv_nsec = tvp[0].tv_usec * 1000;
+      ts32[1].tv_sec = tvp[1].tv_sec;
+      ts32[1].tv_nsec = tvp[1].tv_usec * 1000;
+      tsp32 = ts32;
     }
 
-  __set_errno (ENOSYS);
-  return -1;
+  /* use utimensat rather than utimes which not all arches can use */
+  return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tsp32, 0);
 }
-
-weak_alias (__utimes, utimes)
-
-stub_warning (utimes)
diff --git a/time/Versions b/time/Versions
index e8b63d2..c28dab6 100644
--- a/time/Versions
+++ b/time/Versions
@@ -84,5 +84,6 @@ libc {
     __settimeofday64;
     __time64;
     __stime64;
+    __utimes64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=76a5912a8c907bbdfa3e3b47edb220a8dd968413

commit 76a5912a8c907bbdfa3e3b47edb220a8dd968413
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:56 2017 +0200

    Y2038: add function __stime64
    
    This implementation uses __settimeofday64.
    Therefore, on a system where current time-of-day is 32 bits, this
    implementation will fail for dates beyond Y2038.

diff --git a/time/stime.c b/sysdeps/unix/stime64.c
similarity index 69%
copy from time/stime.c
copy to sysdeps/unix/stime64.c
index 0378e23..2506227 100644
--- a/time/stime.c
+++ b/sysdeps/unix/stime64.c
@@ -1,4 +1,6 @@
-/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
+/* Set the system clock on a unix system 
+
+   Copyright (C) 2018 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
@@ -16,22 +18,30 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
+#include <stddef.h>		/* For NULL.  */
+#include <sys/time.h>
 #include <time.h>
-#include <stddef.h>
 
 /* Set the system clock to *WHEN.  */
 
 int
-stime (const time_t *when)
+__stime64 (const __time64_t *when)
 {
+  struct __timeval64 tv;
+
   if (when == NULL)
     {
       __set_errno (EINVAL);
       return -1;
     }
 
-  __set_errno (ENOSYS);
-  return -1;
-}
+  if (*when > INT_MAX)
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
 
-stub_warning (stime)
+  tv.tv_sec = *when;
+  tv.tv_usec = 0;
+  return __settimeofday64 (&tv, (struct timezone *) 0);
+}
diff --git a/time/Makefile b/time/Makefile
index d4c553f..b8ad2f9 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -31,7 +31,7 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \
-	    time64					 \
+	    time64 stime64				 \
 	    gettimeofday settimeofday adjtime tzset	 \
 	    gettimeofday64 settimeofday64		 \
 	    tzfile getitimer setitimer			 \
diff --git a/time/Versions b/time/Versions
index b5e070f..e8b63d2 100644
--- a/time/Versions
+++ b/time/Versions
@@ -83,5 +83,6 @@ libc {
     __gettimeofday64;
     __settimeofday64;
     __time64;
+    __stime64;
   }
 }
diff --git a/time/stime.c b/time/stime.c
index 0378e23..5d22aaa 100644
--- a/time/stime.c
+++ b/time/stime.c
@@ -35,3 +35,20 @@ stime (const time_t *when)
 }
 
 stub_warning (stime)
+
+/* 64-bit time version */
+
+int
+__stime64 (const __time64_t *when)
+{
+  if (when == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__stime64)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=835baa6c5916b4f59a29a996dc5858e22ccd5eed

commit 835baa6c5916b4f59a29a996dc5858e22ccd5eed
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:55 2017 +0200

    Y2038: add function __time64
    
    This provides a generic Posix implementation based on calling
    __gettimeofday64().

diff --git a/time/time.c b/sysdeps/posix/time64.c
similarity index 57%
copy from time/time.c
copy to sysdeps/posix/time64.c
index 4996d26..4a58228 100644
--- a/time/time.c
+++ b/sysdeps/posix/time64.c
@@ -1,4 +1,6 @@
-/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
+/* Get the 64-bit current time
+ * 
+   Copyright (C) 1991-2018 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
@@ -15,19 +17,27 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
+#include <stddef.h>		/* For NULL.  */
 #include <time.h>
+#include <sys/time.h>
 
-/* Return the time now, and store it in *TIMER if not NULL.  */
-time_t
-time (time_t *timer)
+
+/* Return the current time as a `time_t' and also put it in *T if T is
+   not NULL.  Time is represented as seconds from Jan 1 00:00:00 1970.  */
+
+__time64_t
+__time64 (__time64_t *t)
 {
-  __set_errno (ENOSYS);
+  struct __timeval64 tv;
+  __time64_t result;
 
-  if (timer != NULL)
-    *timer = (time_t) -1;
-  return (time_t) -1;
-}
-libc_hidden_def (time)
+  if (__gettimeofday64 (&tv, (struct timezone *) NULL))
+    result = (__time64_t) -1;
+  else
+    result = tv.tv_sec;
 
-stub_warning (time)
+  if (t != NULL)
+    *t = result;
+
+  return result;
+}
diff --git a/time/Makefile b/time/Makefile
index 8354b26..d4c553f 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -31,6 +31,7 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \
+	    time64					 \
 	    gettimeofday settimeofday adjtime tzset	 \
 	    gettimeofday64 settimeofday64		 \
 	    tzfile getitimer setitimer			 \
diff --git a/time/Versions b/time/Versions
index 1b178e4..b5e070f 100644
--- a/time/Versions
+++ b/time/Versions
@@ -82,5 +82,6 @@ libc {
     __lutimes64;
     __gettimeofday64;
     __settimeofday64;
+    __time64;
   }
 }
diff --git a/time/time.c b/time/time.c
index 4996d26..9703c72 100644
--- a/time/time.c
+++ b/time/time.c
@@ -31,3 +31,16 @@ time (time_t *timer)
 libc_hidden_def (time)
 
 stub_warning (time)
+
+/* 64-bit time version */
+
+__time64_t
+__time64 (__time64_ *timer)
+{
+  __set_errno (ENOSYS);
+
+  if (timer != NULL)
+    *timer = (__time64_t) -1;
+  return (__time64_t) -1;
+}
+libc_hidden_def (__time64)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5dbc9352c4a99adc02122bcd209761b8fd373195

commit 5dbc9352c4a99adc02122bcd209761b8fd373195
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:59 2017 +0200

    Y2038: add function __settimeofday64
    
    Implementing a 64-bit settimeofday requires adding a new
    file to build under time/ and we cannot name that new file
    'settimeofday.c' or it will break the 32-bit settimeofday
    file symbol, so we call it 'settimeofday64.c'.

diff --git a/include/sys/time.h b/include/sys/time.h
index ed73a44..792fe84 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -29,6 +29,8 @@ extern int __gettimeofday64 (struct __timeval64 *__tv,
 extern int __settimeofday (const struct timeval *__tv,
 			   const struct timezone *__tz)
 	attribute_hidden;
+extern int __settimeofday64 (const struct __timeval64 *__tv,
+			     const struct timezone *__tz);
 extern int __adjtime (const struct timeval *__delta,
 		      struct timeval *__olddelta);
 extern int __getitimer (enum __itimer_which __which,
diff --git a/time/settimeofday.c b/sysdeps/unix/sysv/linux/settimeofday64.c
similarity index 68%
copy from time/settimeofday.c
copy to sysdeps/unix/sysv/linux/settimeofday64.c
index 01bf4b0..1a9fa23 100644
--- a/time/settimeofday.c
+++ b/sysdeps/unix/sysv/linux/settimeofday64.c
@@ -1,4 +1,6 @@
-/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
+/* Set the current time of day and timezone information.
+
+   Copyright (C) 2018 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
@@ -15,17 +17,23 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sysdep.h>
 #include <errno.h>
 #include <sys/time.h>
 
-/* Set the current time of day and timezone information.
-   This call is restricted to the super-user.  */
-int
-__settimeofday (const struct timeval *tv, const struct timezone *tz)
+int __settimeofday64(const struct __timeval64 *tv,
+                       const struct timezone *tz)
 {
-  __set_errno (ENOSYS);
-  return -1;
-}
-stub_warning (settimeofday)
+  struct timeval tv32;
 
-weak_alias (__settimeofday, settimeofday)
+  if (tv && tv->tv_sec > INT_MAX)
+    {
+      __set_errno(EOVERFLOW);
+      return -1;
+    }
+
+  tv32.tv_sec = tv->tv_sec;
+  tv32.tv_usec = tv->tv_usec;
+
+  return __settimeofday(&tv32, tz);
+}
diff --git a/time/Makefile b/time/Makefile
index c466206..8354b26 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -32,7 +32,7 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \
 	    gettimeofday settimeofday adjtime tzset	 \
-	    gettimeofday64				 \
+	    gettimeofday64 settimeofday64		 \
 	    tzfile getitimer setitimer			 \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
diff --git a/time/Versions b/time/Versions
index f1b4cbf..1b178e4 100644
--- a/time/Versions
+++ b/time/Versions
@@ -81,5 +81,6 @@ libc {
     __futimes64;
     __lutimes64;
     __gettimeofday64;
+    __settimeofday64;
   }
 }
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 01bf4b0..000ed21 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -29,3 +29,11 @@ __settimeofday (const struct timeval *tv, const struct timezone *tz)
 stub_warning (settimeofday)
 
 weak_alias (__settimeofday, settimeofday)
+
+int
+__settimeofday64 (const struct timeval *tv, const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__settimeofday64)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=617ca8fd5f117156847ad4ba32395bcd50bde4a1

commit 617ca8fd5f117156847ad4ba32395bcd50bde4a1
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:58 2017 +0200

    Y2038: add function __gettimeofday64
    
    Implementing a 64-bit settimeofday requires adding a new
    file to build under time/ and we cannot name that new file
    'settimeofday.c' or it will break the 32-bit settimeofday
    symbol, so we call it 'settimeofday64.c'.

diff --git a/include/sys/time.h b/include/sys/time.h
index 98f6b6b..ed73a44 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -24,6 +24,8 @@ extern int __gettimeofday (struct timeval *__tv,
 			   struct timezone *__tz);
 libc_hidden_proto (__gettimeofday)
 libc_hidden_proto (gettimeofday)
+extern int __gettimeofday64 (struct __timeval64 *__tv,
+			     struct timezone *__tz);
 extern int __settimeofday (const struct timeval *__tv,
 			   const struct timezone *__tz)
 	attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/gettimeofday64.c b/sysdeps/unix/sysv/linux/gettimeofday64.c
new file mode 100644
index 0000000..e1538a9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/gettimeofday64.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2015-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sys/time.h>
+
+#undef __gettimeofday
+
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#include <sysdep-vdso.h>
+#endif
+
+/* Get the current time of day and timezone information,
+   putting it into *tv and *tz.  If tz is null, *tz is not filled.
+   Returns 0 on success, -1 on errors.  */
+
+int
+__gettimeofday64 (struct __timeval64 *tv, struct timezone *tz)
+{
+  struct timeval tv32;
+  int result;
+
+#ifdef __vdso_gettimeofday
+  result = INLINE_VSYSCALL (gettimeofday, 2, &tv32, tz);
+#else
+  result = INLINE_SYSCALL (gettimeofday, 2, &tv32, tz);
+#endif
+
+  if (result == 0)
+    {
+      tv->tv_sec = tv32.tv_sec;
+      tv->tv_usec = tv32.tv_usec;
+    }
+
+  return result;
+}
diff --git a/time/Makefile b/time/Makefile
index f784fa1..c466206 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -32,6 +32,7 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \
 	    gettimeofday settimeofday adjtime tzset	 \
+	    gettimeofday64				 \
 	    tzfile getitimer setitimer			 \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
diff --git a/time/Versions b/time/Versions
index f22ce38..f1b4cbf 100644
--- a/time/Versions
+++ b/time/Versions
@@ -80,5 +80,6 @@ libc {
     __sigtimedwait_time64;
     __futimes64;
     __lutimes64;
+    __gettimeofday64;
   }
 }
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index d1ab9ac..e4a67c6 100644
--- a/time/gettimeofday.c
+++ b/time/gettimeofday.c
@@ -16,7 +16,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <sys/time.h>
 
 /* Get the current time of day and timezone information,
    putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
@@ -32,3 +31,13 @@ weak_alias (__gettimeofday, gettimeofday)
 libc_hidden_weak (gettimeofday)
 
 stub_warning (gettimeofday)
+
+/* 64-bit time version */
+
+int
+__gettimeofday64 (struct timeval *tv, struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__gettimeofday64)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c4e1c0ad3670eeef5523275e34d4fefa920791c9

commit c4e1c0ad3670eeef5523275e34d4fefa920791c9
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:54 2017 +0200

    Y2038: add function __fstatat64_time64 (and __fxstatat_time64)
    
    These implementations just use the existing syscalls and convert from
    kernel 32-bit-time struct stat64 to GLIBC Y2038-ready struct __stat64_t64.

diff --git a/include/sys/stat.h b/include/sys/stat.h
index 72aca27..d267dd0 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -42,6 +42,10 @@ extern int __xstat64_time64 (int __ver, const char *__filename,
 			     struct __stat64_t64 *__stat_buf);
 extern int __lxstat64_time64 (int __ver, const char *__filename,
 			      struct __stat64_t64 *__stat_buf);
+extern int __fxstatat64_time64 (int __ver, int __fildes,
+				const char *__filename,
+				struct __stat64_t64 *__stat_buf,
+				int __flag);
 
 #if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN)
 hidden_proto (__fxstat)
diff --git a/io/Versions b/io/Versions
index 46f9d4c..90956fe 100644
--- a/io/Versions
+++ b/io/Versions
@@ -136,6 +136,7 @@ libc {
     __fxstat64_time64;
     __xstat64_time64;
     __lxstat64_time64;
+    __fxstatat64_time64;
   }
   GLIBC_PRIVATE {
     __libc_fcntl64;
diff --git a/io/fstatat64.c b/io/fstatat64.c
index f4f46a9..b7efd89 100644
--- a/io/fstatat64.c
+++ b/io/fstatat64.c
@@ -50,3 +50,10 @@ fstatat64 (int fd, const char *file, struct stat64 *buf, int flag)
 {
   return __fxstatat64 (_STAT_VER, fd, file, buf, flag);
 }
+
+int
+attribute_hidden
+__fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf, int flag)
+{
+  return __fxstatat64_time64 (_STAT_VER, fd, file, buf, flag);
+}
diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c
index baa9a60..2c04e66 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -45,3 +45,48 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
 								      err));
 }
 libc_hidden_def (__fxstatat64)
+
+/* 64-bit time version */
+
+int
+__fxstatat64_time64 (int vers, int fd, const char *file, struct __stat64_t64 *buf, int flag)
+{
+  if (__glibc_unlikely (vers != _STAT_VER_LINUX))
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  int result;
+  struct stat64 st64;
+  INTERNAL_SYSCALL_DECL (err);
+
+  result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
+  if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+    {
+      buf->st_dev          = st64.st_dev;
+    
+#if defined _HAVE_STAT64___ST_INO
+      buf->__st_ino        = st64.__st_ino;
+#endif
+      buf->st_mode         = st64.st_mode;
+      buf->st_nlink        = st64.st_nlink;
+      buf->st_uid          = st64.st_uid;		 
+      buf->st_gid          = st64.st_gid;		 
+      buf->st_rdev         = st64.st_rdev;		 
+      buf->st_size         = st64.st_size;		 
+      buf->st_blksize      = st64.st_blksize;
+    
+      buf->st_blocks       = st64.st_blocks;		
+      buf->st_atim.tv_sec  = st64.st_atim.tv_sec;	
+      buf->st_atim.tv_nsec = st64.st_atim.tv_nsec;	
+      buf->st_mtim.tv_sec  = st64.st_mtim.tv_sec;	
+      buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;	
+      buf->st_ctim.tv_sec  = st64.st_ctim.tv_sec;	
+      buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;	
+    
+      buf->st_ino          = st64.st_ino;
+    
+      return 0;
+    }
+  else
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result,
+								      err));
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=68e1c8cbe0005a72dd43d73dbdd795adc9ad57dd

commit 68e1c8cbe0005a72dd43d73dbdd795adc9ad57dd
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:53 2017 +0200

    Y2038: add function __lstat64_time64 (and __lxstat64_time64)
    
    These implementations just use the existing syscalls and convert from
    kernel 32-bit-time struct stat64 to GLIBC Y2038-ready struct __stat64_t64.

diff --git a/include/sys/stat.h b/include/sys/stat.h
index 186df0c..72aca27 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -40,6 +40,8 @@ extern int __fxstat64_time64 (int __ver, int __fildes,
 			      struct __stat64_t64 *__stat_buf);
 extern int __xstat64_time64 (int __ver, const char *__filename,
 			     struct __stat64_t64 *__stat_buf);
+extern int __lxstat64_time64 (int __ver, const char *__filename,
+			      struct __stat64_t64 *__stat_buf);
 
 #if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN)
 hidden_proto (__fxstat)
diff --git a/io/Versions b/io/Versions
index 821e375..46f9d4c 100644
--- a/io/Versions
+++ b/io/Versions
@@ -135,6 +135,7 @@ libc {
   GLIBC_2.29 {
     __fxstat64_time64;
     __xstat64_time64;
+    __lxstat64_time64;
   }
   GLIBC_PRIVATE {
     __libc_fcntl64;
diff --git a/io/lstat64.c b/io/lstat64.c
index c3eb7a7..96ce999 100644
--- a/io/lstat64.c
+++ b/io/lstat64.c
@@ -50,3 +50,10 @@ lstat64 (const char *file, struct stat64 *buf)
 {
   return __lxstat64 (_STAT_VER, file, buf);
 }
+
+int
+attribute_hidden
+__lstat64_time64 (const char *file, struct __stat64_t64 *buf)
+{
+  return __lxstat64_time64 (_STAT_VER, file, buf);
+}
diff --git a/sysdeps/unix/sysv/linux/lxstat64.c b/sysdeps/unix/sysv/linux/lxstat64.c
index d05fa14..0c55407 100644
--- a/sysdeps/unix/sysv/linux/lxstat64.c
+++ b/sysdeps/unix/sysv/linux/lxstat64.c
@@ -50,3 +50,44 @@ hidden_ver (___lxstat64, __lxstat64)
 strong_alias (___lxstat64, __lxstat64);
 hidden_def (__lxstat64)
 #endif
+
+/* 64-bit time version */
+
+int
+__lxstat64_time64 (int vers, const char *name, struct __stat64_t64 *buf)
+{
+  int result;
+  struct stat64 st64;
+
+  result = INLINE_SYSCALL (lstat64, 2, name, &st64);
+#if defined _HAVE_STAT64___ST_INO && !__ASSUME_ST_INO_64_BIT
+  if (__builtin_expect (!result, 1) && st64.__st_ino != (__ino_t) st64.st_ino)
+    st64.st_ino = st64.__st_ino;
+#endif
+  if (!result)
+    {
+      buf->st_dev          = st64.st_dev;
+    
+#if defined _HAVE_STAT64___ST_INO
+      buf->__st_ino        = st64.__st_ino;
+#endif
+      buf->st_mode         = st64.st_mode;
+      buf->st_nlink        = st64.st_nlink;
+      buf->st_uid          = st64.st_uid;		 
+      buf->st_gid          = st64.st_gid;		 
+      buf->st_rdev         = st64.st_rdev;		 
+      buf->st_size         = st64.st_size;		 
+      buf->st_blksize      = st64.st_blksize;
+    
+      buf->st_blocks       = st64.st_blocks;		
+      buf->st_atim.tv_sec  = st64.st_atim.tv_sec;	
+      buf->st_atim.tv_nsec = st64.st_atim.tv_nsec;	
+      buf->st_mtim.tv_sec  = st64.st_mtim.tv_sec;	
+      buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;	
+      buf->st_ctim.tv_sec  = st64.st_ctim.tv_sec;	
+      buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;	
+    
+      buf->st_ino          = st64.st_ino;
+    }
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=da4d3c580175cd0e0623e0240d9e52c707fa0947

commit da4d3c580175cd0e0623e0240d9e52c707fa0947
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:52 2017 +0200

    Y2038: add function __stat64_time64 (and __xstat64_time64)
    
    These implementations just use the existing syscalls and convert from
    kernel 32-bit-time struct stat64 to GLIBC Y2038-ready struct __stat64_t64.

diff --git a/include/sys/stat.h b/include/sys/stat.h
index c00f7b4..186df0c 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -38,6 +38,8 @@ extern int __mknod (const char *__path,
 		    __mode_t __mode, __dev_t __dev);
 extern int __fxstat64_time64 (int __ver, int __fildes,
 			      struct __stat64_t64 *__stat_buf);
+extern int __xstat64_time64 (int __ver, const char *__filename,
+			     struct __stat64_t64 *__stat_buf);
 
 #if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN)
 hidden_proto (__fxstat)
diff --git a/io/Versions b/io/Versions
index 0d8f63c..821e375 100644
--- a/io/Versions
+++ b/io/Versions
@@ -134,6 +134,7 @@ libc {
   }
   GLIBC_2.29 {
     __fxstat64_time64;
+    __xstat64_time64;
   }
   GLIBC_PRIVATE {
     __libc_fcntl64;
diff --git a/io/stat64.c b/io/stat64.c
index 5020551..4ed632f 100644
--- a/io/stat64.c
+++ b/io/stat64.c
@@ -50,3 +50,10 @@ stat64 (const char *file, struct stat64 *buf)
 {
   return __xstat64 (_STAT_VER, file, buf);
 }
+
+int
+attribute_hidden
+__stat64_time64 (const char *file, struct __stat64_t64 *buf)
+{
+  return __xstat64_time64 (_STAT_VER, file, buf);
+}
diff --git a/sysdeps/unix/sysv/linux/xstat64.c b/sysdeps/unix/sysv/linux/xstat64.c
index afc9ba2..e0341c1 100644
--- a/sysdeps/unix/sysv/linux/xstat64.c
+++ b/sysdeps/unix/sysv/linux/xstat64.c
@@ -52,3 +52,44 @@ hidden_ver (___xstat64, __xstat64)
 strong_alias (___xstat64, __xstat64)
 hidden_def (__xstat64)
 #endif
+
+/* 64-bit time version */
+
+int
+__xstat64_time64 (int vers, const char *name, struct __stat64_t64 *buf)
+{
+  int result;
+  struct stat64 st64;
+
+  result = INLINE_SYSCALL (stat64, 2, name, &st64);
+#if defined _HAVE_STAT64___ST_INO && !__ASSUME_ST_INO_64_BIT
+  if (__builtin_expect (!result, 1) && st64.__st_ino != (__ino_t) st64.st_ino)
+    st64.st_ino = st64.__st_ino;
+#endif
+  if (!result)
+    {
+      buf->st_dev          = st64.st_dev;
+#if defined _HAVE_STAT64___ST_INO
+      buf->__st_ino        = st64.__st_ino;
+#endif
+      buf->st_mode         = st64.st_mode;
+      buf->st_nlink        = st64.st_nlink;
+      buf->st_uid          = st64.st_uid;		 
+      buf->st_gid          = st64.st_gid;		 
+      buf->st_rdev         = st64.st_rdev;		 
+      buf->st_size         = st64.st_size;		 
+      buf->st_blksize      = st64.st_blksize;
+    
+      buf->st_blocks       = st64.st_blocks;
+
+      buf->st_atim.tv_sec  = st64.st_atim.tv_sec;
+      buf->st_atim.tv_nsec = st64.st_atim.tv_nsec;
+      buf->st_mtim.tv_sec  = st64.st_mtim.tv_sec;
+      buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;
+      buf->st_ctim.tv_sec  = st64.st_ctim.tv_sec;
+      buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;
+
+      buf->st_ino          = st64.st_ino;
+    }
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e815560be861a0fdbaa368c305721667fa27e1c1

commit e815560be861a0fdbaa368c305721667fa27e1c1
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:51 2017 +0200

    Y2038: add function __fstat64_time64 (and __fxstat64_time64)
    
    These implementations just use the existing syscalls and convert from
    kernel 32-bit-time struct stat64 to GLIBC Y2038-ready struct __stat64_t64.

diff --git a/include/sys/stat.h b/include/sys/stat.h
index 0f2a662..c00f7b4 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -36,6 +36,9 @@ extern int __mkdir (const char *__path, __mode_t __mode);
 libc_hidden_proto (__mkdir)
 extern int __mknod (const char *__path,
 		    __mode_t __mode, __dev_t __dev);
+extern int __fxstat64_time64 (int __ver, int __fildes,
+			      struct __stat64_t64 *__stat_buf);
+
 #if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN)
 hidden_proto (__fxstat)
 hidden_proto (__fxstat64)
diff --git a/io/Versions b/io/Versions
index f7e5dbe..0d8f63c 100644
--- a/io/Versions
+++ b/io/Versions
@@ -132,6 +132,9 @@ libc {
     fcntl64;
     statx;
   }
+  GLIBC_2.29 {
+    __fxstat64_time64;
+  }
   GLIBC_PRIVATE {
     __libc_fcntl64;
     __fcntl_nocancel;
diff --git a/io/fstat64.c b/io/fstat64.c
index 0f4de02..56b1b3f 100644
--- a/io/fstat64.c
+++ b/io/fstat64.c
@@ -50,3 +50,10 @@ fstat64 (int fd, struct stat64 *buf)
 {
   return __fxstat64 (_STAT_VER, fd, buf);
 }
+
+int
+attribute_hidden
+__fstat64_time64 (int fd, struct __stat64_t64 *buf)
+{
+  return __fxstat64_time64 (_STAT_VER, fd, buf);
+}
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index 0d05389..8c376cc 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -51,3 +51,43 @@ hidden_ver (___fxstat64, __fxstat64)
 strong_alias (___fxstat64, __fxstat64)
 hidden_def (__fxstat64)
 #endif
+
+/* 64-bit time version */
+
+int
+__fxstat64_time64 (int vers, int fd, struct __stat64_t64 *buf)
+{
+  int result;
+  struct stat64 st64;
+
+  result = INLINE_SYSCALL (fstat64, 2, fd, &st64);
+#if defined _HAVE_STAT64___ST_INO && !__ASSUME_ST_INO_64_BIT
+  if (__builtin_expect (!result, 1) && st64.__st_ino != (__ino_t) st64.st_ino)
+    st64.st_ino = st64.__st_ino;
+#endif
+  if (!result)
+    {
+      buf->st_dev          = st64.st_dev;
+#if defined _HAVE_STAT64___ST_INO
+      buf->__st_ino        = st64.__st_ino;
+#endif
+      buf->st_mode         = st64.st_mode;
+      buf->st_nlink        = st64.st_nlink;
+      buf->st_uid          = st64.st_uid;		 
+      buf->st_gid          = st64.st_gid;		 
+      buf->st_rdev         = st64.st_rdev;		 
+      buf->st_size         = st64.st_size;		 
+      buf->st_blksize      = st64.st_blksize;
+    
+      buf->st_blocks       = st64.st_blocks;		
+      buf->st_atim.tv_sec  = st64.st_atim.tv_sec;	
+      buf->st_atim.tv_nsec = st64.st_atim.tv_nsec;	
+      buf->st_mtim.tv_sec  = st64.st_mtim.tv_sec;	
+      buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;	
+      buf->st_ctim.tv_sec  = st64.st_ctim.tv_sec;	
+      buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;	
+    
+      buf->st_ino          = st64.st_ino;
+    }
+  return result;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=84203903bb3c6b5fc64e952d8781b67209e06ea3

commit 84203903bb3c6b5fc64e952d8781b67209e06ea3
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:50 2017 +0200

    Y2038: add struct __stat64_t64

diff --git a/include/sys/stat.h b/include/sys/stat.h
index b82d452..0f2a662 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -2,6 +2,28 @@
 #include <io/sys/stat.h>
 
 #ifndef _ISOMAC
+
+/* Used for 64-bit time implementations */
+struct __stat64_t64
+  {
+    __dev_t st_dev;			/* Device.  */
+
+    __ino_t __st_ino;			/* 32bit 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. */
+    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.  */
+    __ino64_t st_ino;			/* File serial number.		*/
+  };
+
 /* Now define the internal interfaces. */
 extern int __stat (const char *__file, struct stat *__buf);
 extern int __fstat (int __fd, struct stat *__buf);

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=21fb4f8d787cff4a5ad8067a4321e681f676354e

commit 21fb4f8d787cff4a5ad8067a4321e681f676354e
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:49 2017 +0200

    Y2038: add function __timerfd_settime64
    
    For Linux this uses the 32-bit time syscal, so it converts
    syscall input from 64-bit time into 32-bit time and syscall
    output from 32-bit time to 64-bit time.

diff --git a/rt/Makefile b/rt/Makefile
index c0aad5d..994891e 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -33,7 +33,7 @@ clock-routines := get_clockfreq clock_getcpuclockid			\
 		  clock_nanosleep
 timer-routines := timer_create timer_delete timer_getoverr		\
 		  timer_gettime timer_settime                           \
-		  timerfd_gettime64
+		  timerfd_gettime64 timerfd_settime64
 shm-routines   := shm_open shm_unlink
 mq-routines    := mq_open mq_close mq_unlink mq_getattr mq_setattr	\
 		  mq_notify mq_send mq_receive mq_timedsend		\
diff --git a/rt/Versions b/rt/Versions
index 7cee855..8f757ed 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -41,5 +41,6 @@ librt {
    __timer_gettime64;
    __timer_settime64;
    __timerfd_gettime64;
+   __timerfd_settime64;
   }
 }
diff --git a/rt/timerfd_settime64.c b/rt/timerfd_settime64.c
new file mode 100644
index 0000000..39ce88b
--- /dev/null
+++ b/rt/timerfd_settime64.c
@@ -0,0 +1,30 @@
+/* Set timer TIMERID to VALUE, returning old value in OVALUE.
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+
+int
+__timerfd_settime64 (int fd, int flags, const struct itimerspec *value,
+	       struct itimerspec *ovalue)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__timerfd_settime64)
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index bcfdc22..344fa5b 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,6 +1,7 @@
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
 GLIBC_2.29 __timerfd_gettime64 F
+GLIBC_2.29 __timerfd_settime64 F
 GLIBC_2.4 aio_cancel F
 GLIBC_2.4 aio_cancel64 F
 GLIBC_2.4 aio_error F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index eabb760..f34ae35 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -30,6 +30,7 @@ GLIBC_2.2 timer_settime F
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
 GLIBC_2.29 __timerfd_gettime64 F
+GLIBC_2.29 __timerfd_settime64 F
 GLIBC_2.3.4 mq_close F
 GLIBC_2.3.4 mq_getattr F
 GLIBC_2.3.4 mq_notify F
diff --git a/sysdeps/unix/sysv/linux/timerfd_settime64.c b/sysdeps/unix/sysv/linux/timerfd_settime64.c
new file mode 100644
index 0000000..fc31f5a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/timerfd_settime64.c
@@ -0,0 +1,72 @@
+/* Set timer TIMERID to VALUE, returning old value in OVALUE.
+
+   Copyright (C) 2018 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sysdep.h>
+#include <y2038-support.h>
+#include "kernel-posix-timers.h"
+
+int
+__timerfd_settime64 (int fd, int flags, const struct __itimerspec64 *value,
+	             struct __itimerspec64 *ovalue)
+{
+  int res;
+  struct itimerspec value32;
+  struct itimerspec ovalue32;
+
+  if (value == NULL)
+    return EFAULT;
+
+#ifdef __NR_timerfd_settime64
+  if (__y2038_get_kernel_support () > 0)
+    {
+      res = INLINE_SYSCALL (timerfd_settime64, 3, fd, value, ovalue);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  if (value->it_value.tv_sec > INT_MAX
+      || value->it_interval.tv_sec > INT_MAX)
+    {
+      __set_errno(EOVERFLOW);
+      return -1;
+    }
+
+  value32.it_value.tv_sec = value->it_value.tv_sec;
+  value32.it_value.tv_nsec = value->it_value.tv_nsec;
+  value32.it_interval.tv_sec = value->it_interval.tv_sec;
+  value32.it_interval.tv_nsec = value->it_interval.tv_nsec;
+
+  res = INLINE_SYSCALL (timerfd_settime, 4, fd, flags,
+                        &value32, &ovalue32);
+
+  if (res == 0 && ovalue != NULL)
+    {
+      ovalue->it_value.tv_sec = ovalue32.it_value.tv_sec;
+      ovalue->it_value.tv_nsec = ovalue32.it_value.tv_nsec;
+      ovalue->it_interval.tv_sec = ovalue32.it_interval.tv_sec;
+      ovalue->it_interval.tv_nsec = ovalue32.it_interval.tv_nsec;
+    }
+
+  return res;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b05011f0a7497c05f27ec78b3948185d940b5ec9

commit b05011f0a7497c05f27ec78b3948185d940b5ec9
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:48 2017 +0200

    Y2038: add function __timerfd_gettime64
    
    For Linux this uses the 32-bit time syscall so it converts the
    syscall output from 32-bit time to 64-bit time.

diff --git a/rt/Makefile b/rt/Makefile
index 6d6b896..c0aad5d 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -32,7 +32,8 @@ clock-routines := get_clockfreq clock_getcpuclockid			\
 		  clock_getres clock_gettime clock_settime		\
 		  clock_nanosleep
 timer-routines := timer_create timer_delete timer_getoverr		\
-		  timer_gettime timer_settime
+		  timer_gettime timer_settime                           \
+		  timerfd_gettime64
 shm-routines   := shm_open shm_unlink
 mq-routines    := mq_open mq_close mq_unlink mq_getattr mq_setattr	\
 		  mq_notify mq_send mq_receive mq_timedsend		\
diff --git a/rt/Versions b/rt/Versions
index c8703cb..7cee855 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -40,5 +40,6 @@ librt {
   GLIBC_2.29 {
    __timer_gettime64;
    __timer_settime64;
+   __timerfd_gettime64;
   }
 }
diff --git a/rt/timerfd_gettime64.c b/rt/timerfd_gettime64.c
new file mode 100644
index 0000000..72d0b68
--- /dev/null
+++ b/rt/timerfd_gettime64.c
@@ -0,0 +1,29 @@
+/* Get current value of timer TIMERID and store it in VALUE.
+
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+
+int
+__timerfd_gettime64 (int fd, struct itimerspec *value)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__timerfd_gettime64)
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index b92173e..bcfdc22 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,5 +1,6 @@
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
+GLIBC_2.29 __timerfd_gettime64 F
 GLIBC_2.4 aio_cancel F
 GLIBC_2.4 aio_cancel64 F
 GLIBC_2.4 aio_error F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index e7774ee..eabb760 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -29,6 +29,7 @@ GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
 GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.29 __timer_settime64 F
+GLIBC_2.29 __timerfd_gettime64 F
 GLIBC_2.3.4 mq_close F
 GLIBC_2.3.4 mq_getattr F
 GLIBC_2.3.4 mq_notify F
diff --git a/sysdeps/unix/sysv/linux/timerfd_gettime64.c b/sysdeps/unix/sysv/linux/timerfd_gettime64.c
new file mode 100644
index 0000000..51be6c7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/timerfd_gettime64.c
@@ -0,0 +1,54 @@
+/* Get current value of timer TIMERID and store it in VALUE.
+
+   Copyright (C) 2018 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sysdep.h>
+#include <y2038-support.h>
+#include "kernel-posix-timers.h"
+
+int
+__timerfd_gettime64 (int fd, struct __itimerspec64 *value)
+{
+  int res;
+  struct itimerspec value32;
+
+#ifdef __NR_timerfd_gettime64
+  if (__y2038_get_kernel_support () > 0)
+    {
+      res = INLINE_SYSCALL (timerfd_gettime64, 2, fd, value);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  res = INLINE_SYSCALL (timerfd_gettime, 2, fd, &value32);
+
+  if (res == 0)
+    {
+      value->it_value.tv_sec = value32.it_value.tv_sec;
+      value->it_value.tv_nsec = value32.it_value.tv_nsec;
+      value->it_interval.tv_sec = value32.it_interval.tv_sec;
+      value->it_interval.tv_nsec = value32.it_interval.tv_nsec;
+    }
+
+  return res;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3080fd4a51f8a6672e0fc92cd22341a117cc2432

commit 3080fd4a51f8a6672e0fc92cd22341a117cc2432
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:47 2017 +0200

    Y2038: add function __timer_settime64
    
    For Linux this uses a 32-bit syscall, so it converts the syscall
    input from 64-bit time into 32-bit time, and the syscall output
    from 32-bit time into 64-bit time.

diff --git a/rt/Versions b/rt/Versions
index e55faa0..c8703cb 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -39,5 +39,6 @@ librt {
   }
   GLIBC_2.29 {
    __timer_gettime64;
+   __timer_settime64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index e18f5ee..b92173e 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,4 +1,5 @@
 GLIBC_2.29 __timer_gettime64 F
+GLIBC_2.29 __timer_settime64 F
 GLIBC_2.4 aio_cancel F
 GLIBC_2.4 aio_cancel64 F
 GLIBC_2.4 aio_error F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index cb6ba72..e7774ee 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -28,6 +28,7 @@ GLIBC_2.2 timer_getoverrun F
 GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
 GLIBC_2.29 __timer_gettime64 F
+GLIBC_2.29 __timer_settime64 F
 GLIBC_2.3.4 mq_close F
 GLIBC_2.3.4 mq_getattr F
 GLIBC_2.3.4 mq_notify F
diff --git a/sysdeps/unix/sysv/linux/timer_settime.c b/sysdeps/unix/sysv/linux/timer_settime.c
index 7c938bd..bc876a9 100644
--- a/sysdeps/unix/sysv/linux/timer_settime.c
+++ b/sysdeps/unix/sysv/linux/timer_settime.c
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <sysdep.h>
+#include <y2038-support.h>
 #include "kernel-posix-timers.h"
 
 
@@ -41,3 +42,52 @@ timer_settime (timer_t timerid, int flags, const struct itimerspec *value,
 
   return res;
 }
+
+/* 64-bit time version */
+
+int
+__timer_settime64 (timer_t timerid, int flags, const struct itimerspec *value,
+                   struct itimerspec *ovalue)
+{
+  int res;
+  struct timer *kt = (struct timer *) timerid;
+  struct itimerspec value32, ovalue32;
+
+  if (value == NULL)
+  {
+    __set_errno(EFAULT);
+    return -1;
+  }
+
+#ifdef __NR_timer_settime64
+  if (__y2038_get_kernel_support () > 0)
+    {
+      res = INLINE_SYSCALL (timer_settime, 3, kt->ktimerid, value, ovalue);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  if (value->it_value.tv_sec > INT_MAX
+      || value->it_interval.tv_sec > INT_MAX)
+    return EOVERFLOW;
+
+  value32.it_value.tv_sec = value->it_value.tv_sec;
+  value32.it_value.tv_nsec = value->it_value.tv_nsec;
+  value32.it_interval.tv_sec = value->it_interval.tv_sec;
+  value32.it_interval.tv_nsec = value->it_interval.tv_nsec;
+
+  res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
+        &value32, &ovalue32);
+
+  if (res == 0 && ovalue != NULL)
+    {
+      ovalue->it_value.tv_sec = ovalue32.it_value.tv_sec;
+      ovalue->it_value.tv_nsec = ovalue32.it_value.tv_nsec;
+      ovalue->it_interval.tv_sec = ovalue32.it_interval.tv_sec;
+      ovalue->it_interval.tv_nsec = ovalue32.it_interval.tv_nsec;
+    }
+
+  return res;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=70a1833cbc3f14fdffd5c3932e98357e59e7d818

commit 70a1833cbc3f14fdffd5c3932e98357e59e7d818
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:46 2017 +0200

    Y2038: add function __timer_gettime64
    
    For Linux this uses the 32-bit time syscall, so it
    converts the syscall output into 64-bit time.

diff --git a/rt/Versions b/rt/Versions
index 91e3fd2..e55faa0 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -37,4 +37,7 @@ librt {
   GLIBC_2.7 {
    __mq_open_2;
   }
+  GLIBC_2.29 {
+   __timer_gettime64;
+  }
 }
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index cfbbd27..e18f5ee 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,3 +1,4 @@
+GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.4 aio_cancel F
 GLIBC_2.4 aio_cancel64 F
 GLIBC_2.4 aio_error F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index 595f1b7..cb6ba72 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -27,6 +27,7 @@ GLIBC_2.2 timer_delete F
 GLIBC_2.2 timer_getoverrun F
 GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
+GLIBC_2.29 __timer_gettime64 F
 GLIBC_2.3.4 mq_close F
 GLIBC_2.3.4 mq_getattr F
 GLIBC_2.3.4 mq_notify F
diff --git a/sysdeps/unix/sysv/linux/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c
index 10a19d9..85806f4 100644
--- a/sysdeps/unix/sysv/linux/timer_gettime.c
+++ b/sysdeps/unix/sysv/linux/timer_gettime.c
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <sysdep.h>
+#include <y2038-support.h>
 #include "kernel-posix-timers.h"
 
 
@@ -39,3 +40,35 @@ timer_gettime (timer_t timerid, struct itimerspec *value)
 
   return res;
 }
+
+/* 64-bit time version */
+
+int
+__timer_gettime64 (timer_t timerid, struct __itimerspec64 *value)
+{
+  struct itimerspec value32;
+  struct timer *kt = (struct timer *) timerid;
+  int res;
+
+#ifdef __NR_timer_gettime64
+  if (__y2038_get_kernel_support () > 0)
+    {
+      res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, &value32);
+
+  if (res == 0)
+    {
+      value->it_value.tv_sec = value32.it_value.tv_sec;
+      value->it_value.tv_nsec = value32.it_value.tv_nsec;
+      value->it_interval.tv_sec = value32.it_interval.tv_sec;
+      value->it_interval.tv_nsec = value32.it_interval.tv_nsec;
+    }
+
+  return res;
+}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=622c5f3a28cb0117d52c750b29d45e967c36cdf0

commit 622c5f3a28cb0117d52c750b29d45e967c36cdf0
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:45 2017 +0200

    Y2038: add struct __itimerspec64

diff --git a/include/bits/types/struct_itimerspec64.h b/include/bits/types/struct_itimerspec64.h
new file mode 100644
index 0000000..cc503f7
--- /dev/null
+++ b/include/bits/types/struct_itimerspec64.h
@@ -0,0 +1 @@
+#include <time/bits/types/struct_itimerspec64.h>
diff --git a/sysdeps/unix/sysv/linux/sys/timerfd.h b/sysdeps/unix/sysv/linux/sys/timerfd.h
index 4d75e15..37490cf 100644
--- a/sysdeps/unix/sysv/linux/sys/timerfd.h
+++ b/sysdeps/unix/sysv/linux/sys/timerfd.h
@@ -20,6 +20,7 @@
 
 #include <time.h>
 #include <bits/types/struct_itimerspec.h>
+#include <bits/types/struct_itimerspec64.h>
 
 /* Get the platform-dependent flags.  */
 #include <bits/timerfd.h>
diff --git a/time/bits/types/struct_itimerspec64.h b/time/bits/types/struct_itimerspec64.h
new file mode 100644
index 0000000..039af1c
--- /dev/null
+++ b/time/bits/types/struct_itimerspec64.h
@@ -0,0 +1,15 @@
+#ifndef __itimerspec64_defined
+#define __itimerspec64_defined 1
+
+#include <bits/types.h>
+#include <bits/types/struct_timespec.h>
+#include <bits/types/struct_timespec64.h>
+
+/* POSIX.1b structure for timer start values and intervals.  */
+struct __itimerspec64
+{
+  struct __timespec64 it_interval;
+  struct __timespec64 it_value;
+};
+
+#endif
diff --git a/time/time.h b/time/time.h
index 4b55e34..35012b9 100644
--- a/time/time.h
+++ b/time/time.h
@@ -46,6 +46,7 @@
 # include <bits/types/clockid_t.h>
 # include <bits/types/timer_t.h>
 # include <bits/types/struct_itimerspec.h>
+# include <bits/types/struct_itimerspec64.h>
 struct sigevent;
 #endif
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6d35c65cbb88663c26062f45db43c70903669125

commit 6d35c65cbb88663c26062f45db43c70903669125
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:44 2017 +0200

    Y2038: add function __lutimes64

diff --git a/misc/lutimes.c b/misc/lutimes.c
index b241c14..e436899 100644
--- a/misc/lutimes.c
+++ b/misc/lutimes.c
@@ -31,3 +31,11 @@ __lutimes (const char *file, const struct timeval tvp[2])
 weak_alias (__lutimes, lutimes)
 
 stub_warning (lutimes)
+
+int
+__lutimes64 (const char *file, const struct __timeval64 tvp[2])
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__lutimes64)
diff --git a/sysdeps/unix/sysv/linux/lutimes.c b/sysdeps/unix/sysv/linux/lutimes.c
index 4f2f9ec..e76b9dd 100644
--- a/sysdeps/unix/sysv/linux/lutimes.c
+++ b/sysdeps/unix/sysv/linux/lutimes.c
@@ -22,6 +22,7 @@
 #include <time.h>
 #include <sys/time.h>
 #include <sysdep.h>
+#include <y2038-support.h>
 
 
 int
@@ -42,3 +43,60 @@ lutimes (const char *file, const struct timeval tvp[2])
   return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tvp ? ts : NULL,
 			 AT_SYMLINK_NOFOLLOW);
 }
+
+/* 64-bit time version */
+
+int
+__lutimes64 (const char *file, const struct __timeval64 tvp[2])
+{
+  struct timespec ts32[2], *ts32p = NULL;;
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  /* The system call expects timespec, not timeval.  */
+  struct __timespec64 ts64[2], *ts64p = NULL;
+  int result;
+#endif
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  if (__y2038_linux_support > 0)
+    {
+      if (tvp != NULL)
+        {
+          if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+              || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+  	    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+        
+          ts64[0].tv_sec = tvp[0].tv_sec;
+          ts64[0].tv_nsec = tvp[0].tv_usec * 1000;
+          ts64[0].tv_pad = 0;
+          ts64[1].tv_sec = tvp[1].tv_sec;
+          ts64[1].tv_nsec = tvp[1].tv_usec * 1000;
+          ts64[1].tv_pad = 0;
+          ts64p = ts64;
+        }
+    
+      result = INLINE_SYSCALL (utimensat_time64, 4, AT_FDCWD, file, ts64p,
+  	  		     AT_SYMLINK_NOFOLLOW);
+      if (result == 0 || errno == ENOSYS)
+        return result;
+      __y2038_linux_support = -1;
+    }
+#endif
+
+  if (tvp != NULL)
+    {
+      if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+          || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+    
+      ts32[0].tv_sec = tvp[0].tv_sec;
+      ts32[0].tv_nsec = tvp[0].tv_usec * 1000;
+      ts32[1].tv_sec = tvp[1].tv_sec;
+      ts32[1].tv_nsec = tvp[1].tv_usec * 1000;
+      ts32p = ts32;
+    }
+
+  return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, ts32p,
+                             AT_SYMLINK_NOFOLLOW);
+}
diff --git a/time/Versions b/time/Versions
index 0a55284..f22ce38 100644
--- a/time/Versions
+++ b/time/Versions
@@ -79,5 +79,6 @@ libc {
     __futimens64;
     __sigtimedwait_time64;
     __futimes64;
+    __lutimes64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=bdc8d5fa690a74c3959fee45125624a9c8b8cd9d

commit bdc8d5fa690a74c3959fee45125624a9c8b8cd9d
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:43 2017 +0200

    Y2038: add function __futimes64

diff --git a/misc/futimes.c b/misc/futimes.c
index 3ffa40b..c8756a0 100644
--- a/misc/futimes.c
+++ b/misc/futimes.c
@@ -30,3 +30,12 @@ __futimes (int fd, const struct timeval tvp[2])
 weak_alias (__futimes, futimes)
 
 stub_warning (futimes)
+
+int
+__futimes64 (int fd, const struct __timeval64 tvp[2])
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__futimes64)
diff --git a/sysdeps/unix/sysv/linux/futimes.c b/sysdeps/unix/sysv/linux/futimes.c
index 9e6267c..c3d7678 100644
--- a/sysdeps/unix/sysv/linux/futimes.c
+++ b/sysdeps/unix/sysv/linux/futimes.c
@@ -24,6 +24,7 @@
 #include <sys/time.h>
 #include <_itoa.h>
 #include <fcntl.h>
+#include <y2038-support.h>
 
 
 /* Change the access time of the file associated with FD to TVP[0] and
@@ -49,3 +50,61 @@ __futimes (int fd, const struct timeval tvp[2])
   return INLINE_SYSCALL (utimensat, 4, fd, NULL, tvp ? &ts : NULL, 0);
 }
 weak_alias (__futimes, futimes)
+
+/* 64-bit time version */
+
+int
+__futimes64 (int fd, const struct __timeval64 tvp[2])
+{
+  struct timespec ts32[2], *ts32p = NULL;
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  /* The utimensat system call expects timespec not timeval.  */
+  struct __timespec64 ts64[2], *ts64p = NULL;
+  int result;
+#endif
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  if (__y2038_linux_support > 0)
+    {
+      if (tvp != NULL)
+        {
+          if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+              || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+  	    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+        
+          ts64[0].tv_sec = tvp[0].tv_sec;
+          ts64[0].tv_nsec = tvp[0].tv_usec * 1000;
+          ts64[0].tv_pad = 0;
+          ts64[1].tv_sec = tvp[1].tv_sec;
+          ts64[1].tv_nsec = tvp[1].tv_usec * 1000;
+          ts64[1].tv_pad = 0;
+          ts64p = ts64;
+        }
+    
+      result = INLINE_SYSCALL (utimensat_time64, 4, fd, NULL, ts64p, 0);
+      if (result == 0 || errno != ENOSYS)
+        return result;
+      __y2038_linux_support = -1;
+    }
+#endif
+
+  if (tvp != NULL)
+    {
+      if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+          || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+    
+      if (tvp[0].tv_sec > INT_MAX || tvp[1].tv_sec > INT_MAX)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
+    
+      ts32[0].tv_sec = tvp[0].tv_sec;
+      ts32[0].tv_nsec = tvp[0].tv_usec * 1000;
+      ts32[1].tv_sec = tvp[1].tv_sec;
+      ts32[1].tv_nsec = tvp[1].tv_usec * 1000;
+      ts32p = ts32;
+    }
+
+  return INLINE_SYSCALL (utimensat, 4, fd, NULL, ts32p, 0);
+}
diff --git a/time/Versions b/time/Versions
index 8e5f021..0a55284 100644
--- a/time/Versions
+++ b/time/Versions
@@ -78,5 +78,6 @@ libc {
     __utimensat_time64;
     __futimens64;
     __sigtimedwait_time64;
+    __futimes64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ec71c0ebf6a91218ca8d1474a3cda538e5c70132

commit ec71c0ebf6a91218ca8d1474a3cda538e5c70132
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:42 2017 +0200

    Y2038: add struct __timeval64
    
    Also, provide static inline functions and macros for checking
    and converting between 32-bit and 64-bit timevals.

diff --git a/bits/resource.h b/bits/resource.h
index 7693d20..c0b00be 100644
--- a/bits/resource.h
+++ b/bits/resource.h
@@ -134,6 +134,7 @@ enum __rusage_who
   };
 
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 #include <bits/types/struct_rusage.h>
 
 /* Priority limits.  */
diff --git a/include/bits/types/struct_timeval64.h b/include/bits/types/struct_timeval64.h
new file mode 100644
index 0000000..fe2ffe6
--- /dev/null
+++ b/include/bits/types/struct_timeval64.h
@@ -0,0 +1 @@
+#include <time/bits/types/struct_timeval64.h>
diff --git a/misc/sys/select.h b/misc/sys/select.h
index 6dd0c83..4183e85 100644
--- a/misc/sys/select.h
+++ b/misc/sys/select.h
@@ -35,6 +35,7 @@
 /* Get definition of timer specification structures.  */
 #include <bits/types/time_t.h>
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 #ifdef __USE_XOPEN2K
 # include <bits/types/struct_timespec.h>
 #endif
diff --git a/resource/bits/types/struct_rusage.h b/resource/bits/types/struct_rusage.h
index 5dc0916..bb2ecb2 100644
--- a/resource/bits/types/struct_rusage.h
+++ b/resource/bits/types/struct_rusage.h
@@ -21,6 +21,7 @@
 
 #include <bits/types.h>
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 
 /* Structure which says how much of each resource has been used.  */
 
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/resource.h b/sysdeps/unix/sysv/linux/alpha/bits/resource.h
index dddcb0f..b602f56 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/resource.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/resource.h
@@ -176,6 +176,7 @@ enum __rusage_who
 };
 
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 #include <bits/types/struct_rusage.h>
 
 /* Priority limits.  */
diff --git a/sysdeps/unix/sysv/linux/bits/resource.h b/sysdeps/unix/sysv/linux/bits/resource.h
index fafbadf..1f42d0d 100644
--- a/sysdeps/unix/sysv/linux/bits/resource.h
+++ b/sysdeps/unix/sysv/linux/bits/resource.h
@@ -176,6 +176,7 @@ enum __rusage_who
 };
 
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 #include <bits/types/struct_rusage.h>
 
 /* Priority limits.  */
diff --git a/sysdeps/unix/sysv/linux/bits/timex.h b/sysdeps/unix/sysv/linux/bits/timex.h
index 1dbcc0b..d3c16ec 100644
--- a/sysdeps/unix/sysv/linux/bits/timex.h
+++ b/sysdeps/unix/sysv/linux/bits/timex.h
@@ -20,6 +20,7 @@
 
 #include <bits/types.h>
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 
 /* These definitions from linux/timex.h as of 3.18.  */
 
diff --git a/sysdeps/unix/sysv/linux/mips/bits/resource.h b/sysdeps/unix/sysv/linux/mips/bits/resource.h
index 89d8788..ba46c0b 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/resource.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/resource.h
@@ -184,6 +184,7 @@ enum __rusage_who
 };
 
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 #include <bits/types/struct_rusage.h>
 
 /* Priority limits.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/resource.h b/sysdeps/unix/sysv/linux/sparc/bits/resource.h
index ee5c26e..1c88169 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/resource.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/resource.h
@@ -192,6 +192,7 @@ enum __rusage_who
 };
 
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 #include <bits/types/struct_rusage.h>
 
 /* Priority limits.  */
diff --git a/time/Makefile b/time/Makefile
index ec3e39d..f784fa1 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -27,7 +27,7 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 	   bits/types/struct_itimerspec.h				\
 	   bits/types/struct_timespec.h bits/types/struct_timeval.h	\
 	   bits/types/struct_tm.h bits/types/timer_t.h			\
-	   bits/types/time_t.h
+	   bits/types/time_t.h						\
 
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \
diff --git a/time/bits/types/struct_timeval64.h b/time/bits/types/struct_timeval64.h
new file mode 100644
index 0000000..e4966ea
--- /dev/null
+++ b/time/bits/types/struct_timeval64.h
@@ -0,0 +1,13 @@
+#ifndef __timeval64_defined
+#define __timeval64_defined 1
+
+#include <bits/types.h>
+
+/* A time value that is accurate to the nearest
+   microsecond but also has a range of years.  */
+struct __timeval64
+{
+  __time64_t tv_sec;		/* Seconds */
+  __int64_t tv_usec;		/* Microseconds */
+};
+#endif
diff --git a/time/sys/time.h b/time/sys/time.h
index 4166a5b..4e6255e 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -23,6 +23,7 @@
 #include <bits/types.h>
 #include <bits/types/time_t.h>
 #include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timeval64.h>
 
 #ifndef __suseconds_t_defined
 typedef __suseconds_t suseconds_t;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f8568278c808e6e0a86f98448bf06ef71d520a2c

commit f8568278c808e6e0a86f98448bf06ef71d520a2c
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:41 2017 +0200

    Y2038: add function __sigtimedwait_time64

diff --git a/signal/sigtimedwait.c b/signal/sigtimedwait.c
index 308b9b9..e187883 100644
--- a/signal/sigtimedwait.c
+++ b/signal/sigtimedwait.c
@@ -30,3 +30,13 @@ libc_hidden_def (__sigtimedwait)
 weak_alias (__sigtimedwait, sigtimedwait)
 
 stub_warning (sigtimedwait)
+
+int
+__sigtimedwait_time64 (const sigset_t *set, siginfo_t *info,
+		const struct __timespec64 *timeout)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__sigtimedwait_time64)
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index b4de885..6cfe8f0 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -18,7 +18,11 @@
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
+//#include <stdint.h>
+
+//#include <nptl/pthreadP.h>
 #include <sysdep-cancel.h>
+#include <y2038-support.h>
 
 int
 __sigtimedwait (const sigset_t *set, siginfo_t *info,
@@ -39,3 +43,80 @@ __sigtimedwait (const sigset_t *set, siginfo_t *info,
 }
 libc_hidden_def (__sigtimedwait)
 weak_alias (__sigtimedwait, sigtimedwait)
+
+/* 64-bit time version */
+
+int
+__sigtimedwait_time64 (const sigset_t *set, siginfo_t *info,
+		const struct __timespec64 *timeout)
+{
+  int result;
+  struct timespec ts32;
+#ifdef __NR_rt_sigtimedwait_time64
+  struct __timespec64 ts64;
+#endif
+
+#ifdef SIGCANCEL
+  sigset_t tmpset;
+  if (set != NULL
+      && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+	  || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+	  ))
+    {
+      /* Create a temporary mask without the bit for SIGCANCEL set.  */
+      // We are not copying more than we have to.
+      memcpy (&tmpset, set, _NSIG / 8);
+      __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+      __sigdelset (&tmpset, SIGSETXID);
+# endif
+      set = &tmpset;
+    }
+#endif
+
+    /* XXX The size argument hopefully will have to be changed to the
+       real size of the user-level sigset_t.  */
+#ifdef __NR_rt_sigtimedwait_time64
+  if (__y2038_linux_support > 0)
+    {
+      if (timeout)
+        {
+          ts64.tv_sec = timeout->tv_sec;
+          ts64.tv_nsec = timeout->tv_nsec;
+          ts64.tv_pad = 0;
+          result = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, &ts64, _NSIG / 8);
+          if (result == -1 && errno==ENOSYS)
+	    {
+	      __y2038_linux_support = -1;
+	    }
+        }
+      else
+        result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, NULL, _NSIG / 8);
+    }
+  else
+#endif
+    {
+      if (timeout)
+        {
+          if (! timespec64_to_timespec(timeout, &ts32))
+            {
+              errno = EOVERFLOW;
+              return -1;
+            }
+          result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, &ts32, _NSIG / 8);
+        }
+      else
+        result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, NULL, _NSIG / 8);
+    }
+
+  /* The kernel generates a SI_TKILL code in si_code in case tkill is
+     used.  tkill is transparently used in raise().  Since having
+     SI_TKILL as a code is useful in general we fold the results
+     here.  */
+  if (result != -1 && info != NULL && info->si_code == SI_TKILL)
+    info->si_code = SI_USER;
+
+  return result;
+}
diff --git a/time/Versions b/time/Versions
index 5614729..8e5f021 100644
--- a/time/Versions
+++ b/time/Versions
@@ -77,5 +77,6 @@ libc {
     __timespec_get64;
     __utimensat_time64;
     __futimens64;
+    __sigtimedwait_time64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=bf31b49b724d6676c537ec583f218737e9223a6e

commit bf31b49b724d6676c537ec583f218737e9223a6e
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:39 2017 +0200

    Y2038: add function __futimens64

diff --git a/io/futimens.c b/io/futimens.c
index fb170ff..2e9648a 100644
--- a/io/futimens.c
+++ b/io/futimens.c
@@ -32,3 +32,11 @@ futimens (int fd, const struct timespec tsp[2])
   return -1;
 }
 stub_warning (futimens)
+
+int
+__futimens64 (int fd, const struct __timespec64 tsp[2])
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__futimens64)
diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c
index bc7fe54..5de651d 100644
--- a/sysdeps/unix/sysv/linux/futimens.c
+++ b/sysdeps/unix/sysv/linux/futimens.c
@@ -21,7 +21,7 @@
 #include <string.h>
 #include <time.h>
 #include <sysdep.h>
-
+#include <y2038-support.h>
 
 /* Change the access time of the file associated with FD to TSP[0] and
    the modification time of FILE to TSP[1].
@@ -36,3 +36,50 @@ futimens (int fd, const struct timespec tsp[2])
   /* Avoid implicit array coercion in syscall macros.  */
   return INLINE_SYSCALL (utimensat, 4, fd, NULL, &tsp[0], 0);
 }
+
+/* 64-bit time version */
+
+int
+__futimens64 (int fd, const struct __timespec64 tsp[2])
+{
+  struct timespec ts32[2];
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimesat_time64
+  struct __timespec64 ts64[2];
+  int res;
+#endif
+
+  if (fd < 0)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF);
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimesat_time64
+  if (__y2038_linux_support > 0)
+    {
+      ts64[0].tv_sec = tsp[0].tv_sec;
+      ts64[0].tv_nsec = tsp[0].tv_nsec;
+      ts64[0].tv_pad = 0;
+      ts64[1].tv_sec = tsp[1].tv_sec;
+      ts64[1].tv_nsec = tsp[1].tv_nsec;
+      ts64[1].tv_pad = 0;
+      res = INLINE_SYSCALL (utimensat_time64, 4, fd, NULL, &ts64[0], 0);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_linux_support = -1;
+    }
+#endif
+
+  if (! timespec64_to_timespec(&tsp[0], &ts32[0]))
+    {
+      __set_errno(EOVERFLOW);
+      return -1;
+    }
+
+  if (! timespec64_to_timespec(&tsp[1], &ts32[1]))
+    {
+      __set_errno(EOVERFLOW);
+      return -1;
+    }
+
+  return INLINE_SYSCALL (utimensat, 4, fd, NULL, &ts32[0], 0);
+}
diff --git a/time/Versions b/time/Versions
index c5f6336..5614729 100644
--- a/time/Versions
+++ b/time/Versions
@@ -76,5 +76,6 @@ libc {
     __clock_nanosleep64;
     __timespec_get64;
     __utimensat_time64;
+    __futimens64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4992c6ce6cd99470c26708e881aeaeca78a082e9

commit 4992c6ce6cd99470c26708e881aeaeca78a082e9
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:40 2017 +0200

    Y2038: add function __utimensat_time64

diff --git a/io/utimensat.c b/io/utimensat.c
index 6b67a52..c535930 100644
--- a/io/utimensat.c
+++ b/io/utimensat.c
@@ -30,3 +30,12 @@ utimensat (int fd, const char *file, const struct timespec tsp[2],
   return -1;
 }
 stub_warning (utimensat)
+
+int
+__utimensat_time64 (int fd, const char *file, const struct __timespec64 tsp[2],
+	   int flags)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__utimensat_time64)
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 108d3bc..a0d1f5d 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include <sysdep.h>
+#include <y2038-support.h>
 
 
 /* Change the access time of FILE to TSP[0] and
@@ -34,3 +35,60 @@ utimensat (int fd, const char *file, const struct timespec tsp[2],
   /* Avoid implicit array coercion in syscall macros.  */
   return INLINE_SYSCALL (utimensat, 4, fd, file, &tsp[0], flags);
 }
+
+/* 64-bit time version */
+
+int
+__utimensat_time64 (int fd, const char *file, const struct __timespec64 tsp[2],
+		    int flags)
+{
+  struct timespec ts32[2], *ts32p = NULL;
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  struct __timespec64 ts64[2], *ts64p = NULL;
+  int res;
+#endif
+
+  if (file == NULL)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  if (__y2038_linux_support > 0)
+    {
+      if (tsp)
+        {
+          ts64[0].tv_sec = tsp[0].tv_sec;
+          ts64[0].tv_nsec = tsp[0].tv_nsec;
+          ts64[0].tv_pad = 0;
+          ts64[1].tv_sec = tsp[1].tv_sec;
+          ts64[1].tv_nsec = tsp[1].tv_nsec;
+          ts64[1].tv_pad = 0;
+          ts64p = ts64;
+        }
+
+      res = INLINE_SYSCALL (utimensat_time64, 4, fd, file, ts64p, flags);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_linux_support = -1;
+    }
+#endif
+
+  if (tsp)
+    {
+      if (! timespec64_to_timespec(&tsp[0], &ts32[0]))
+        {
+          __set_errno(EOVERFLOW);
+          return -1;
+        }
+
+      if (! timespec64_to_timespec(&tsp[1], &ts32[1]))
+        {
+          __set_errno(EOVERFLOW);
+          return -1;
+        }
+      ts32p = ts32;
+    }
+
+  return INLINE_SYSCALL (utimensat, 4, fd, file, ts32p, flags);
+}
diff --git a/time/Versions b/time/Versions
index 1e4d81b..c5f6336 100644
--- a/time/Versions
+++ b/time/Versions
@@ -75,5 +75,6 @@ libc {
     __clock_getres_time64;
     __clock_nanosleep64;
     __timespec_get64;
+    __utimensat_time64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4907e12b0ac6f1d5031ec108e604ebd1aa6de139

commit 4907e12b0ac6f1d5031ec108e604ebd1aa6de139
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:38 2017 +0200

    Y2038: add function __timespec_get64

diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
index b14a302..4cc534a 100644
--- a/sysdeps/unix/sysv/linux/timespec_get.c
+++ b/sysdeps/unix/sysv/linux/timespec_get.c
@@ -44,3 +44,24 @@ timespec_get (struct timespec *ts, int base)
 
   return base;
 }
+
+/* 64-bit time version */
+
+/* We don't have a 64-bit-time syscall yet, so just convert arguments
+ * between 64-bit and 32-bit time, and use the 32-bit implementation.
+ * 
+ * We could do the reverse and make the 32-bit time implementation a
+ * wrapper around the 64-bit-time implementation, but then 32-bit-time
+ * uses would incur two conversions instead of zero right now.
+ */
+int
+__timespec_get64 (struct __timespec64 *ts, int base)
+{
+  struct timespec ts32;
+  int res = timespec_get (&ts32, base);
+  if (res != base)
+    {
+      timespec_to_timespec64(&ts32, ts);
+    }
+  return res;
+}
diff --git a/time/Versions b/time/Versions
index 5dfe984..1e4d81b 100644
--- a/time/Versions
+++ b/time/Versions
@@ -74,5 +74,6 @@ libc {
     __clock_settime64;
     __clock_getres_time64;
     __clock_nanosleep64;
+    __timespec_get64;
   }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fd6b21f418a2ba6cc21b0b7536e873d27bd5c515

commit fd6b21f418a2ba6cc21b0b7536e873d27bd5c515
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:37 2017 +0200

    Y2038: add function __clock_nanosleep64
    
    Linux does not provide a 64-bit-time clock_nanosleep syscall,
    so __clock_nanosleep64 is a wrapper calling __clock_nanosleep,
    with one conversion before the call and possibly one after.
    
    Note:
    
    There is no point in implementing __clock_nanosleep64 directly
    around the 32-bit-time syscall and making __clock_nanosleep a
    wrapper around __clock_nanosleep64, because __clock_nanosleep64
    would still need one or two conversions, and __clock_nanosleep
    would now also need those, adding a cost of 2 to 4 conversions
    in the worst case.

diff --git a/include/time.h b/include/time.h
index dbb6f10..b482ac3 100644
--- a/include/time.h
+++ b/include/time.h
@@ -31,6 +31,9 @@ extern int __clock_settime64 (clockid_t __clock_id,
 			       const struct __timespec64 *__tp) __THROW;
 extern int __clock_getres_time64 (clockid_t __clock_id,
 				  struct __timespec64 *__res) __THROW;
+extern int __clock_nanosleep64 (clockid_t __clock_id, int __flags,
+				const struct __timespec64 *__req,
+				struct __timespec64 *__rem);
 
 /* Now define the internal interfaces.  */
 struct tm;
diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index 93d5d6e..6878da9 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -21,7 +21,6 @@
 #include <sysdep-cancel.h>
 #include "kernel-posix-cpu-timers.h"
 
-
 /* We can simply use the syscall.  The CPU clocks are not supported
    with this function.  */
 int
@@ -52,3 +51,51 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
 	  ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
 }
 weak_alias (__clock_nanosleep, clock_nanosleep)
+
+/* 64-bit time version */
+
+/* We don't have a 64-bit-time syscall yet, so just convert arguments
+ * between 64-bit and 32-bit time, and use the 32-bit implementation.
+ * 
+ * We could do the reverse and make the 32-bit time implementation a
+ * wrapper around the 64-bit-time implementation, but then 32-bit-time
+ * uses would incur four conversions instead of zero right now.
+ */
+int
+__clock_nanosleep64 (clockid_t clock_id, int flags,
+		     const struct __timespec64 *req,
+		     struct __timespec64 *rem)
+{
+  int res;
+  struct timespec req32, rem32, *rem32p = NULL;
+
+  if (req == NULL)
+    {
+      __set_errno (EFAULT);
+      return -1;
+    }
+
+  if (req->tv_sec > INT32_MAX || req->tv_sec < INT32_MIN)
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  /* For now, use the 32-bit-time implementation above */
+
+  req32.tv_sec = req->tv_sec;
+  req32.tv_nsec = req->tv_nsec;
+
+  if (rem != NULL)
+    rem32p = &rem32;
+
+  res = __clock_nanosleep (clock_id, flags, &req32, rem32p);
+
+  if (res == 0 && rem != NULL)
+    {
+      rem->tv_sec = rem32.tv_sec;
+      rem->tv_nsec = rem32.tv_nsec;
+    }
+
+  return res;
+}
diff --git a/time/Versions b/time/Versions
index fd83818..5dfe984 100644
--- a/time/Versions
+++ b/time/Versions
@@ -65,4 +65,14 @@ libc {
   GLIBC_2.16 {
     timespec_get;
   }
+  GLIBC_2.29 {
+    __ctime64; __ctime64_r;
+    __gmtime64; __gmtime64_r;
+    __localtime64; __localtime64_r;
+    __mktime64; __timelocal64_r; __timegm64;
+    __clock_gettime64;
+    __clock_settime64;
+    __clock_getres_time64;
+    __clock_nanosleep64;
+  }
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=122f7ed1659a4a96e00689fbb5755918618faae0

commit 122f7ed1659a4a96e00689fbb5755918618faae0
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:36 2017 +0200

    Y2038: add function __clock_getres_time64
    
    * include/time.h (__clock_getres_time64): Add.
    * sysdeps/posix/clock_getres.c (hp_timing_getres): Use
      struct __timespec64.
    * sysdeps/posix/clock_getres.c (realtime_getres): Likewise.
    * sysdeps/posix/clock_getres.c (__clock_getres_time64): Add.
    * sysdeps/posix/clock_getres.c Use SYSDEP_GETRES64.
    * sysdeps/posix/clock_getres.c Use SYSDEP_GETRES_CPU64.
    * sysdeps/posix/clock_getres.c (__clock_getres):
      Use __clock_getres_time64.
    * sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES32): Add.
    * sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES64): Likewise.
    * sysdeps/unix/sysv/linux/clock_getres.c (SYSDEP_GETRES64): Likewise.
    * sysdeps/unix/sysv/linux/clock_getres.c (SYSDEP_GETRES_CPU64): Likewise.

diff --git a/include/time.h b/include/time.h
index ba765ce..dbb6f10 100644
--- a/include/time.h
+++ b/include/time.h
@@ -29,6 +29,8 @@ extern int __clock_gettime64 (clockid_t __clock_id,
 			      struct __timespec64 *__tp) __THROW;
 extern int __clock_settime64 (clockid_t __clock_id,
 			       const struct __timespec64 *__tp) __THROW;
+extern int __clock_getres_time64 (clockid_t __clock_id,
+				  struct __timespec64 *__res) __THROW;
 
 /* Now define the internal interfaces.  */
 struct tm;
diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
index e7924e0..6b0d5da 100644
--- a/sysdeps/posix/clock_getres.c
+++ b/sysdeps/posix/clock_getres.c
@@ -23,12 +23,11 @@
 #include <sys/param.h>
 #include <libc-internal.h>
 
-
 #if HP_TIMING_AVAIL
 static long int nsec;		/* Clock frequency of the processor.  */
 
 static int
-hp_timing_getres (struct timespec *res)
+hp_timing_getres (struct __timespec64 *res)
 {
   if (__glibc_unlikely (nsec == 0))
     {
@@ -56,7 +55,7 @@ hp_timing_getres (struct timespec *res)
 #endif
 
 static inline int
-realtime_getres (struct timespec *res)
+realtime_getres (struct __timespec64 *res)
 {
   long int clk_tck = __sysconf (_SC_CLK_TCK);
 
@@ -73,17 +72,16 @@ realtime_getres (struct timespec *res)
   return -1;
 }
 
-
 /* Get resolution of clock.  */
 int
-__clock_getres (clockid_t clock_id, struct timespec *res)
+__clock_getres_time64 (clockid_t clock_id, struct __timespec64 *res)
 {
   int retval = -1;
 
   switch (clock_id)
     {
-#ifdef SYSDEP_GETRES
-      SYSDEP_GETRES;
+#ifdef SYSDEP_GETRES64
+      SYSDEP_GETRES64;
 #endif
 
 #ifndef HANDLED_REALTIME
@@ -93,8 +91,8 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
 #endif	/* handled REALTIME */
 
     default:
-#ifdef SYSDEP_GETRES_CPU
-      SYSDEP_GETRES_CPU;
+#ifdef SYSDEP_GETRES_CPU64
+      SYSDEP_GETRES_CPU64;
 #endif
 #if HP_TIMING_AVAIL
       if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
@@ -115,4 +113,19 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
 
   return retval;
 }
+
+int
+__clock_getres (clockid_t clock_id, struct timespec *res)
+{
+  struct __timespec64 ts64;
+  int retval = __clock_getres_time64 (clock_id, &ts64);
+  if (retval == 0)
+    {
+      // We assume we never run with a CPU clock period greater than
+      // 2**31 seconds and therefore we do not check the seconds field
+      res->tv_sec = ts64.tv_sec;
+      res->tv_nsec = ts64.tv_nsec;
+    }
+  return retval;
+}
 weak_alias (__clock_getres, clock_getres)
diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 5d94f59..6b895f1 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -19,6 +19,7 @@
 #include <sysdep.h>
 #include <errno.h>
 #include <time.h>
+#include <y2038-support.h>
 #include "kernel-posix-cpu-timers.h"
 
 #ifdef HAVE_CLOCK_GETRES_VSYSCALL
@@ -48,4 +49,64 @@
 #define SYSDEP_GETRES_CPU SYSCALL_GETRES
 #define SYSDEP_GETRES_CPUTIME	/* Default catches them too.  */
 
+/* The 64-bit version */
+
+// Call the 32-bit syscall and convert to 64-bit time
+#define SYSCALL_GETRES32 \
+  retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, &ts32);		\
+  if (retval==0)							\
+    {									\
+      timespec_to_timespec64(&ts32, res);				\
+      res->tv_pad = 0;							\
+    }
+
+#ifdef __NR_clock_getres_time64
+
+/* We are building with a 64-bit-time getres syscall */
+
+#define SYSCALL_GETRES64 \
+  if (__y2038_linux_support > 0)					\
+    {									\
+      retval = INLINE_SYSCALL (clock_getres_time64, 2, clock_id, res);	\
+      if (retval == -1 && errno == ENOSYS)				\
+	{								\
+	  __y2038_linux_support = -1;					\
+	  SYSCALL_GETRES32;						\
+	}								\
+    }									\
+  else									\
+    {									\
+      SYSCALL_GETRES32;							\
+    }									\
+  break
+
+#else
+
+/* We are building without a 64-bit-time getres syscall */
+
+#define SYSCALL_GETRES64 \
+  SYSCALL_GETRES32;							\
+  break
+
+#endif
+
+/* The REALTIME and MONOTONIC clock are definitely supported in the
+   kernel.  */
+#define SYSDEP_GETRES64							\
+  SYSDEP_GETRES_CPUTIME64						\
+  case CLOCK_REALTIME:							\
+  case CLOCK_MONOTONIC:							\
+  case CLOCK_MONOTONIC_RAW:						\
+  case CLOCK_REALTIME_COARSE:						\
+  case CLOCK_MONOTONIC_COARSE:						\
+    SYSCALL_GETRES64
+
+/* We handled the REALTIME clock here.  */
+#define HANDLED_REALTIME64	1
+#define HANDLED_CPUTIME64	1
+
+#define SYSDEP_GETRES_CPU64 SYSCALL_GETRES64
+#define SYSDEP_GETRES_CPUTIME64 \
+  struct timespec ts32;
+
 #include <sysdeps/posix/clock_getres.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2aa2f664160afee95c60dd2c23e761b83c9b3c31

commit 2aa2f664160afee95c60dd2c23e761b83c9b3c31
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:35 2017 +0200

    Y2038: add function __clock_settime64
    
    * include/time.h (__clock_settime64): Add.
    * sysdeps/unix/clock_settime.c (__clock_settime64): Add.
    * sysdeps/unix/sysv/linux/clock_settime.c (DO_CLOCK_SETTIME_32): Add.
    * sysdeps/unix/sysv/linux/clock_settime.c (DO_CLOCK_SETTIME_64): Add.
    * sysdeps/unix/sysv/linux/clock_settime.c (SYSDEP_SETTIME64_CPUTIME): Add.
    * sysdeps/unix/sysv/linux/clock_settime.c (SYSDEP_SETTIME64): Add.

diff --git a/include/time.h b/include/time.h
index 7a6236e..ba765ce 100644
--- a/include/time.h
+++ b/include/time.h
@@ -27,6 +27,8 @@ extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
 
 extern int __clock_gettime64 (clockid_t __clock_id,
 			      struct __timespec64 *__tp) __THROW;
+extern int __clock_settime64 (clockid_t __clock_id,
+			       const struct __timespec64 *__tp) __THROW;
 
 /* Now define the internal interfaces.  */
 struct tm;
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
index 38813ed..13abe31 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/unix/clock_settime.c
@@ -68,9 +68,67 @@ hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
 }
 #endif
 
-
 /* Set CLOCK to value TP.  */
 int
+__clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp)
+{
+#ifndef HANDLED_REALTIME
+  struct timeval tv32;
+#endif
+  int retval = -1;
+
+  /* Make sure the time cvalue is OK.  */
+  if (! IS_VALID_NANOSECONDS(tp->tv_nsec))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  switch (clock_id)
+    {
+#define HANDLE_REALTIME64 \
+      if (timespec64_to_timeval (tp, &tv32))				\
+        {								\
+	  retval = __settimeofday (&tv32, NULL);			\
+      else								\
+        {								\
+          __set_errno (EOVERFLOW);					\
+	  retval = -1;							\
+        }
+
+#ifdef SYSDEP_SETTIME64
+      SYSDEP_SETTIME64;
+#endif
+
+#ifndef HANDLED_REALTIME
+    case CLOCK_REALTIME:
+      HANDLE_REALTIME64;
+      break;
+#endif
+
+    default:
+#ifdef SYSDEP_SETTIME64_CPU
+      SYSDEP_SETTIME64_CPU;
+#endif
+#ifndef HANDLED_CPUTIME
+# if HP_TIMING_AVAIL
+      if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID
+	  || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID)
+	retval = hp_timing_settime (clock_id, tp);
+      else
+# endif
+	{
+	  __set_errno (EINVAL);
+	  retval = -1;
+	}
+#endif
+      break;
+    }
+
+  return retval;
+}
+
+int
 __clock_settime (clockid_t clock_id, const struct timespec *tp)
 {
   int retval;
diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c
index 5f3f22f..5913dd6 100644
--- a/sysdeps/unix/sysv/linux/clock_settime.c
+++ b/sysdeps/unix/sysv/linux/clock_settime.c
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <sysdep.h>
 #include <time.h>
+#include <y2038-support.h>
 
 #include "kernel-posix-cpu-timers.h"
 
@@ -35,4 +36,61 @@
 #define SYSDEP_SETTIME_CPU \
   retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp)
 
+/* 64-bit time version */
+
+# define DO_CLOCK_SETTIME_32 \
+  if (! fits_in_time_t(tp->tv_sec))					\
+    {									\
+      __set_errno (EOVERFLOW);						\
+      retval = -1;							\
+    }									\
+  else									\
+    {									\
+      valid_timespec64_to_timespec(tp, &ts32);  			\
+      retval = INLINE_SYSCALL (clock_settime, 2, clock_id, &ts32);	\
+    }
+
+#ifdef __NR_clock_settime64
+
+/* We are building with a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_SETTIME_64 \
+  if (__y2038_linux_support > 0)					\
+    {									\
+      ts64.tv_sec = tp->tv_sec;						\
+      ts64.tv_nsec = tp->tv_nsec;						\
+      ts64.tv_pad = 0;							\
+      retval = INLINE_SYSCALL (clock_settime64, 2, clock_id, &ts64);	\
+      if (retval == 1 && errno==ENOSYS)					\
+	{								\
+	  __y2038_linux_support = -1;					\
+	  DO_CLOCK_SETTIME_32;						\
+	}								\
+    }									\
+  else									\
+    {									\
+      DO_CLOCK_SETTIME_32;						\
+    }
+
+# define SYSDEP_SETTIME64_CPUTIME \
+  struct __timespec64 ts64;						\
+  struct timespec ts32
+
+#else
+
+/* We are building without a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_SETTIME_64 DO_CLOCK_SETTIME_32
+
+# define SYSDEP_SETTIME64_CPUTIME \
+  struct timespec ts32
+
+#endif
+
+#define SYSDEP_SETTIME64 \
+  SYSDEP_SETTIME64_CPUTIME;						\
+  case CLOCK_REALTIME:							\
+    DO_CLOCK_SETTIME_64;						\
+    break
+
 #include <sysdeps/unix/clock_settime.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=90a18c72b71cc76d1379bf38ac6ce4b110ecca1a

commit 90a18c72b71cc76d1379bf38ac6ce4b110ecca1a
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Sun Apr 8 11:15:24 2018 +0200

    Y2038: add function __clock_gettime64
    
    * include/time.h: Declare __clock_gettime64().
    * ntpl/pthread_clock_gettime.c: Add __pthread_clock_gettime64().
    * ntpl/pthread_clock_gettime.c: Make __pthread_clock_gettime()
      a wrapper around __pthread_clock_gettime64().
    * sysdeps/unix/clock_gettime.c (hp_timing_gettime): Use struct
      __timespec64.
    * sysdeps/unix/clock_gettime.c (realtime_gettime): Likewise.
    * sysdeps/unix/clock_gettime.c: Add __clock_gettime64().
    * sysdeps/unix/clock_gettime.c: Make __clock_gettime() a
      wrapper around __clock_gettime64().
    * sysdeps/unix/sysv/linux/clock_gettime.c: Add 64-bit-time syscall
      support.

diff --git a/include/time.h b/include/time.h
index 5e0efd5..7a6236e 100644
--- a/include/time.h
+++ b/include/time.h
@@ -25,6 +25,9 @@ extern __typeof (clock_settime) __clock_settime;
 extern __typeof (clock_nanosleep) __clock_nanosleep;
 extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
 
+extern int __clock_gettime64 (clockid_t __clock_id,
+			      struct __timespec64 *__tp) __THROW;
+
 /* Now define the internal interfaces.  */
 struct tm;
 
diff --git a/nptl/pthread_clock_gettime.c b/nptl/pthread_clock_gettime.c
index 6bc75cf..508821b 100644
--- a/nptl/pthread_clock_gettime.c
+++ b/nptl/pthread_clock_gettime.c
@@ -18,13 +18,14 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <time.h>
+#include <bits/types/struct_timespec64.h>
 #include "pthreadP.h"
 
 
 #if HP_TIMING_AVAIL
 int
-__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-			 struct timespec *tp)
+__pthread_clock_gettime64 (clockid_t clock_id, hp_timing_t freq,
+			   struct __timespec64 *tp)
 {
   hp_timing_t tsc;
 
@@ -64,4 +65,36 @@ __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
 
   return 0;
 }
+
+int
+__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
+			   struct timespec *tp)
+{
+  struct __timespec64 ts64;
+  int res;
+
+  if (tp == NULL)
+    {
+      __set_errno(EINVAL);
+      res = -1;
+    }
+  else
+    {
+      int res = __pthread_clock_gettime64 (clock_id, freq, &ts64);
+      if (res == 0)
+	{
+	  if (fits_in_time_t (ts64.tv_time))
+	    {
+	      tp->tv_sec = ts64.tv_sec;
+	      tp->tv_nsec = ts64.tv_nsec;
+	    }
+	  else
+	    {
+	      set_errno(EOVERFLOW);
+	      res = -1;
+	    }
+	}
+    }
+  return res;
+}
 #endif
diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c
index 96df78a..88c1955 100644
--- a/sysdeps/unix/clock_gettime.c
+++ b/sysdeps/unix/clock_gettime.c
@@ -32,12 +32,12 @@ static hp_timing_t freq;
 
 
 /* This function is defined in the thread library.  */
-extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-				    struct timespec *tp)
+extern int __pthread_clock_gettime64 (clockid_t clock_id, hp_timing_t freq,
+				      struct __timespec64 *tp)
      __attribute__ ((__weak__));
 
 static int
-hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
+hp_timing_gettime (clockid_t clock_id, struct __timespec64 *tp)
 {
   hp_timing_t tsc;
 
@@ -55,7 +55,7 @@ hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
 
   if (clock_id != CLOCK_PROCESS_CPUTIME_ID
       && __pthread_clock_gettime != NULL)
-    return __pthread_clock_gettime (clock_id, freq, tp);
+    return __pthread_clock_gettime64 (clock_id, freq, tp);
 
   /* Get the current counter.  */
   HP_TIMING_NOW (tsc);
@@ -76,20 +76,20 @@ hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
 
 
 static inline int
-realtime_gettime (struct timespec *tp)
+realtime_gettime (struct __timespec64 *tp)
 {
   struct timeval tv;
   int retval = __gettimeofday (&tv, NULL);
   if (retval == 0)
     /* Convert into `timespec'.  */
-    TIMEVAL_TO_TIMESPEC (&tv, tp);
+    valid_timeval_to_timespec64 (&tv, tp);
   return retval;
 }
 
 
 /* Get current value of CLOCK and store it in TP.  */
 int
-__clock_gettime (clockid_t clock_id, struct timespec *tp)
+__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 {
   int retval = -1;
 
@@ -103,9 +103,9 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
     case CLOCK_REALTIME:
       {
 	struct timeval tv;
-	retval = __gettimeofday (&tv, NULL);
+	retval = __gettimeofday (&tv32, NULL);
 	if (retval == 0)
-	  TIMEVAL_TO_TIMESPEC (&tv, tp);
+	  valid_timeval_to_timespec64 (&tv32, tp);
       }
       break;
 #endif
@@ -132,5 +132,36 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
 
   return retval;
 }
+
+int
+__clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+  struct __timespec64 ts64;
+  int res;
+
+  if (tp == NULL)
+    {
+      __set_errno(EINVAL);
+      res = -1;
+    }
+  else
+    {
+      res = __clock_gettime64 (clock_id, &ts64);
+      if (res == 0)
+	{
+	  if (fits_in_time_t (ts64.tv_sec))
+	    {
+	      tp->tv_sec = ts64.tv_sec;
+	      tp->tv_nsec = ts64.tv_nsec;
+	    }
+	  else
+	    {
+	      __set_errno(EOVERFLOW);
+	      res = -1;
+	    }
+	}
+    }
+  return res;
+}
 weak_alias (__clock_gettime, clock_gettime)
 libc_hidden_def (__clock_gettime)
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index d837fa3..9920ffa 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -25,6 +25,41 @@
 # define HAVE_VSYSCALL
 #endif
 #include <sysdep-vdso.h>
+#include <y2038-support.h>
+
+# define DO_CLOCK_GETTIME_32 \
+  retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &ts32);		\
+  if (retval == 0)							\
+    {									\
+      valid_timespec_to_timespec64 (&ts32, tp);				\
+    }
+
+#ifdef __NR_clock_gettime64
+
+/* We are building with a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_GETTIME_64 \
+    if (__y2038_linux_support > 0)					\
+      {									\
+	retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp);	\
+	if (retval == -1 && errno == ENOSYS)				\
+	  {								\
+	    __y2038_linux_support = -1;					\
+	    DO_CLOCK_GETTIME_32;					\
+	  }								\
+      }									\
+    else								\
+      {									\
+        DO_CLOCK_GETTIME_32;						\
+      }
+
+#else
+
+/* We are building without a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_GETTIME_64 DO_CLOCK_GETTIME_32
+
+#endif
 
 /* The REALTIME and MONOTONIC clock are definitely supported in the
    kernel.  */
@@ -32,7 +67,7 @@
   SYSDEP_GETTIME_CPUTIME;						      \
   case CLOCK_REALTIME:							      \
   case CLOCK_MONOTONIC:							      \
-    retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);		      \
+    DO_CLOCK_GETTIME_64;						      \
     break
 
 /* We handled the REALTIME clock here.  */
@@ -40,8 +75,10 @@
 #define HANDLED_CPUTIME	1
 
 #define SYSDEP_GETTIME_CPU(clock_id, tp) \
-  retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \
+  DO_CLOCK_GETTIME_64; \
   break
-#define SYSDEP_GETTIME_CPUTIME	/* Default catches them too.  */
+
+#define SYSDEP_GETTIME_CPUTIME \
+  struct timespec ts32
 
 #include <sysdeps/unix/clock_gettime.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4f65faa6c33122f564ea281fb64abaac54f093ba

commit 4f65faa6c33122f564ea281fb64abaac54f093ba
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Fri Sep 8 00:41:33 2017 +0200

    Y2038: add struct __timespec64
    
    This type is a glibc-internal type similar to struct timespec
    but whose tv_sec field is a _time64_t rather than a time_t,
    which makes it Y2038-proof and useable to pass between user
    code and Y2038-proof kernel syscalls.
    
    On 64-bit architectures, and on X32, struct __timespec64 is
    just an alias of struct timespec, which is already 64-bit.
    On other architectures, it must be explicitly defined.
    
    In order to match the Linux kernel struct, the tv_nsec field
    of struct __timespec64 is also a signed 64-bit integer. The
    kernel ensures that the higher half of tv_nsec is always 0,
    which means glibc does not need to do it.
    
    Note: the corresponding glibc public* type will differ from
    this private type, as the user source code might depend on the
    tv_nsec field being a 32-bit long, not a 64-bit int. To meet
    this expectation, the public type will have a 32-bit tv_nsec
    field plus 32-bit anonymous padding, ordered according to the
    endianness of the architecture.
    
    Tested with make xtests on x86_64 and ARM.
    
    * include/bits/types/struct_timespec64.h:
      Include time/bits/types/struct_timespec64.h
    * include/time.h (valid_timeval_to_timespec64): Add.
    * include/time.h (valid_timespec_to_timespec64): Likewise.
    * include/time.h (valid_timespec64_to_timespec): Likewise.
    * include/time.h (valid_timespec64_to_timeval): Likewise.
    * include/time.h (IS_VALID_NANOSECONDS): Likewise.
    * include/time.h (timespec_to_timespec64): Likewise.
    * include/time.h (timespec64_to_timespec): Likewise.
    * include/time.h (timespec64_to_timeval): Likewise.
    * io/fcntl.h: Include bits/types/struct_timespec64.h.
    * io/sys/poll.h: Likewise.
    * io/sys/stat.h: Likewise.
    * misc/sys/select.h: Likewise.
    * posix/sched.h: Likewise.
    * posix/netdb.h: Likewise.
    * rt/aio.h: Likewise.
    * rt/mqueue.h: Likewise.
    * signal/signal.h: Likewise.
    * sysdeps/nptl/pthread.h: Likewise.
    * sysdeps/pthread/semaphore.h: Likewise.
    * sysdeps/unix/sysv/linux/hppa/pthread.h: Likewise.
    * sysvipc/sys/sem.h: Likewise.
    * time/Makefile: Add bits/types/struct_timespec64.h
    * time/bits/types/struct_itimerspec.h:
      Include bits/types/struct_timespec64.h
    * time/bits/types/struct_itimerspec64.h: Add.
    * time/time.h: Include bits/types/struct_timespec64.h

diff --git a/include/bits/types/struct___timespec64.h b/include/bits/types/struct___timespec64.h
new file mode 100644
index 0000000..b168c77
--- /dev/null
+++ b/include/bits/types/struct___timespec64.h
@@ -0,0 +1,36 @@
+#ifndef __timespec64_defined
+#define __timespec64_defined 1
+
+#include <bits/types.h>
+#include <bits/timesize.h>
+#include <endian.h>
+
+/* The glibc-internal Y2038-proof structure for a time value.
+   To keep things Posix-ish, we keep the nanoseconds field a 32-bit
+   signed long, but since the Linux field is a 64-bit signed int, we
+   pad our tv_nsec with a 32-bit int, which should always be 0.
+   Note that this is the glibc-internal type; in the public type, the
+   padding is an anonymous 32-bit bitfield, so that source-code initializers
+   keep working.  */
+#if __TIMESIZE==64
+# define __timespec64 timespec
+#else
+#define TIMSPEC64_TV_PAD_DEFINED
+# if BYTE_ORDER == BIG_ENDIAN
+struct __timespec64
+{
+  __time64_t tv_sec;		/* Seconds */
+  int tv_pad: 32;		/* Padding named for checking/setting */
+  __syscall_slong_t tv_nsec;	/* Nanoseconds */
+};
+# else
+struct __timespec64
+{
+  __time64_t tv_sec;		/* Seconds */
+  __syscall_slong_t tv_nsec;	/* Nanoseconds */
+  int tv_pad: 32;		/* Padding named for checking/setting */
+};
+# endif
+#endif
+
+#endif
diff --git a/include/time.h b/include/time.h
index 68d1413..5e0efd5 100644
--- a/include/time.h
+++ b/include/time.h
@@ -3,6 +3,7 @@
 
 #ifndef _ISOMAC
 # include <bits/types/locale_t.h>
+# include <bits/types/struct___timespec64.h>
 # include <stdbool.h>
 
 extern __typeof (strftime_l) __strftime_l;
@@ -150,5 +151,90 @@ fits_in_time_t (__time64_t t64)
   return t == t64;
 }
 
+/* Convert a known valid struct timeval into a struct __timespec64.  */
+static inline void
+valid_timeval_to_timespec64 (const struct timeval *tv32,
+			     struct __timespec64 *ts64)
+{
+  ts64->tv_sec = tv32->tv_sec;
+  ts64->tv_nsec = tv32->tv_usec * 1000;
+}
+
+/* Convert a known valid struct timespec into a struct __timespec64.  */
+static inline void
+valid_timespec_to_timespec64 (const struct timespec *ts32,
+			      struct __timespec64 *ts64)
+{
+  ts64->tv_sec = ts32->tv_sec;
+  ts64->tv_nsec = ts32->tv_nsec;
+  /* We only need to zero ts64->tv_pad if we pass it to the kernel.  */
+}
+
+/* Convert a known valid struct __timespec64 into a struct timespec.  */
+static inline void
+valid_timespec64_to_timespec (const struct __timespec64 *ts64,
+			      struct timespec *ts32)
+{
+  ts32->tv_sec = (time_t) ts64->tv_sec;
+  ts32->tv_nsec = ts64->tv_nsec;
+}
+
+/* Convert a known valid struct __timespec64 into a struct timeval.  */
+static inline void
+valid_timespec64_to_timeval (const struct __timespec64 *ts64,
+			     struct timeval *tv32)
+{
+  tv32->tv_sec = (time_t) ts64->tv_sec;
+  tv32->tv_usec = ts64->tv_nsec / 1000;
+}
+
+/* Check if a value lies with the valid nanoseconds range.  */
+#define IS_VALID_NANOSECONDS(ns) (ns >= 0 && ns <= 999999999)
+
+/* Check and convert a struct timespec into a struct __timespec64.  */
+static inline bool
+timespec_to_timespec64 (const struct timespec *ts32,
+					   struct __timespec64 *ts64)
+{
+  /* Check that ts32 holds a valid count of nanoseconds.  */
+  if (! IS_VALID_NANOSECONDS (ts32->tv_nsec))
+    return false;
+  /* All ts32 fields can fit in ts64, so copy them.  */
+  valid_timespec_to_timespec64 (ts32, ts64);
+  /* We only need to zero ts64->tv_pad if we pass it to the kernel.  */
+  return true;
+}
+
+/* Check and convert a struct __timespec64 into a struct timespec.  */
+static inline bool
+timespec64_to_timespec (const struct __timespec64 *ts64,
+					   struct timespec *ts32)
+{
+  /* Check that tv_nsec holds a valid count of nanoseconds.  */
+  if (! IS_VALID_NANOSECONDS (ts64->tv_nsec))
+    return false;
+  /* Check that tv_sec can fit in a __time_t.  */
+  if (! fits_in_time_t (ts64->tv_sec))
+    return false;
+  /* All ts64 fields can fit in ts32, so copy them.  */
+  valid_timespec64_to_timespec (ts64, ts32);
+  return true;
+}
+
+/* Check and convert a struct __timespec64 into a struct timeval.  */
+static inline bool
+timespec64_to_timeval (const struct __timespec64 *ts64,
+					  struct timeval *tv32)
+{
+  /* Check that tv_nsec holds a valid count of nanoseconds.  */
+  if (! IS_VALID_NANOSECONDS (ts64->tv_nsec))
+    return false;
+  /* Check that tv_sec can fit in a __time_t.  */
+  if (! fits_in_time_t (ts64->tv_sec))
+    return false;
+  /* All ts64 fields can fit in tv32, so copy them.  */
+  valid_timespec64_to_timeval (ts64, tv32);
+  return true;
+}
 #endif
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=60fd8a269d32469b54ffc7f0494588a8c1dfb685

commit 60fd8a269d32469b54ffc7f0494588a8c1dfb685
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Sun Jun 10 10:47:12 2018 +0200

    Y2038: provide kernel support indication
    
    Introduce __ASSUME_KERNEL_Y2038_SUPPORT which means that
    the underlying kernel *always* implements 64-bit-time Y2038-proof
    syscalls.
    
    If __ASSUME_KERNEL_Y2038_SUPPORT is not defined, glibc must
    check dynamically whether the underlying kernel provides these
    syscalls or not, and must fallback to 32-bit-time syscalls if
    not.
    
    Introduce function __y2038_get_kernel_support(), which returns
    true if the underlying kernel supports 64-bit-time syscalls.
    
    Also introduce function __y2038_set_kernel_support(), which
    allows an implementation to notify glibc of the absence of
    64-bit-time syscalls (ENOSYS) so that they are not needlessly
    tried again.
    
    * misc/Makefile: Add module y2038-support.
    * misc/Versions: (__y2038_get_kernel_support): Add to GLIBC_PRIVATE.
    * misc/Versions: (__y2038_set_kernel_support): Likewise.
    * misc/y2038-support.c: New file.
    * misc/y2038-support.h: Likewise.
    * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_KERNEL_Y2038_SUPPORT): Add.
    * sysdeps/unix/sysv/linux/y2038-support.c: New file.
    * sysdeps/unix/sysv/linux/y2038-support.h: New file.

diff --git a/misc/Makefile b/misc/Makefile
index 30e0673..7ced1ea 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -71,7 +71,7 @@ routines := brk sbrk sstk ioctl \
 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
 	    removexattr setxattr getauxval ifunc-impl-list makedev \
-	    allocate_once
+	    allocate_once y2038-support
 
 generated += tst-error1.mtrace tst-error1-mem.out \
   tst-allocate_once.mtrace tst-allocate_once-mem.out
diff --git a/misc/Versions b/misc/Versions
index 900e4ff..48285d8 100644
--- a/misc/Versions
+++ b/misc/Versions
@@ -158,6 +158,8 @@ libc {
   GLIBC_2.26 {
     preadv2; preadv64v2; pwritev2; pwritev64v2;
   }
+  GLIBC_2.29 {
+  }
   GLIBC_PRIVATE {
     __madvise;
     __mktemp;
@@ -166,5 +168,7 @@ libc {
     __mmap; __munmap; __mprotect;
     __sched_get_priority_min; __sched_get_priority_max;
     __libc_allocate_once_slow;
+    __y2038_get_kernel_support;
+    __y2038_set_kernel_support;
   }
 }
diff --git a/misc/y2038-support.c b/misc/y2038-support.c
new file mode 100644
index 0000000..a499472
--- /dev/null
+++ b/misc/y2038-support.c
@@ -0,0 +1,35 @@
+/* y2038 general kernel support indication.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdbool.h>
+
+/* By default glibc assumes the underlying kernel does not support Y2038 */ 
+bool __default_y2038_get_kernel_support (void)
+{
+  return false;
+}
+weak_alias (__default_y2038_get_kernel_support, __y2038_get_kernel_support)
+
+/* By default glibc just ignores Y2038 support indication setting */ 
+void __default_y2038_set_kernel_support (bool support __attribute__ ((unused)))
+{
+  /* Do nothing.  */
+}
+weak_alias (__default_y2038_set_kernel_support, __y2038_set_kernel_support)
+
diff --git a/misc/y2038-support.h b/misc/y2038-support.h
new file mode 100644
index 0000000..90ae3a4
--- /dev/null
+++ b/misc/y2038-support.h
@@ -0,0 +1,30 @@
+/* y2038 general kernel support indication.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdbool.h>
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+/* Dynamically check whether actual kernel supports Y2038 or not.  */
+extern bool __y2038_get_kernel_support (void);
+
+/* Dynamically set whether actual kernel supports Y2038 or not.  */
+extern void __y2038_set_kernel_support (bool support);
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 5543d92..b47755b 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -154,3 +154,17 @@
    */
 
 #define __ASSUME_CLONE_DEFAULT 1
+
+/* Support for Y2038-proof times.
+
+   If defined, the underlying kernel always provides a set of syscalls
+   (__NR_* names and numbers) which can handle times beyond Y2038.
+
+   If undefined, whether the underlying kernel provides this set or not
+   must be checked dynamically.
+
+   Definition is commented out until Y2038 syscalls are merged in the
+   kernel.
+   */
+
+/* #define __ASSUME_KERNEL_Y2038_SUPPORT 1 */
diff --git a/sysdeps/unix/sysv/linux/y2038-support.c b/sysdeps/unix/sysv/linux/y2038-support.c
new file mode 100644
index 0000000..5c31118
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/y2038-support.c
@@ -0,0 +1,44 @@
+/* y2038 Linux kernel support indication.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+#include <stdbool.h>
+
+/* By default the underlying Linux kernel is assumed not to support Y2038.
+ * Any Linux architecture may claim Y2038 kernel support by setting
+ * __y2038_linux_support.
+ */
+bool __y2038_linux_support = false;
+
+/* For Linux, Y2038 kernel support is determined by __y2038_linux_support  */
+
+bool __linux_y2038_get_kernel_support (void)
+{
+  return __y2038_linux_support;
+}
+strong_alias (__linux_y2038_get_kernel_support, __y2038_get_kernel_support)
+
+void __linux_y2038_set_kernel_support (bool support)
+{
+  __y2038_linux_support = support;
+}
+strong_alias (__linux_y2038_set_kernel_support, __y2038_set_kernel_support)
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/y2038-support.h b/sysdeps/unix/sysv/linux/y2038-support.h
new file mode 100644
index 0000000..1be24b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/y2038-support.h
@@ -0,0 +1,35 @@
+/* y2038 Linux kernel support indication.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+#include <stdbool.h>
+
+/* Indicates Y2038 support.
+ * Can be read directly from within libc linux-related files.
+ * Can be written non-zero to indicate support or lack thereof.
+ * Other libraries (e.g. librt) cannot access this variable and
+ * must call __y2038_get_kernel_support/__y2038_set_kernel_support
+ */
+extern bool __y2038_linux_support;
+
+#endif
+
+/* As a fallback, provide generic Y2038 support indication */
+#include <misc/y2038-support.h>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=98ada9d2bc670d5e3d0422772a3843f1d3b4b53e

commit 98ada9d2bc670d5e3d0422772a3843f1d3b4b53e
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Wed Mar 29 11:57:53 2017 +0200

    Y2038: make __difftime compatible with 64-bit time
    
    Provide a 64-bit-time version of __difftime (but do not assume
    __time64_t is a signed int so that Gnulib can reuse the code)
    and make the 32-bit version a wrapper of it.
    
    Current difftime expects two time_t arguments and returns a
    double. To preserve source-code compatibility, its 64-bit-time
    equivalent expects two __time64_t arguments but still returns
    a double.
    
    * include/time.h (__difftime64): Add.
    * time/difftime.c (subtract): convert to 64-bit time.
    * time/difftime.c (__difftime64): Add.
    * time/difftime.c (__difftime): Wrap around __difftime64.

diff --git a/include/time.h b/include/time.h
index b3b46b0..68d1413 100644
--- a/include/time.h
+++ b/include/time.h
@@ -130,6 +130,12 @@ extern char * __strptime_internal (const char *rp, const char *fmt,
 				   struct tm *tm, void *statep,
 				   locale_t locparam) attribute_hidden;
 
+#if __TIMESIZE == 64
+# define __difftime64 __difftime
+#else
+extern double __difftime64 (__time64_t time1, __time64_t time0);
+#endif
+
 extern double __difftime (time_t time1, time_t time0);
 
 /* Use in the clock_* functions.  Size of the field representing the
diff --git a/time/difftime.c b/time/difftime.c
index 7c5dd98..e3a4e57 100644
--- a/time/difftime.c
+++ b/time/difftime.c
@@ -31,9 +31,9 @@
    time_t is known to be an integer type.  */
 
 static double
-subtract (time_t time1, time_t time0)
+subtract (__time64_t time1, __time64_t time0)
 {
-  if (! TYPE_SIGNED (time_t))
+  if (! TYPE_SIGNED (__time64_t))
     return time1 - time0;
   else
     {
@@ -76,9 +76,9 @@ subtract (time_t time1, time_t time0)
              1 is unsigned in C, so it need not be compared to zero.  */
 
 	  uintmax_t hdt = dt / 2;
-	  time_t ht1 = time1 / 2;
-	  time_t ht0 = time0 / 2;
-	  time_t dht = ht1 - ht0;
+	  __time64_t ht1 = time1 / 2;
+	  __time64_t ht0 = time0 / 2;
+	  __time64_t dht = ht1 - ht0;
 
 	  if (2 < dht - hdt + 1)
 	    {
@@ -99,18 +99,18 @@ subtract (time_t time1, time_t time0)
 
 /* Return the difference between TIME1 and TIME0.  */
 double
-__difftime (time_t time1, time_t time0)
+__difftime64 (__time64_t time1, __time64_t time0)
 {
   /* Convert to double and then subtract if no double-rounding error could
      result.  */
 
-  if (TYPE_BITS (time_t) <= DBL_MANT_DIG
-      || (TYPE_FLOATING (time_t) && sizeof (time_t) < sizeof (long double)))
+  if (TYPE_BITS (__time64_t) <= DBL_MANT_DIG
+      || (TYPE_FLOATING (__time64_t) && sizeof (__time64_t) < sizeof (long double)))
     return (double) time1 - (double) time0;
 
   /* Likewise for long double.  */
 
-  if (TYPE_BITS (time_t) <= LDBL_MANT_DIG || TYPE_FLOATING (time_t))
+  if (TYPE_BITS (__time64_t) <= LDBL_MANT_DIG || TYPE_FLOATING (__time64_t))
     return (long double) time1 - (long double) time0;
 
   /* Subtract the smaller integer from the larger, convert the difference to
@@ -118,4 +118,17 @@ __difftime (time_t time1, time_t time0)
 
   return time1 < time0 ? - subtract (time0, time1) : subtract (time1, time0);
 }
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
+
+double
+__difftime (time_t time1, time_t time0)
+{
+  return __difftime64 (time1, time0);
+}
+
+#endif
+
 strong_alias (__difftime, difftime)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f7d5f7d122cb4929c08f13f5054edc5a8d29d68e

commit f7d5f7d122cb4929c08f13f5054edc5a8d29d68e
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Aug 31 23:45:31 2018 -0700

    Add support for __time64_t to mktime, timegm
    
    * include/time.h, time/mktime.c, time/timegm.c:
    Change externally-visible names to their __xxx64yyy version.
    * include/time.h (fits_in_time_t): New static function.
    * time/mktime.c (mktime) [_LIBC]: New wrapper function.
    * time/timegm.c (timegm) [_LIBC]: New wrapper function.

diff --git a/include/time.h b/include/time.h
index 2710b45..b3b46b0 100644
--- a/include/time.h
+++ b/include/time.h
@@ -3,6 +3,7 @@
 
 #ifndef _ISOMAC
 # include <bits/types/locale_t.h>
+# include <stdbool.h>
 
 extern __typeof (strftime_l) __strftime_l;
 libc_hidden_proto (__strftime_l)
@@ -49,13 +50,13 @@ extern void __tzset_parse_tz (const char *tz) attribute_hidden;
 extern void __tz_compute (__time64_t timer, struct tm *tm, int use_localtime)
   __THROW attribute_hidden;
 
-/* Subroutine of `mktime'.  Return the `time_t' representation of TP and
-   normalize TP, given that a `struct tm *' maps to a `time_t' as performed
+/* Subroutine of mktime.  Return the __time64_t representation of TP and
+   normalize TP, given that a struct tm * maps to a __time64_t as performed
    by FUNC.  Record next guess for localtime-gmtime offset in *OFFSET.  */
-extern time_t __mktime_internal (struct tm *__tp,
-				 struct tm *(*__func) (const time_t *,
-						       struct tm *),
-				 long int *__offset) attribute_hidden;
+extern __time64_t __mktime_internal (struct tm *__tp,
+				     struct tm *(*__func) (const __time64_t *,
+							   struct tm *),
+				     long int *__offset) attribute_hidden;
 
 /* nis/nis_print.c needs ctime, so even if ctime is not declared here,
    we define __ctime64 as ctime so that nis/nis_print.c can get linked
@@ -135,5 +136,13 @@ extern double __difftime (time_t time1, time_t time0);
    actual clock ID.  */
 #define CLOCK_IDFIELD_SIZE	3
 
+/* Check whether a time64_t value fits in a time_t.  */
+static inline bool
+fits_in_time_t (__time64_t t64)
+{
+  time_t t = t64;
+  return t == t64;
+}
+
 #endif
 #endif
diff --git a/time/mktime.c b/time/mktime.c
index 00f0dec..caf39ed 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -51,6 +51,7 @@
 
 #include <time.h>
 
+#include <errno.h>
 #include <limits.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -125,11 +126,11 @@ my_tzset (void)
    to be subtracted from each other, and sometimes with an offset
    added to them, without worrying about overflow.
 
-   Much of the code uses long_int to represent time_t values, to
-   lessen the hassle of dealing with platforms where time_t is
-   unsigned, and because long_int should suffice to represent all
-   time_t values that mktime can generate even on platforms where
-   time_t is excessively wide.  */
+   Much of the code uses long_int to represent __time64_t values, to
+   lessen the hassle of dealing with Gnulib-using platforms where
+   __time64_t is time_t and time_t is unsigned, and because long_int
+   should suffice to represent all __time64_t values that mktime can
+   generate even on platforms where __time64_t is excessively wide.  */
 
 #if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60
 typedef long int long_int;
@@ -157,16 +158,17 @@ shr (long_int a, int b)
 	  : a / (one << b) - (a % (one << b) < 0));
 }
 
-/* Bounds for the intersection of time_t and long_int.  */
+/* Bounds for the intersection of __time64_t and long_int.  */
 
 static long_int const mktime_min
-  = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int))
-     ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t));
+  = ((TYPE_SIGNED (__time64_t)
+      && TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int))
+     ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t));
 static long_int const mktime_max
-  = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t)
-     ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t));
+  = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t)
+     ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t));
 
-verify (TYPE_IS_INTEGER (time_t));
+verify (TYPE_IS_INTEGER (__time64_t));
 
 #define EPOCH_YEAR 1970
 #define TM_YEAR_BASE 1900
@@ -247,11 +249,11 @@ long_int_avg (long_int a, long_int b)
   return shr (a, 1) + shr (b, 1) + ((a | b) & 1);
 }
 
-/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
+/* Return a __time64_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
    assuming that T corresponds to *TP and that no clock adjustments
    occurred between *TP and the desired time.
    Although T and the returned value are of type long_int,
-   they represent time_t values and must be in time_t range.
+   they represent __time64_t values and must be in __time64_t range.
    If TP is null, return a value not equal to T; this avoids false matches.
    YEAR and YDAY must not be so large that multiplying them by three times the
    number of seconds in a year (or day, respectively) would overflow long_int.
@@ -282,22 +284,22 @@ guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
 }
 
 /* Use CONVERT to convert T to a struct tm value in *TM.  T must be in
-   range for time_t.  Return TM if successful, NULL if T is out of
+   range for __time64_t.  Return TM if successful, NULL if T is out of
    range for CONVERT.  */
 static struct tm *
-convert_time (struct tm *(*convert) (const time_t *, struct tm *),
+convert_time (struct tm *(*convert) (const __time64_t *, struct tm *),
 	      long_int t, struct tm *tm)
 {
-  time_t x = t;
+  __time64_t x = t;
   return convert (&x, tm);
 }
 
 /* Use CONVERT to convert *T to a broken down time in *TP.
    If *T is out of range for conversion, adjust it so that
    it is the nearest in-range value and then convert that.
-   A value is in range if it fits in both time_t and long_int.  */
+   A value is in range if it fits in both __time64_t and long_int.  */
 static struct tm *
-ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
+ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *),
 		long_int *t, struct tm *tp)
 {
   struct tm *r;
@@ -339,15 +341,15 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
 }
 
 
-/* Convert *TP to a time_t value, inverting
+/* Convert *TP to a __time64_t value, inverting
    the monotonic and mostly-unit-linear conversion function CONVERT.
    Use *OFFSET to keep track of a guess at the offset of the result,
    compared to what the result would be for UTC without leap seconds.
    If *OFFSET's guess is correct, only one CONVERT call is needed.
    This function is external because it is used also by timegm.c.  */
-time_t
+__time64_t
 __mktime_internal (struct tm *tp,
-		   struct tm *(*convert) (const time_t *, struct tm *),
+		   struct tm *(*convert) (const __time64_t *, struct tm *),
 		   mktime_offset_t *offset)
 {
   long_int t, gt, t0, t1, t2, dt;
@@ -518,9 +520,9 @@ __mktime_internal (struct tm *tp,
 
 #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
 
-/* Convert *TP to a time_t value.  */
-time_t
-mktime (struct tm *tp)
+/* Convert *TP to a __time64_t value.  */
+__time64_t
+__mktime64 (struct tm *tp)
 {
   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
      time zone names contained in the external variable 'tzname' shall
@@ -529,7 +531,7 @@ mktime (struct tm *tp)
 
 # if defined _LIBC || NEED_MKTIME_WORKING
   static mktime_offset_t localtime_offset;
-  return __mktime_internal (tp, __localtime_r, &localtime_offset);
+  return __mktime_internal (tp, __localtime64_r, &localtime_offset);
 # else
 #  undef mktime
   return mktime (tp);
@@ -537,8 +539,22 @@ mktime (struct tm *tp)
 }
 #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
 
+#ifdef _LIBC
+/* The 32-bit-time wrapper.  */
+time_t
+mktime (struct tm *tp)
+{
+  __time64_t t64 = __mktime64 (tp);
+  if (fits_in_time_t (t64))
+    return t64;
+  __set_errno (EOVERFLOW);
+  return -1;
+}
+#endif
+
 #ifdef weak_alias
 weak_alias (mktime, timelocal)
+weak_alias (__mktime64, __timelocal64)
 #endif
 
 #ifdef _LIBC
diff --git a/time/timegm.c b/time/timegm.c
index 229fff2..99b5436 100644
--- a/time/timegm.c
+++ b/time/timegm.c
@@ -24,11 +24,26 @@
 #include <time.h>
 
 #include "mktime-internal.h"
+#include <errno.h>
+
+__time64_t
+__timegm64 (struct tm *tmp)
+{
+  static long int gmtime_offset;
+  tmp->tm_isdst = 0;
+  return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset);
+}
+
+#ifdef _LIBC
 
 time_t
 timegm (struct tm *tmp)
 {
-  static mktime_offset_t gmtime_offset;
-  tmp->tm_isdst = 0;
-  return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
+  __time64_t t64 = __timegm64 (tmp);
+  if (fits_in_time_t (t64))
+    return t64;
+  __set_errno (EOVERFLOW);
+  return -1;
 }
+
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7fc661e675ded113a0ef4cd1779d140a41e34dbd

commit 7fc661e675ded113a0ef4cd1779d140a41e34dbd
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Mon Jun 18 21:14:43 2018 +0200

    Y2038: make __tz_convert compatible with 64-bit-time
    
    Now that __time_64_t exists, we can switch internal function
    __tz_convert from 32-bit to 64-bit time. This involves switching
    some other internal functions and turning some implementations
    which use these into wrappers between public 32-bit and internal
    64-bit time.
    
    This patch was tested by running 'make check' on branch
    master then applying this patch and its two predecessors and
    running 'make check' again, and checking that both 'make check'
    yield identical results. This was done on x86_64-linux-gnu and
    i686-linux-gnu.
    
    * include/time.h (__tz_compute): replace time_t with __time64_t
    * include/time.h (__ctime64): Add.
    * include/time.h (__ctime64_r): Likewise.
    * include/time.h (__localtime64): Likewise.
    * include/time.h (__localtime64_r): Likewise.
    * include/time.h (__gmtime64): Likewise.
    * include/time.h (__gmtime64_r): Likewise.
    * include/time.h (__offtime): Replace const time_t* argument
      with __time64_t.
    * include/time.h (__tz_convert): Likewise.
    * time/ctime.c (__ctime64): Add.
    * time/ctime.c (__ctime): Turn into a wrapper.
    * time/ctime_r.c (__ctime64_r): Add.
    * time/ctime_r.c (__ctime_r): Turn into a wrapper.
    * time/gmtime.c (__gmtime64): Add.
    * time/gmtime.c (__gmtime): Turn into a wrapper.
    * time/gmtime.c (__gmtime64_r): Add.
    * time/gmtime.c (__gmtime_r): Turn into a wrapper.
    * time/localtime.c (__localtime64): Add.
    * time/localtime.c (__localtime): Turn into a wrapper.
    * time/localtime.c (__localtime64_r): Add.
    * time/localtime.c (__localtime_r): Turn into a wrapper.
    * time/offtime.c (__offtime): Replace const time_t* argument
      with __time64_t.
    * time/offtime.c (__offtime): Turn all time_t variables
      into __time64_t ones.
    * time/tzfile.c (__tzfile_compute): fix call to __offtime.
    * time/tzset.c: Turn all time_t variables into __time64_t ones.
    * time/tzset.c (__tz_convert): fix call to __tzfile_compute.
    * time/tzset.c (__tz_convert): fix call to __tz_compute.

diff --git a/include/time.h b/include/time.h
index e99711a..2710b45 100644
--- a/include/time.h
+++ b/include/time.h
@@ -46,7 +46,7 @@ extern void __tzfile_default (const char *std, const char *dst,
 			      long int stdoff, long int dstoff)
   attribute_hidden;
 extern void __tzset_parse_tz (const char *tz) attribute_hidden;
-extern void __tz_compute (time_t timer, struct tm *tm, int use_localtime)
+extern void __tz_compute (__time64_t timer, struct tm *tm, int use_localtime)
   __THROW attribute_hidden;
 
 /* Subroutine of `mktime'.  Return the `time_t' representation of TP and
@@ -56,18 +56,52 @@ extern time_t __mktime_internal (struct tm *__tp,
 				 struct tm *(*__func) (const time_t *,
 						       struct tm *),
 				 long int *__offset) attribute_hidden;
+
+/* nis/nis_print.c needs ctime, so even if ctime is not declared here,
+   we define __ctime64 as ctime so that nis/nis_print.c can get linked
+   against a function called ctime. */
+#if __TIMESIZE == 64
+# define __ctime64 ctime
+#endif
+
+#if __TIMESIZE == 64
+# define __ctime64_r ctime_r
+#endif
+
+#if __TIMESIZE == 64
+# define __localtime64 localtime
+#else
+extern struct tm *__localtime64 (const __time64_t *__timer);
+libc_hidden_proto (__localtime64)
+#endif
+
 extern struct tm *__localtime_r (const time_t *__timer,
 				 struct tm *__tp) attribute_hidden;
 
+#if __TIMESIZE == 64
+# define __localtime64_r __localtime_r
+#else
+extern struct tm *__localtime64_r (const __time64_t *__timer,
+				   struct tm *__tp) attribute_hidden;
+#endif
+
 extern struct tm *__gmtime_r (const time_t *__restrict __timer,
 			      struct tm *__restrict __tp);
 libc_hidden_proto (__gmtime_r)
 
-/* Compute the `struct tm' representation of *T,
+#if __TIMESIZE == 64
+# define __gmtime64 gmtime
+# define __gmtime64_r __gmtime_r
+#else
+extern struct tm *__gmtime64_r (const __time64_t *__restrict __timer,
+			        struct tm *__restrict __tp);
+#endif
+
+/* Compute the `struct tm' representation of T,
    offset OFFSET seconds east of UTC,
    and store year, yday, mon, mday, wday, hour, min, sec into *TP.
    Return nonzero if successful.  */
-extern int __offtime (const time_t *__timer,
+extern int __offtime (__time64_t __timer,
 		      long int __offset,
 		      struct tm *__tp) attribute_hidden;
 
@@ -76,8 +110,8 @@ extern char *__asctime_r (const struct tm *__tp, char *__buf)
 extern void __tzset (void) attribute_hidden;
 
 /* Prototype for the internal function to get information based on TZ.  */
-extern struct tm *__tz_convert (const time_t *timer, int use_localtime,
-				struct tm *tp) attribute_hidden;
+extern struct tm *__tz_convert (__time64_t timer, int use_localtime,
+			        struct tm *tp) attribute_hidden;
 
 extern int __nanosleep (const struct timespec *__requested_time,
 			struct timespec *__remaining);
diff --git a/time/ctime.c b/time/ctime.c
index 1222614..286c6b5 100644
--- a/time/ctime.c
+++ b/time/ctime.c
@@ -20,9 +20,22 @@
 /* Return a string as returned by asctime which
    is the representation of *T in that form.  */
 char *
-ctime (const time_t *t)
+__ctime64 (const __time64_t *t)
 {
   /* The C Standard says ctime (t) is equivalent to asctime (localtime (t)).
      In particular, ctime and asctime must yield the same pointer.  */
-  return asctime (localtime (t));
+  return asctime (__localtime64 (t));
 }
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
+
+char *
+ctime (const time_t *t)
+{
+  __time64_t t64 = *t;
+  return __ctime64 (&t64);
+}
+
+#endif
diff --git a/time/ctime_r.c b/time/ctime_r.c
index c111146..8408959 100644
--- a/time/ctime_r.c
+++ b/time/ctime_r.c
@@ -22,8 +22,21 @@
 /* Return a string as returned by asctime which is the representation
    of *T in that form.  Reentrant version.  */
 char *
-ctime_r (const time_t *t, char *buf)
+__ctime64_r (const __time64_t *t, char *buf)
 {
   struct tm tm;
-  return __asctime_r (__localtime_r (t, &tm), buf);
+  return __asctime_r (__localtime64_r (t, &tm), buf);
 }
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
+
+char *
+ctime_r (const time_t *t, char *buf)
+{
+  __time64_t t64 = *t;
+  return __ctime64_r (&t64, buf);
+}
+
+#endif
diff --git a/time/gmtime.c b/time/gmtime.c
index dc33b3e..d485a38 100644
--- a/time/gmtime.c
+++ b/time/gmtime.c
@@ -18,20 +18,49 @@
 
 #include <time.h>
 
-/* Return the `struct tm' representation of *T in UTC,
+/* Return the `struct tm' representation of T in UTC,
    using *TP to store the result.  */
 struct tm *
+__gmtime64_r (const __time64_t *t, struct tm *tp)
+{
+  return __tz_convert (*t, 0, tp);
+}
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
+
+struct tm *
 __gmtime_r (const time_t *t, struct tm *tp)
 {
-  return __tz_convert (t, 0, tp);
+  __time64_t t64 = *t;
+  return __gmtime64_r (&t64, tp);
 }
+
+#endif
+
+/* This always works because either __TIMESIZE != 64 and __gmtime_r exists
+   or __TIMESIZE == 64 and the definition of __gmtime64_r above actually
+   defined __gmtime_r.  */
 libc_hidden_def (__gmtime_r)
 weak_alias (__gmtime_r, gmtime_r)
 
+/* Return the `struct tm' representation of 64-bit-time *T in UTC.	*/
+struct tm *
+__gmtime64 (const __time64_t *t)
+{
+  return __tz_convert (*t, 0, &_tmbuf);
+}
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
 
-/* Return the `struct tm' representation of *T in UTC.	*/
 struct tm *
 gmtime (const time_t *t)
 {
-  return __tz_convert (t, 0, &_tmbuf);
+  __time64_t t64 = *t;
+  return __gmtime64 (&t64);
 }
+
+#endif
diff --git a/time/localtime.c b/time/localtime.c
index 8684a8a..8e3b76e 100644
--- a/time/localtime.c
+++ b/time/localtime.c
@@ -21,21 +21,50 @@
 /* The C Standard says that localtime and gmtime return the same pointer.  */
 struct tm _tmbuf;
 
-
 /* Return the `struct tm' representation of *T in local time,
    using *TP to store the result.  */
 struct tm *
+__localtime64_r (const __time64_t *t, struct tm *tp)
+{
+  return __tz_convert (*t, 1, tp);
+}
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
+
+struct tm *
 __localtime_r (const time_t *t, struct tm *tp)
 {
-  return __tz_convert (t, 1, tp);
+  __time64_t t64 = *t;
+  return __localtime64_r (&t64, tp);
 }
-weak_alias (__localtime_r, localtime_r)
 
+#endif
+
+/* This always works because either __TIMESIZE != 64 and __localtime_r
+   exists or __TIMESIZE == 64 and the definition of __localtime64_r above
+   actually defined __localtime_r.  */
+weak_alias (__localtime_r, localtime_r)
 
 /* Return the `struct tm' representation of *T in local time.  */
 struct tm *
+__localtime64 (const __time64_t *t)
+{
+  return __tz_convert (*t, 1, &_tmbuf);
+}
+libc_hidden_def (__localtime64)
+
+/* Provide a 32-bit wrapper if needed */
+
+#if __TIMESIZE != 64
+
+struct tm *
 localtime (const time_t *t)
 {
-  return __tz_convert (t, 1, &_tmbuf);
+  __time64_t t64 = *t;
+  return __localtime64 (&t64);
 }
 libc_hidden_def (localtime)
+
+#endif
diff --git a/time/offtime.c b/time/offtime.c
index 04c4838..3309fcd 100644
--- a/time/offtime.c
+++ b/time/offtime.c
@@ -21,18 +21,18 @@
 #define	SECS_PER_HOUR	(60 * 60)
 #define	SECS_PER_DAY	(SECS_PER_HOUR * 24)
 
-/* Compute the `struct tm' representation of *T,
+/* Compute the `struct tm' representation of T,
    offset OFFSET seconds east of UTC,
    and store year, yday, mon, mday, wday, hour, min, sec into *TP.
    Return nonzero if successful.  */
 int
-__offtime (const time_t *t, long int offset, struct tm *tp)
+__offtime (__time64_t t, long int offset, struct tm *tp)
 {
-  time_t days, rem, y;
+  __time64_t days, rem, y;
   const unsigned short int *ip;
 
-  days = *t / SECS_PER_DAY;
-  rem = *t % SECS_PER_DAY;
+  days = t / SECS_PER_DAY;
+  rem = t % SECS_PER_DAY;
   rem += offset;
   while (rem < 0)
     {
@@ -60,7 +60,7 @@ __offtime (const time_t *t, long int offset, struct tm *tp)
   while (days < 0 || days >= (__isleap (y) ? 366 : 365))
     {
       /* Guess a corrected year, assuming 365 days per year.  */
-      time_t yg = y + days / 365 - (days % 365 < 0);
+      __time64_t yg = y + days / 365 - (days % 365 < 0);
 
       /* Adjust DAYS and Y to match the guessed year.  */
       days -= ((yg - y) * 365
diff --git a/time/tzfile.c b/time/tzfile.c
index 844a68d..3920525 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -633,16 +633,10 @@ __tzfile_compute (__time64_t timer, int use_localtime,
 
 	  /* Convert to broken down structure.  If this fails do not
 	     use the string.  */
-	  {
-	    time_t truncated = timer;
-	    if (__glibc_unlikely (truncated != timer
-				  || ! __offtime (&truncated, 0, tp)))
-	      goto use_last;
-	  }
-
-	  /* Use the rules from the TZ string to compute the change.
-	     timer fits into time_t due to the truncation check
-	     above.  */
+	  if (__glibc_unlikely (! __offtime (timer, 0, tp)))
+	    goto use_last;
+
+	  /* Use the rules from the TZ string to compute the change.  */
 	  __tz_compute (timer, tp, 1);
 
 	  /* If tzspec comes from posixrules loaded by __tzfile_default,
diff --git a/time/tzset.c b/time/tzset.c
index a828b9f..834cc3c 100644
--- a/time/tzset.c
+++ b/time/tzset.c
@@ -16,7 +16,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <ctype.h>
-#include <errno.h>
 #include <libc-lock.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -27,7 +26,7 @@
 
 #include <timezone/tzfile.h>
 
-#define SECSPERDAY ((time_t) 86400)
+#define SECSPERDAY ((__time64_t) 86400)
 
 char *__tzname[2] = { (char *) "GMT", (char *) "GMT" };
 int __daylight = 0;
@@ -55,7 +54,7 @@ typedef struct
 
     /* We cache the computed time of change for a
        given year so we don't have to recompute it.  */
-    time_t change;	/* When to change to this zone.  */
+    __time64_t change;	/* When to change to this zone.  */
     int computed_for;	/* Year above is computed for.  */
   } tz_rule;
 
@@ -416,7 +415,7 @@ tzset_internal (int always)
       tz_rules[0].name = tz_rules[1].name = "UTC";
       if (J0 != 0)
 	tz_rules[0].type = tz_rules[1].type = J0;
-      tz_rules[0].change = tz_rules[1].change = (time_t) -1;
+      tz_rules[0].change = tz_rules[1].change = -1;
       update_vars ();
       return;
     }
@@ -424,13 +423,13 @@ tzset_internal (int always)
   __tzset_parse_tz (tz);
 }
 
-/* Figure out the exact time (as a time_t) in YEAR
+/* Figure out the exact time (as a __time64_t) in YEAR
    when the change described by RULE will occur and
    put it in RULE->change, saving YEAR in RULE->computed_for.  */
 static void
 compute_change (tz_rule *rule, int year)
 {
-  time_t t;
+  __time64_t t;
 
   if (year != -1 && rule->computed_for == year)
     /* Operations on times in 2 BC will be slower.  Oh well.  */
@@ -516,7 +515,7 @@ compute_change (tz_rule *rule, int year)
 /* Figure out the correct timezone for TM and set `__tzname',
    `__timezone', and `__daylight' accordingly.  */
 void
-__tz_compute (time_t timer, struct tm *tm, int use_localtime)
+__tz_compute (__time64_t timer, struct tm *tm, int use_localtime)
 {
   compute_change (&tz_rules[0], 1900 + tm->tm_year);
   compute_change (&tz_rules[1], 1900 + tm->tm_year);
@@ -562,20 +561,14 @@ __tzset (void)
 }
 weak_alias (__tzset, tzset)
 
-/* Return the `struct tm' representation of *TIMER in the local timezone.
+/* Return the `struct tm' representation of TIMER in the local timezone.
    Use local time if USE_LOCALTIME is nonzero, UTC otherwise.  */
 struct tm *
-__tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
+__tz_convert (__time64_t timer, int use_localtime, struct tm *tp)
 {
   long int leap_correction;
   int leap_extra_secs;
 
-  if (timer == NULL)
-    {
-      __set_errno (EINVAL);
-      return NULL;
-    }
-
   __libc_lock_lock (tzset_lock);
 
   /* Update internal database according to current TZ setting.
@@ -584,14 +577,14 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
   tzset_internal (tp == &_tmbuf && use_localtime);
 
   if (__use_tzfile)
-    __tzfile_compute (*timer, use_localtime, &leap_correction,
+    __tzfile_compute (timer, use_localtime, &leap_correction,
 		      &leap_extra_secs, tp);
   else
     {
       if (! __offtime (timer, 0, tp))
 	tp = NULL;
       else
-	__tz_compute (*timer, tp, use_localtime);
+	__tz_compute (timer, tp, use_localtime);
       leap_correction = 0L;
       leap_extra_secs = 0;
     }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=cdd465cb7a612a25899ff7b28742038099585e13

commit cdd465cb7a612a25899ff7b28742038099585e13
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Mon Jun 18 21:14:42 2018 +0200

    Y2038: Add 64-bit time for all architectures
    
    glibc support for 64-bit time_t on 32-bit architectures
    will involve:
    
    - Using 64-bit times inside glibc, with conversions
      to and from 32-bit times taking place as necessary
      for interfaces using such times.
    
    - Adding 64-bit-time support in the glibc public API.
      This support should be dynamic, i.e. glibc should
      provide both 32-bit and 64-bit implementations and
       let user code choose at compile time whether to use
       the 32-bit or 64-bit interfaces.
    
    This requires a glibc-internal name for a type for times
    that are always 64-bit.
    
    Based on __TIMESIZE, a new macro is defined, __TIME64_T_TYPE,
     which is always the right __*_T_TYPE to hold a 64-bit-time.
    __TIME64_T_TYPE equals __TIME_T_TYPE if __TIMESIZE equals 64
    and equals __SQUAD_T_TYPE otherwise.
    
    __time64_t can then replace uses of internal_time_t.
    
    This patch was tested by running 'make check' on branch
    master then applying this patch and its predecessor and
    running 'make check' again, and checking that both 'make
    check' yield identical results. This was done on
    x86_64-linux-gnu and i686-linux-gnu.
    
    * bit/time64.h: New file.
    * include/time.h: Replace internal_time_t with __time64_t.
    * posix/bits/types (__time64_t): Add.
    * stdlib/Makefile: Add bits/timesize.h to includes.
    * stdlib/Makefile: Add bits/time64.h to includes.
    * time/tzfile.c: Replace internal_time_t with __time64_t.

diff --git a/bits/time64.h b/bits/time64.h
new file mode 100644
index 0000000..c8a9c7d
--- /dev/null
+++ b/bits/time64.h
@@ -0,0 +1,36 @@
+/* bits/time64.h -- underlying types for __time64_t.  Generic version.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/time64.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef	_BITS_TIME64_H
+#define	_BITS_TIME64_H	1
+
+/* Define __TIME64_T_TYPE so that it is always a 64-bit type.  */
+
+#if __TIMESIZE == 64
+/* If we already have 64-bit time type then use it.  */
+# define __TIME64_T_TYPE		__TIME_T_TYPE
+#else
+/* Define a 64-bit time type alongsize the 32-bit one.  */
+# define __TIME64_T_TYPE		__SQUAD_TYPE
+#endif
+
+#endif /* bits/time64.h */
diff --git a/include/time.h b/include/time.h
index e30c5fc..e99711a 100644
--- a/include/time.h
+++ b/include/time.h
@@ -26,10 +26,6 @@ extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
 /* Now define the internal interfaces.  */
 struct tm;
 
-/* time_t variant for representing time zone data, independent of
-   time_t.  */
-typedef __int64_t internal_time_t;
-
 /* Defined in mktime.c.  */
 extern const unsigned short int __mon_yday[2][13] attribute_hidden;
 
@@ -43,7 +39,7 @@ extern int __use_tzfile attribute_hidden;
 
 extern void __tzfile_read (const char *file, size_t extra,
 			   char **extrap) attribute_hidden;
-extern void __tzfile_compute (internal_time_t timer, int use_localtime,
+extern void __tzfile_compute (__time64_t timer, int use_localtime,
 			      long int *leap_correct, int *leap_hit,
 			      struct tm *tp) attribute_hidden;
 extern void __tzfile_default (const char *std, const char *dst,
@@ -101,7 +97,6 @@ extern char * __strptime_internal (const char *rp, const char *fmt,
 
 extern double __difftime (time_t time1, time_t time0);
 
-
 /* Use in the clock_* functions.  Size of the field representing the
    actual clock ID.  */
 #define CLOCK_IDFIELD_SIZE	3
diff --git a/posix/bits/types.h b/posix/bits/types.h
index 5e22ce4..cda0a70 100644
--- a/posix/bits/types.h
+++ b/posix/bits/types.h
@@ -25,6 +25,7 @@
 
 #include <features.h>
 #include <bits/wordsize.h>
+#include <bits/timesize.h>
 
 /* Convenience types.  */
 typedef unsigned char __u_char;
@@ -138,6 +139,7 @@ __extension__ typedef unsigned long long int __uintmax_t;
 # error
 #endif
 #include <bits/typesizes.h>	/* Defines __*_T_TYPE macros.  */
+#include <bits/time64.h>	/* Defines __TIME*_T_TYPE macros.  */
 
 
 __STD_TYPE __DEV_T_TYPE __dev_t;	/* Type of device numbers.  */
@@ -211,6 +213,12 @@ __STD_TYPE __U32_TYPE __socklen_t;
    It is not currently necessary for this to be machine-specific.  */
 typedef int __sig_atomic_t;
 
+#if __TIMESIZE == 64
+# define __time64_t __time_t
+#else
+__STD_TYPE __TIME64_T_TYPE __time64_t;	/* Seconds since the Epoch.  */
+#endif
+
 #undef __STD_TYPE
 
 #endif /* bits/types.h */
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 01194bb..bdb0a18 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -29,7 +29,7 @@ headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   ucontext.h sys/ucontext.h bits/indirect-return.h		      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
-	   bits/stdint-uintn.h
+	   bits/stdint-uintn.h bits/time64.h bits/timesize.h		      \
 
 routines	:=							      \
 	atof atoi atol atoll						      \
diff --git a/time/tzfile.c b/time/tzfile.c
index 72ef75f..844a68d 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -44,12 +44,12 @@ struct ttinfo
 
 struct leap
   {
-    internal_time_t transition;	/* Time the transition takes effect.  */
+    __time64_t transition;	/* Time the transition takes effect.  */
     long int change;		/* Seconds of correction to apply.  */
   };
 
 static size_t num_transitions;
-libc_freeres_ptr (static internal_time_t *transitions);
+libc_freeres_ptr (static __time64_t *transitions);
 static unsigned char *type_idxs;
 static size_t num_types;
 static struct ttinfo *types;
@@ -113,8 +113,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
   size_t tzspec_len;
   char *new = NULL;
 
-  _Static_assert (sizeof (internal_time_t) == 8,
-		  "internal_time_t must be eight bytes");
+  _Static_assert (sizeof (__time64_t) == 8,
+		  "__time64_t must be eight bytes");
 
   __use_tzfile = 0;
 
@@ -217,9 +217,9 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
 
   if (__builtin_expect (num_transitions
 			> ((SIZE_MAX - (__alignof__ (struct ttinfo) - 1))
-			   / (sizeof (internal_time_t) + 1)), 0))
+			   / (sizeof (__time64_t) + 1)), 0))
     goto lose;
-  total_size = num_transitions * (sizeof (internal_time_t) + 1);
+  total_size = num_transitions * (sizeof (__time64_t) + 1);
   total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
 		& ~(__alignof__ (struct ttinfo) - 1));
   types_idx = total_size;
@@ -276,7 +276,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
     goto lose;
 
   type_idxs = (unsigned char *) transitions + (num_transitions
-					       * sizeof (internal_time_t));
+					       * sizeof (__time64_t));
   types = (struct ttinfo *) ((char *) transitions + types_idx);
   zone_names = (char *) types + num_types * sizeof (struct ttinfo);
   leaps = (struct leap *) ((char *) transitions + leaps_idx);
@@ -578,7 +578,7 @@ __tzfile_default (const char *std, const char *dst,
 }
 
 void
-__tzfile_compute (internal_time_t timer, int use_localtime,
+__tzfile_compute (__time64_t timer, int use_localtime,
 		  long int *leap_correct, int *leap_hit,
 		  struct tm *tp)
 {
@@ -667,7 +667,7 @@ __tzfile_compute (internal_time_t timer, int use_localtime,
 	     initial search spot from it.  Half of a gregorian year
 	     has on average 365.2425 * 86400 / 2 = 15778476 seconds.
 	     The value i can be truncated if size_t is smaller than
-	     internal_time_t, but this is harmless because it is just
+	     __time64_t, but this is harmless because it is just
 	     a guess.  */
 	  i = (transitions[num_transitions - 1] - timer) / 15778476;
 	  if (i < num_transitions)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5d8079b96dae8b6d1f581999db5c601af4d86a5a

commit 5d8079b96dae8b6d1f581999db5c601af4d86a5a
Author: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Date:   Thu Oct 11 19:47:29 2018 +0200

    Y2038: provide size of default time_t for target architecture
    
    To determine whether the default time_t interfaces are 32-bit
    and so need conversions, or are 64-bit and so are compatible
    with the internal 64-bit type without conversions, a macro
    giving the size of the  default time_t is also required.
    This macro is called __TIMESIZE.
    
    This macro can then be used instead of __WORDSIZE in msq-pad.h
    files, which in turn allows removing the x86 variant of them.
    
    This patch was tested by running 'make check' on branch master
    then applying this patch and running 'make check' again, and
    checking that both 'make check' yield identical results.
    This was done on x86_64-linux-gnu and i686-linux-gnu.
    
    * bits/timesize.h: New file.
    * sysdeps/unix/sysv/linux/bits/msq-pad.h: Replace __WORDSIZE with __TIMESIZE.
    * sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h: Likewise.
    * sysdeps/unix/sysv/linux/mips/bits/msq-pad.h: Likewise.
    * sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h: Likewise.
    * sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h: Likewise.
    * sysdeps/unix/sysv/linux/x86/bits/msq-pad.h: Delete file.
    * sysdeps/unix/sysv/linux/x86/bits/timesize.h: New file.

diff --git a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h b/bits/timesize.h
similarity index 76%
copy from sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
copy to bits/timesize.h
index 10b26b7..cc47ff1 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
+++ b/bits/timesize.h
@@ -1,4 +1,4 @@
-/* Define where padding goes in struct msqid_ds.  HPPA version.
+/* Bit size of the time_t type at glibc build time, general case.
    Copyright (C) 2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,11 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
 #include <bits/wordsize.h>
 
-#define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__WORDSIZE == 32)
+/* Size in bits of the 'time_t' type of the default ABI.  */
+#define __TIMESIZE	__WORDSIZE
diff --git a/sysdeps/unix/sysv/linux/bits/msq-pad.h b/sysdeps/unix/sysv/linux/bits/msq-pad.h
index 97dee0b..53f367d 100644
--- a/sysdeps/unix/sysv/linux/bits/msq-pad.h
+++ b/sysdeps/unix/sysv/linux/bits/msq-pad.h
@@ -20,12 +20,12 @@
 # error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
 #endif
 
-#include <bits/wordsize.h>
+#include <bits/timesize.h>
 
 /* On most architectures, padding goes after time fields for 32-bit
    systems and is omitted for 64-bit systems.  Some architectures pad
    before time fields instead, or omit padding despite being
    32-bit.  */
 
-#define __MSQ_PAD_AFTER_TIME (__WORDSIZE == 32)
+#define __MSQ_PAD_AFTER_TIME (__TIMESIZE == 32)
 #define __MSQ_PAD_BEFORE_TIME 0
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h b/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
index 10b26b7..05db3fd 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
@@ -20,7 +20,7 @@
 # error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
 #endif
 
-#include <bits/wordsize.h>
+#include <bits/timesize.h>
 
 #define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__WORDSIZE == 32)
+#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h b/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
index 1ddfb0d..530babe 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
@@ -20,12 +20,12 @@
 # error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
 #endif
 
-#include <bits/wordsize.h>
+#include <bits/timesize.h>
 
 #ifdef __MIPSEL__
-# define __MSQ_PAD_AFTER_TIME (__WORDSIZE == 32)
+# define __MSQ_PAD_AFTER_TIME (__TIMESIZE == 32)
 # define __MSQ_PAD_BEFORE_TIME 0
 #else
 # define __MSQ_PAD_AFTER_TIME 0
-# define __MSQ_PAD_BEFORE_TIME (__WORDSIZE == 32)
+# define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h b/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
index 9680176..d19dfd5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
@@ -20,7 +20,7 @@
 # error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
 #endif
 
-#include <bits/wordsize.h>
+#include <bits/timesize.h>
 
 #define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__WORDSIZE == 32)
+#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h b/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
index 3dfeb07..72324e8 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
@@ -20,7 +20,7 @@
 # error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
 #endif
 
-#include <bits/wordsize.h>
+#include <bits/timesize.h>
 
 #define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__WORDSIZE == 32)
+#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/x86/bits/msq-pad.h b/sysdeps/unix/sysv/linux/x86/bits/timesize.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/x86/bits/msq-pad.h
rename to sysdeps/unix/sysv/linux/x86/bits/timesize.h
index 5d46956..8b88ab8 100644
--- a/sysdeps/unix/sysv/linux/x86/bits/msq-pad.h
+++ b/sysdeps/unix/sysv/linux/x86/bits/timesize.h
@@ -1,4 +1,4 @@
-/* Define where padding goes in struct msqid_ds.  x86 version.
+/* Bit size of the time_t type at glibc build time, x86-64 and x32 case.
    Copyright (C) 2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,13 +16,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
-#ifdef __x86_64__
-# define __MSQ_PAD_AFTER_TIME 0
+#if defined __x86_64__ && defined __ILP32__
+/* For x32, time is 64-bit even though word size is 32-bit.  */
+# define __TIMESIZE	64
 #else
-# define __MSQ_PAD_AFTER_TIME 1
+/* For others, time size is word size.  */
+# define __TIMESIZE	__WORDSIZE
 #endif
-#define __MSQ_PAD_BEFORE_TIME 0

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]