about summary refs log tree commit diff
path: root/time
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-02-17 13:35:19 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-06-15 10:42:11 -0300
commit47f24c21ee38701ae275aa9e451f70fa3e77478c (patch)
treeb4cc52206173fb2ed427a1e797769d12369a89ad /time
parent8af344feb5ae3e6e3374a6cf2175b44cc904a94e (diff)
downloadglibc-47f24c21ee38701ae275aa9e451f70fa3e77478c.tar.gz
glibc-47f24c21ee38701ae275aa9e451f70fa3e77478c.tar.xz
glibc-47f24c21ee38701ae275aa9e451f70fa3e77478c.zip
y2038: Add support for 64-bit time on legacy ABIs
A new build flag, _TIME_BITS, enables the usage of the newer 64-bit
time symbols for legacy ABI (where 32-bit time_t is default).  The 64
bit time support is only enabled if LFS (_FILE_OFFSET_BITS=64) is
also used.

Different than LFS support, the y2038 symbols are added only for the
required ABIs (armhf, csky, hppa, i386, m68k, microblaze, mips32,
mips64-n32, nios2, powerpc32, sparc32, s390-32, and sh).  The ABIs with
64-bit time support are unchanged, both for symbol and types
redirection.

On Linux the full 64-bit time support requires a minimum of kernel
version v5.1.  Otherwise, the 32-bit fallbacks are used and might
results in error with overflow return code (EOVERFLOW).

The i686-gnu does not yet support 64-bit time.

This patch exports following rediretions to support 64-bit time:

  * libc:
    adjtime
    adjtimex
    clock_adjtime
    clock_getres
    clock_gettime
    clock_nanosleep
    clock_settime
    cnd_timedwait
    ctime
    ctime_r
    difftime
    fstat
    fstatat
    futimens
    futimes
    futimesat
    getitimer
    getrusage
    gettimeofday
    gmtime
    gmtime_r
    localtime
    localtime_r
    lstat_time
    lutimes
    mktime
    msgctl
    mtx_timedlock
    nanosleep
    nanosleep
    ntp_gettime
    ntp_gettimex
    ppoll
    pselec
    pselect
    pthread_clockjoin_np
    pthread_cond_clockwait
    pthread_cond_timedwait
    pthread_mutex_clocklock
    pthread_mutex_timedlock
    pthread_rwlock_clockrdlock
    pthread_rwlock_clockwrlock
    pthread_rwlock_timedrdlock
    pthread_rwlock_timedwrlock
    pthread_timedjoin_np
    recvmmsg
    sched_rr_get_interval
    select
    sem_clockwait
    semctl
    semtimedop
    sem_timedwait
    setitimer
    settimeofday
    shmctl
    sigtimedwait
    stat
    thrd_sleep
    time
    timegm
    timerfd_gettime
    timerfd_settime
    timespec_get
    utime
    utimensat
    utimes
    utimes
    wait3
    wait4

  * librt:
    aio_suspend
    mq_timedreceive
    mq_timedsend
    timer_gettime
    timer_settime

  * libanl:
    gai_suspend

Reviewed-by: Lukasz Majewski <lukma@denx.de>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'time')
-rw-r--r--time/sys/time.h71
-rw-r--r--time/time.h138
2 files changed, 206 insertions, 3 deletions
diff --git a/time/sys/time.h b/time/sys/time.h
index 42f91f186b..d21411c0b4 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -63,10 +63,21 @@ struct timezone
    use localtime etc. instead.
    This function itself is semi-obsolete;
    most callers should use time or clock_gettime instead. */
+#ifndef __USE_TIME_BITS64
 extern int gettimeofday (struct timeval *__restrict __tv,
 			 void *__restrict __tz) __THROW __nonnull ((1));
+#else
+# ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (gettimeofday, (struct timeval *__restrict __tv,
+                                          void *__restrict __tz),
+                           __gettimeofday64) __nonnull ((1));
+# else
+#  define gettimeofday __gettimeofday64
+# endif
+#endif
 
 #ifdef __USE_MISC
