public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc] y2038: linux: Provide __gettimeofday64 implementation
@ 2020-02-18 22:57 Lukasz Majewski
  0 siblings, 0 replies; only message in thread
From: Lukasz Majewski @ 2020-02-18 22:57 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=7455b700279ec8baccf8dd7b119648f8b3e34eec

commit 7455b700279ec8baccf8dd7b119648f8b3e34eec
Author: Lukasz Majewski <lukma@denx.de>
Date:   Mon Jan 27 15:37:07 2020 +0100

    y2038: linux: Provide __gettimeofday64 implementation
    
    In the glibc the gettimeofday can use vDSO (on power and x86 the
    USE_IFUNC_GETTIMEOFDAY is defined), gettimeofday syscall or 'default'
    ___gettimeofday() from ./time/gettime.c (as a fallback).
    
    In this patch the last function (___gettimeofday) has been refactored and
    moved to ./sysdeps/unix/sysv/linux/gettimeofday.c to be Linux specific.
    
    The new __gettimeofday64 explicit 64 bit function for getting 64 bit time from
    the kernel (by internally calling __clock_gettime64) has been introduced.
    
    Moreover, a 32 bit version - __gettimeofday has been refactored to internally
    use __gettimeofday64.
    
    The __gettimeofday is now supposed to be used on systems still supporting 32
    bit time (__TIMESIZE != 64) - hence the necessary check for time_t potential
    overflow and conversion of struct __timeval64 to 32 bit struct timespec.
    
    The iFUNC vDSO direct call optimization has been removed from both i686 and
    powerpc32 (USE_IFUNC_GETTIMEOFDAY is not defined for those architectures
    anymore). The Linux kernel does not provide a y2038 safe implementation of
    gettimeofday neither it plans to provide it in the future, clock_gettime64
    should be used instead. Keeping support for this optimization would require
    to handle another build permutation (!__ASSUME_TIME64_SYSCALLS &&
    USE_IFUNC_GETTIMEOFDAY) which adds more complexity and has limited use
    (since the idea is to eventually have a y2038 safe glibc build).
    
    Build tests:
    ./src/scripts/build-many-glibcs.py glibcs
    
    Run-time tests:
    - Run specific tests on ARM/x86 32bit systems (qemu):
      https://github.com/lmajewski/meta-y2038 and run tests:
      https://github.com/lmajewski/y2038-tests/commits/master
    
    Above tests were performed with Y2038 redirection applied as well as without
    to test proper usage of both __gettimeofday64 and __gettimeofday.
    
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
    [Including some commit message improvement]

Diff:
---
 include/time.h                                 |  4 +++
 sysdeps/unix/sysv/linux/gettimeofday.c         | 40 +++++++++++++++++++++++++-
 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c |  4 ++-
 sysdeps/unix/sysv/linux/x86/gettimeofday.c     |  4 ++-
 4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/include/time.h b/include/time.h
index 73f6627..6180665 100644
--- a/include/time.h
+++ b/include/time.h
@@ -227,10 +227,14 @@ libc_hidden_proto (__sched_rr_get_interval64);
 
 #if __TIMESIZE == 64
 # define __settimeofday64 __settimeofday
+# define __gettimeofday64 __gettimeofday
 #else
 extern int __settimeofday64 (const struct __timeval64 *tv,
                              const struct timezone *tz);
 libc_hidden_proto (__settimeofday64)
+extern int __gettimeofday64 (struct __timeval64 *restrict tv,
+                             void *restrict tz);
+libc_hidden_proto (__gettimeofday64)
 #endif
 
 /* Compute the `struct tm' representation of T,
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
index d5cdb22..cb57bc9 100644
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -54,5 +54,43 @@ __gettimeofday (struct timeval *restrict tv, void *restrict tz)
 # endif
 weak_alias (__gettimeofday, gettimeofday)
 #else /* USE_IFUNC_GETTIMEOFDAY  */
-# include <time/gettimeofday.c>
+/* Conversion of gettimeofday function to support 64 bit time on archs
+   with __WORDSIZE == 32 and __TIMESIZE == 32/64  */
+#include <errno.h>
+
+int
+__gettimeofday64 (struct __timeval64 *restrict tv, void *restrict tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof (struct timezone));
+
+  struct __timespec64 ts64;
+  if (__clock_gettime64 (CLOCK_REALTIME, &ts64))
+	  return -1;
+
+  *tv = timespec64_to_timeval64 (ts64);
+  return 0;
+}
+
+# if __TIMESIZE != 64
+libc_hidden_def (__gettimeofday64)
+
+int
+__gettimeofday (struct timeval *restrict tv, void *restrict tz)
+{
+  struct __timeval64 tv64;
+  if (__gettimeofday64 (&tv64, tz))
+	  return -1;
+
+  if (! in_time_t_range (tv64.tv_sec))
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  *tv = valid_timeval64_to_timeval (tv64);
+  return 0;
+}
+# endif
+weak_alias (__gettimeofday, gettimeofday)
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 183fb0a..2d6978f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,5 +15,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define USE_IFUNC_GETTIMEOFDAY
+#ifdef __powerpc64__
+# define USE_IFUNC_GETTIMEOFDAY
+#endif
 #include <sysdeps/unix/sysv/linux/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index 1b7aa88..0c1779d 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -16,5 +16,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define USE_IFUNC_GETTIMEOFDAY
+#ifdef __x86_64__
+# define USE_IFUNC_GETTIMEOFDAY
+#endif
 #include <sysdeps/unix/sysv/linux/gettimeofday.c>


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-02-18 22:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-18 22:57 [glibc] y2038: linux: Provide __gettimeofday64 implementation Lukasz Majewski

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