+# ifndef __USE_TIME_BITS64
 /* Set the current time of day and timezone information.
    This call is restricted to the super-user.
    Setting the timezone in this way is obsolete, but we don't yet
@@ -82,6 +93,20 @@ extern int settimeofday (const struct timeval *__tv,
    This call is restricted to the super-user.  */
 extern int adjtime (const struct timeval *__delta,
 		    struct timeval *__olddelta) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (settimeofday, (const struct timeval *__tv,
+                                          const struct timezone *__tz),
+                           __settimeofday64);
+
+extern int __REDIRECT_NTH (adjtime, (const struct timeval *__delta,
+                                     struct timeval *__olddelta),
+                           __adjtime64);
+#  else
+#   define settimeofday __settimeofday64
+#   define adjtime __adjtime64
+#  endif
+# endif
 #endif
 
 
@@ -118,6 +143,7 @@ typedef enum __itimer_which __itimer_which_t;
 typedef int __itimer_which_t;
 #endif
 
+#ifndef __USE_TIME_BITS64
 /* Set *VALUE to the current setting of timer WHICH.
    Return 0 on success, -1 on errors.  */
 extern int getitimer (__itimer_which_t __which,
@@ -136,21 +162,66 @@ extern int setitimer (__itimer_which_t __which,
 extern int utimes (const char *__file, const struct timeval __tvp[2])
      __THROW __nonnull ((1));
 
+#else
+# ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (getitimer, (__itimer_which_t __which,
+                                       struct itimerval *__value),
+                           __getitimer64);
+
+extern int __REDIRECT_NTH (setitimer, (__itimer_which_t __which,
+                                       const struct itimerval *__restrict __new,
+                                       struct itimerval *__restrict __old),
+                           __setitimer64);
+
+extern int __REDIRECT_NTH (utimes, (const char *__file,
+                                    const struct timeval __tvp[2]),
+                           __utimes64) __nonnull ((1));
+# else
+#  define getitimer __getitimer64
+#  define setitimer __setitimer64
+#  define utimes __utimes64
+# endif
+#endif
+
 #ifdef __USE_MISC
+# ifndef __USE_TIME_BITS64
 /* Same as `utimes', but does not follow symbolic links.  */
 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.  */
 extern int futimes (int __fd, const struct timeval __tvp[2]) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (lutimes, (const char *__file,
+                                     const struct timeval __tvp[2]),
+                           __lutimes64) __nonnull ((1));
+
+extern int __REDIRECT_NTH (futimes, (int __fd, const struct timeval __tvp[2]),
+                           __futimes64);
+#  else
+#   define lutimes __lutimes64
+#   define futimes __futimes64
+#  endif
+# endif
 #endif
 
 #ifdef __USE_GNU
+# ifndef __USE_TIME_BITS64
 /* Change the access time of FILE relative to FD to TVP[0] and the
    modification time of FILE to TVP[1].  If TVP is a null pointer, use
    the current time instead.  Returns 0 on success, -1 on errors.  */
 extern int futimesat (int __fd, const char *__file,
 		      const struct timeval __tvp[2]) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (futimesat, (int __fd, const char *__file,
+                                       const struct timeval __tvp[2]),
+                           __futimesat64);
+#  else
+#   define futimesat __futimesat64
+#  endif
+# endif
 #endif
 
 
diff --git a/time/time.h b/time/time.h
index e255db9772..bde870c934 100644
--- a/time/time.h
+++ b/time/time.h
@@ -71,6 +71,7 @@ __BEGIN_DECLS
    The result / CLOCKS_PER_SEC is program time in seconds.  */
 extern clock_t clock (void) __THROW;
 
+#ifndef __USE_TIME_BITS64
 /* Return the current time and put it in *TIMER if TIMER is not NULL.  */
 extern time_t time (time_t *__timer) __THROW;
 
@@ -80,7 +81,18 @@ extern double difftime (time_t __time1, time_t __time0)
 
 /* Return the `time_t' representation of TP and normalize TP.  */
 extern time_t mktime (struct tm *__tp) __THROW;
-
+#else
+# ifdef __REDIRECT_NTH
+extern time_t __REDIRECT_NTH (time, (time_t *__timer), __time64);
+extern double __REDIRECT_NTH (difftime, (time_t __time1, time_t __time0),
+                              __difftime64) __attribute__ ((__const__));
+extern time_t __REDIRECT_NTH (mktime, (struct tm *__tp), __mktime64);
+# else
+#  define time __time64
+#  define difftime __difftime64
+#  define mktime __mktime64
+# endif
+#endif
 
 /* Format TP into S according to FORMAT.
    Write no more than MAXSIZE characters and return the number
@@ -114,6 +126,7 @@ extern char *strptime_l (const char *__restrict __s,
 #endif
 
 
+#ifndef __USE_TIME_BITS64
 /* Return the `struct tm' representation of *TIMER
    in Universal Coordinated Time (aka Greenwich Mean Time).  */
 extern struct tm *gmtime (const time_t *__timer) __THROW;
@@ -122,7 +135,20 @@ extern struct tm *gmtime (const time_t *__timer) __THROW;
    of *TIMER in the local timezone.  */
 extern struct tm *localtime (const time_t *__timer) __THROW;
 
+#else
+# ifdef __REDIRECT_NTH
+extern struct tm*__REDIRECT_NTH (gmtime, (const time_t *__timer), __gmtime64);
+extern struct tm *__REDIRECT_NTH (localtime, (const time_t *__timer),
+				  __localtime64);
+# else
+#  define gmtime __gmtime64
+#  define localtime __localtime64
+# endif
+#endif
+
+
 #if defined __USE_POSIX || __GLIBC_USE (ISOC2X)
+# ifndef __USE_TIME_BITS64
 /* Return the `struct tm' representation of *TIMER in UTC,
    using *TP to store the result.  */
 extern struct tm *gmtime_r (const time_t *__restrict __timer,
@@ -132,6 +158,20 @@ extern struct tm *gmtime_r (const time_t *__restrict __timer,
    using *TP to store the result.  */
 extern struct tm *localtime_r (const time_t *__restrict __timer,
 			       struct tm *__restrict __tp) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern struct tm*__REDIRECT_NTH (gmtime_r, (const time_t *__restrict __timer,
+                                            struct tm *__restrict __tp),
+                                 __gmtime64_r);
+
+extern struct tm*__REDIRECT_NTH (localtime_r, (const time_t *__restrict __t,
+                                               struct tm *__restrict __tp),
+                                 __localtime64_r);
+#  else
+#   define gmtime_r __gmtime64_r
+#   define localtime_r __localtime_r
+#  endif
+# endif
 #endif	/* POSIX || C2X */
 
 /* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n"
@@ -139,7 +179,15 @@ extern struct tm *localtime_r (const time_t *__restrict __timer,
 extern char *asctime (const struct tm *__tp) __THROW;
 
 /* Equivalent to `asctime (localtime (timer))'.  */
+#ifndef __USE_TIME_BITS64
 extern char *ctime (const time_t *__timer) __THROW;
+#else
+# ifdef __REDIRECT_NTH
+extern char *__REDIRECT_NTH (ctime, (const time_t *__timer), __ctime64);
+# else
+#  define ctime __ctime64
+# endif
+#endif
 
 #ifdef __USE_POSIX
 /* Reentrant versions of the above functions.  */
@@ -150,8 +198,18 @@ extern char *asctime_r (const struct tm *__restrict __tp,
 			char *__restrict __buf) __THROW;
 
 /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'.  */
+#ifndef __USE_TIME_BITS64
 extern char *ctime_r (const time_t *__restrict __timer,
 		      char *__restrict __buf) __THROW;
+#else
+# ifdef __REDIRECT_NTH
+extern char *__REDIRECT_NTH (ctime_r, (const time_t *__restrict __timer,
+                                       char *__restrict __buf), __ctime64_r);
+# else
+#  define ctime_r __ctime64_r
+# endif
+#endif
+
 #endif	/* POSIX */
 
 
@@ -186,11 +244,19 @@ extern long int timezone;
 /* Miscellaneous functions many Unices inherited from the public domain
    localtime package.  These are included only for compatibility.  */
 
+#ifndef __USE_TIME_BITS64
 /* Like `mktime', but for TP represents Universal Time, not local time.  */
 extern time_t timegm (struct tm *__tp) __THROW;
-
 /* Another name for `mktime'.  */
 extern time_t timelocal (struct tm *__tp) __THROW;
+#else
+# ifdef __REDIRECT_NTH
+extern time_t __REDIRECT_NTH (timegm, (struct tm *__tp), __timegm64);
+extern time_t __REDIRECT_NTH (timelocal, (struct tm *__tp), __mktime64);
+# else
+#  define timegm __timegm64
+# endif
+#endif
 
 /* Return the number of days in YEAR.  */
 extern int dysize (int __year) __THROW  __attribute__ ((__const__));
@@ -198,6 +264,7 @@ extern int dysize (int __year) __THROW  __attribute__ ((__const__));
 
 
 #ifdef __USE_POSIX199309
+# ifndef __USE_TIME_BITS64
 /* Pause execution for a number of nanoseconds.
 
    This function is a cancellation point and therefore not marked with
@@ -205,7 +272,6 @@ extern int dysize (int __year) __THROW  __attribute__ ((__const__));
 extern int nanosleep (const struct timespec *__requested_time,
 		      struct timespec *__remaining);
 
-
 /* Get resolution of clock CLOCK_ID.  */
 extern int clock_getres (clockid_t __clock_id, struct timespec *__res) __THROW;
 
@@ -215,15 +281,46 @@ extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
 /* Set clock CLOCK_ID to value TP.  */
 extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp)
      __THROW;
+# else
+#  ifdef __REDIRECT
+extern int __REDIRECT (nanosleep, (const struct timespec *__requested_time,
+                                   struct timespec *__remaining),
+                       __nanosleep64);
+extern int __REDIRECT_NTH (clock_getres, (clockid_t __clock_id,
+                                          struct timespec *__res),
+                           __clock_getres64);
+extern int __REDIRECT_NTH (clock_gettime, (clockid_t __clock_id, struct
+                                           timespec *__tp), __clock_gettime64);
+extern int __REDIRECT_NTH (clock_settime, (clockid_t __clock_id, const struct
+                                           timespec *__tp), __clock_settime64);
+#  else
+#   define nanosleep __nanosleep64
+#   define clock_getres __clock_getres64
+#   define clock_gettime __clock_gettime64
+#   define clock_settime __clock_settime64
+#  endif
+# endif
+
 
 # ifdef __USE_XOPEN2K
 /* High-resolution sleep with the specified clock.
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
+#  ifndef __USE_TIME_BITS64
 extern int clock_nanosleep (clockid_t __clock_id, int __flags,
 			    const struct timespec *__req,
 			    struct timespec *__rem);
+#  else
+#   ifdef __REDIRECT
+extern int __REDIRECT (clock_nanosleep, (clockid_t __clock_id, int __flags,
+                                         const struct timespec *__req,
+                                         struct timespec *__rem),
+                       __clock_nanosleep_time64);
+#   else
+#    define clock_nanosleep __clock_nanosleep_time64
+#   endif
+#  endif
 
 /* Return clock ID for CPU-time clock.  */
 extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) __THROW;
@@ -239,6 +336,7 @@ 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.  */
+# ifndef __USE_TIME_BITS64
 extern int timer_settime (timer_t __timerid, int __flags,
 			  const struct itimerspec *__restrict __value,
 			  struct itimerspec *__restrict __ovalue) __THROW;
@@ -246,6 +344,21 @@ extern int timer_settime (timer_t __timerid, int __flags,
 /* Get current value of timer TIMERID and store it in VALUE.  */
 extern int timer_gettime (timer_t __timerid, struct itimerspec *__value)
      __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (timer_settime, (timer_t __timerid, int __flags,
+     const struct itimerspec *__restrict __value,
+     struct itimerspec *__restrict __ovalue),
+                          __timer_settime64);
+
+extern int __REDIRECT_NTH (timer_gettime, (timer_t __timerid,
+                                           struct itimerspec *__value),
+                           __timer_gettime64);
+#  else
+#   define timer_settime __timer_settime64
+#   define timer_gettime __timer_gettime64
+#  endif
+# endif
 
 /* Get expiration overrun for timer TIMERID.  */
 extern int timer_getoverrun (timer_t __timerid) __THROW;
@@ -253,16 +366,35 @@ extern int timer_getoverrun (timer_t __timerid) __THROW;
 
 
 #ifdef __USE_ISOC11
+# ifndef __USE_TIME_BITS64
 /* Set TS to calendar time based in time base BASE.  */
 extern int timespec_get (struct timespec *__ts, int __base)
      __THROW __nonnull ((1));
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (timespec_get, (struct timespec *__ts, int __base),
+                           __timespec_get64) __nonnull ((1));
+#  else
+#   define timespec_get __timespec_get64
+#  endif
+# endif
 #endif
 
 
 #if __GLIBC_USE (ISOC2X)
+# ifndef __USE_TIME_BITS64
 /* Set TS to resolution of time base BASE.  */
 extern int timespec_getres (struct timespec *__ts, int __base)
      __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (timespec_getres, (struct timespec *__ts,
+                                             int __base),
+                           __timespec_getres64);
+#  else
+#   define timespec_getres __timespec_getres64
+#  endif
+# endif
 #endif