aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS13
-rw-r--r--include/sys/time.h2
-rw-r--r--sysdeps/mach/clock_gettime.c (renamed from sysdeps/unix/clock_gettime.c)37
-rw-r--r--sysdeps/mach/gettimeofday.c43
-rw-r--r--sysdeps/posix/gettimeofday.c67
-rw-r--r--sysdeps/unix/syscalls.list1
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/gettimeofday.c34
-rw-r--r--sysdeps/unix/sysv/linux/alpha/gettimeofday.c (renamed from sysdeps/unix/sysv/linux/i386/gettimeofday.c)25
-rw-r--r--sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c11
-rw-r--r--sysdeps/unix/sysv/linux/alpha/tv32-compat.h6
-rw-r--r--sysdeps/unix/sysv/linux/gettimeofday.c49
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/gettimeofday.c69
-rw-r--r--sysdeps/unix/sysv/linux/x86/gettimeofday.c43
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list1
-rw-r--r--time/gettimeofday.c32
16 files changed, 125 insertions, 309 deletions
diff --git a/NEWS b/NEWS
index 7e9d36e180..75b380c0f8 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,19 @@ Major new features:
18661-1:2014 and TS 18661-3:2015 as amended by the resolution of
Clarification Request 13 to TS 18661-3.
+* The gettimeofday function will no longer report information about a
+ system-wide time zone, expect for aarch64, powerpc, and x86 on Linux
+ which still uses the vDSO symbol (when available).
+
+ This 4.2-BSD-era feature has been deprecated for many years, as it cannot
+ handle the full complexity of the world's timezones, but hitherto we have
+ supported it on a best-effort basis. Changes required to support 64-bit
+ time_t on 32-bit architectures have made this no longer practical.
+
+ As of this release, callers of gettimeofday with a non-null 'tzp' argument
+ will always receive a 'struct timezone' whose tz_minuteswest and
+ tz_dsttime fields are zero.
+
Deprecated and removed features, and other changes affecting compatibility:
* The totalorder and totalordermag functions, and the corresponding
diff --git a/include/sys/time.h b/include/sys/time.h
index c0e30e70fb..2bf4297e76 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -22,8 +22,6 @@
# ifndef _ISOMAC
extern int __gettimeofday (struct timeval *__tv,
struct timezone *__tz);
-libc_hidden_proto (__gettimeofday)
-libc_hidden_proto (gettimeofday)
extern int __settimezone (const struct timezone *__tz)
attribute_hidden;
extern int __adjtime (const struct timeval *__delta,
diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/mach/clock_gettime.c
index aa74e11703..0f872e5a45 100644
--- a/sysdeps/unix/clock_gettime.c
+++ b/sysdeps/mach/clock_gettime.c
@@ -1,5 +1,4 @@
-/* clock_gettime -- Get the current time from a POSIX clockid_t. Unix version.
- Copyright (C) 1999-2019 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2019 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
@@ -18,32 +17,28 @@
#include <errno.h>
#include <time.h>
-#include <sys/time.h>
+#include <mach.h>
#include <shlib-compat.h>
-/* Get current value of CLOCK and store it in TP. */
+/* Get the current time of day, putting it into *TS.
+ Returns 0 on success, -1 on errors. */
int
-__clock_gettime (clockid_t clock_id, struct timespec *tp)
+__clock_gettime (clockid_t clock_id, struct timespec *ts)
{
- int retval = -1;
-
- switch (clock_id)
+ if (clock_id != CLOCK_REALTIME)
{
- case CLOCK_REALTIME:
- {
- struct timeval tv;
- retval = __gettimeofday (&tv, NULL);
- if (retval == 0)
- TIMEVAL_TO_TIMESPEC (&tv, tp);
- }
- break;
-
- default:
- __set_errno (EINVAL);
- break;
+ errno = EINVAL;
+ return -1;
}
- return retval;
+ /* __host_get_time can only fail if passed an invalid host_t.
+ __mach_host_self could theoretically fail (producing an
+ invalid host_t) due to resource exhaustion, but we assume
+ this will never happen. */
+ time_value_t tv;
+ __host_get_time (__mach_host_self (), &tv);
+ TIME_VALUE_TO_TIMESPEC (&tv, ts);
+ return 0;
}
libc_hidden_def (__clock_gettime)
diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c
deleted file mode 100644
index f6df00306b..0000000000
--- a/sysdeps/mach/gettimeofday.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <stddef.h>
-#include <sys/time.h>
-#include <mach.h>
-
-/* 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
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- kern_return_t err;
-
- if (tz != NULL)
- *tz = (struct timezone){0, 0}; /* XXX */
-
- if (err = __host_get_time (__mach_host_self (), (time_value_t *) tv))
- {
- errno = err;
- return -1;
- }
- return 0;
-}
-libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c
deleted file mode 100644
index 6bb98cd018..0000000000
--- a/sysdeps/posix/gettimeofday.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <time.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.
- Returns 0 on success, -1 on errors. */
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- if (tv == NULL)
- {
- __set_errno (EINVAL);
- return -1;
- }
-
- tv->tv_sec = (long int) time ((time_t *) NULL);
- tv->tv_usec = 0L;
-
- if (tz != NULL)
- {
- const time_t timer = tv->tv_sec;
- struct tm tm;
- const struct tm *tmp;
-
- const long int save_timezone = __timezone;
- const long int save_daylight = __daylight;
- char *save_tzname[2];
- save_tzname[0] = __tzname[0];
- save_tzname[1] = __tzname[1];
-
- tmp = localtime_r (&timer, &tm);
-
- tz->tz_minuteswest = __timezone / 60;
- tz->tz_dsttime = __daylight;
-
- __timezone = save_timezone;
- __daylight = save_daylight;
- __tzname[0] = save_tzname[0];
- __tzname[1] = save_tzname[1];
-
- if (tmp == NULL)
- return -1;
- }
-
- return 0;
-}
-libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
index 5fedd5733d..e28e801c7a 100644
--- a/sysdeps/unix/syscalls.list
+++ b/sysdeps/unix/syscalls.list
@@ -33,7 +33,6 @@ getrlimit - getrlimit i:ip __getrlimit getrlimit
getrusage - getrusage i:ip __getrusage getrusage
getsockname - getsockname i:ibN __getsockname getsockname
getsockopt - getsockopt i:iiiBN getsockopt
-gettimeofday - gettimeofday i:pP __gettimeofday gettimeofday
getuid - getuid Ei: __getuid getuid
ioctl - ioctl i:iiI __ioctl ioctl
kill - kill i:ii __kill kill
diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
index 4ff74fa285..075af3d0d3 100644
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
@@ -20,39 +20,39 @@
putting it into *tv and *tz. If tz is null, *tz is not filled.
Returns 0 on success, -1 on errors. */
-#include <sys/time.h>
+#include <time.h>
+#include <sysdep.h>
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <sysdep-vdso.h>
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
/* Used as a fallback in the ifunc resolver if VDSO is not available
and for libc.so internal __gettimeofday calls. */
-
static int
__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
{
+ if (__glibc_unlikely (tz != 0))
+ memset (tz, 0, sizeof *tz);
+
return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
}
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <sysdep-vdso.h>
+
# define INIT_ARCH()
-libc_ifunc_hidden (__gettimeofday, __gettimeofday,
- (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
- ?: __gettimeofday_vsyscall))
-libc_hidden_def (__gettimeofday)
+libc_ifunc (__gettimeofday,
+ (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+ ?: __gettimeofday_vsyscall))
#else
-
-# include <sysdep.h>
int
__gettimeofday (struct timeval *tv, struct timezone *tz)
{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+ return __gettimeofday_vsyscall (tv, tz);
}
-libc_hidden_def (__gettimeofday)
-
#endif
-
weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/gettimeofday.c
index f6faecb21e..262a3c2352 100644
--- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/gettimeofday.c
@@ -1,5 +1,5 @@
-/* gettimeofday - get the time. Linux/i386 version.
- Copyright (C) 2015-2019 Free Software Foundation, Inc.
+/* gettimeofday -- Get the current time of day. Linux/Alpha/tv64 version.
+ Copyright (C) 2019 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,20 +16,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#ifdef SHARED
-# define __gettimeofday __redirect___gettimeofday
-#endif
-
-#include <sys/time.h>
-
-#ifdef SHARED
-# undef __gettimeofday
-# define __gettimeofday_type __redirect___gettimeofday
-
-# undef libc_hidden_def
-# define libc_hidden_def(name) \
- __hidden_ver1 (__gettimeofday_syscall, __GI___gettimeofday, \
- __gettimeofday_syscall);
-#endif
-
-#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
+/* We can use the generic implementation, but we have to override its
+ default symbol version. */
+#define VERSION_gettimeofday GLIBC_2.1
+#include <time/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
index 59fc614523..4698c8a5db 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
@@ -20,6 +20,8 @@
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+#include <string.h>
+#include <time.h>
#include <sys/time.h>
#include <tv32-compat.h>
@@ -30,10 +32,13 @@ int
attribute_compat_text_section
__gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
{
- struct timeval tv;
- __gettimeofday (&tv, tz);
+ if (__glibc_unlikely (tz != 0))
+ memset (tz, 0, sizeof (struct timezone));
- *tv32 = valid_timeval64_to_timeval (tv);
+ struct timespec ts;
+ __clock_gettime (CLOCK_REALTIME, &ts);
+
+ *tv32 = valid_timespec_to_timeval32 (ts);
return 0;
}
diff --git a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
index 5f86e66e08..0fbf284bb5 100644
--- a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
+++ b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
@@ -89,6 +89,12 @@ valid_timeval32_to_timespec (const struct timeval32 tv)
return (struct timespec) { tv.tv_sec, tv.tv_usec * 1000 };
}
+static inline struct timeval32
+valid_timespec_to_timeval32 (const struct timespec ts)
+{
+ return (struct timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
+}
+
static inline void
rusage64_to_rusage32 (struct rusage32 *restrict r32,
const struct rusage *restrict r64)
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
deleted file mode 100644
index c9597d6405..0000000000
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
-
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <sys/time.h>
-
-#undef __gettimeofday
-
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
-#include <sysdep-vdso.h>
-
-/* 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
-___gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-#ifdef VERSION_gettimeofday
-weak_alias (___gettimeofday, __wgettimeofday);
-default_symbol_version (___gettimeofday, __gettimeofday, VERSION_gettimeofday);
-default_symbol_version (__wgettimeofday, gettimeofday, VERSION_gettimeofday);
-libc_hidden_ver (___gettimeofday, __gettimeofday);
-libc_hidden_ver (___gettimeofday, gettimeofday);
-#else
-strong_alias (___gettimeofday, __gettimeofday)
-weak_alias (___gettimeofday, gettimeofday)
-libc_hidden_def (__gettimeofday)
-libc_hidden_weak (gettimeofday)
-#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 13a1fd292a..02486dee3a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,71 +15,40 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#if defined SHARED && !defined __powerpc64__
-# define __gettimeofday __redirect___gettimeofday
-#else
-# define __redirect___gettimeofday __gettimeofday
-#endif
-
-#include <sys/time.h>
-
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-# include <dl-machine.h>
-# include <sysdep.h>
-
-# ifndef __powerpc64__
-# undef __gettimeofday
-
-int
-__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
- compiler make a local call (symbol@local) for internal GLIBC usage. It
- means the PLT won't be used and the ifunc resolver will be called directly.
- For ppc64 a call to a function in another translation unit might use a
- different toc pointer thus disallowing direct branchess and making internal
- ifuncs calls safe. */
-# undef libc_hidden_def
-# define libc_hidden_def(name) \
- __hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday, \
- __gettimeofday_vsyscall);
+#include <time.h>
+#include <sysdep.h>
-# endif /* !__powerpc64__ */
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
static int
__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+ if (__glibc_unlikely (tz != 0))
+ memset (tz, 0, sizeof *tz);
+
+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
}
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
# define INIT_ARCH() \
void *vdso_gettimeofday = get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
/* If the vDSO is not available we fall back syscall. */
-libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
- vdso_gettimeofday
- ? VDSO_IFUNC_RET (vdso_gettimeofday)
- : (void *) __gettimeofday_syscall);
-libc_hidden_def (__gettimeofday)
-
+libc_ifunc (__gettimeofday,
+ vdso_gettimeofday
+ ? VDSO_IFUNC_RET (vdso_gettimeofday)
+ : (void *) __gettimeofday_syscall);
#else
-
-# include <sysdep.h>
-# include <errno.h>
-
int
__gettimeofday (struct timeval *tv, struct timezone *tz)
{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+ return __gettimeofday_syscall (tv, tz);
}
-libc_hidden_def (__gettimeofday)
-
#endif
weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index 2d9248ee26..cb20e358d8 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -16,47 +16,38 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <sys/time.h>
+#include <time.h>
+#include <sysdep.h>
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <errno.h>
-# include <sysdep-vdso.h>
-# include <sysdep-vdso.h>
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
static int
__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+ if (__glibc_unlikely (tz != 0))
+ memset (tz, 0, sizeof *tz);
+
+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
}
-# ifndef __gettimeofday_type
-/* The i386 gettimeofday.c includes this file with a defined
- __gettimeofday_type macro. For x86_64 we have to define it to __gettimeofday
- as the internal symbol is the ifunc'ed one. */
-# define __gettimeofday_type __gettimeofday
-# endif
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
# define INIT_ARCH()
/* If the vDSO is not available we fall back to syscall. */
-libc_ifunc_hidden (__gettimeofday_type, __gettimeofday,
- (get_vdso_symbol ("__vdso_gettimeofday")
- ?: __gettimeofday_syscall));
-libc_hidden_def (__gettimeofday)
+libc_ifunc (__gettimeofday,
+ (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+ ?: __gettimeofday_syscall));
#else
-
-# include <sysdep.h>
-# include <errno.h>
-
int
__gettimeofday (struct timeval *tv, struct timezone *tz)
{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+ return __gettimeofday_syscall (tv, tz);
}
-libc_hidden_def (__gettimeofday)
-
#endif
weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
new file mode 100644
index 0000000000..cd342f33ad
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
index b44f6f99e9..786c884232 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
@@ -1,6 +1,5 @@
# File name Caller Syscall name # args Strong name Weak names
-gettimeofday - gettimeofday:__vdso_gettimeofday@LINUX_2.6 i:pP __gettimeofday gettimeofday
personality EXTRA personality Ei:i __personality personality
posix_fadvise64 - fadvise64 Vi:iiii posix_fadvise posix_fadvise64
time - time:__vdso_time@LINUX_2.6 Ei:P time
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index 1fd2669abd..e8055b397d 100644
--- a/time/gettimeofday.c
+++ b/time/gettimeofday.c
@@ -15,20 +15,32 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <errno.h>
+#include <string.h>
+#include <time.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.
+/* Get the current time of day, putting it into *TV.
+ If *TZ is not NULL, clear it.
Returns 0 on success, -1 on errors. */
int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
+___gettimeofday (struct timeval *tv, struct timezone *tz)
{
- __set_errno (ENOSYS);
- return -1;
+ if (__glibc_unlikely (tz != 0))
+ memset (tz, 0, sizeof *tz);
+
+ struct timespec ts;
+ if (__clock_gettime (CLOCK_REALTIME, &ts))
+ return -1;
+
+ TIMESPEC_TO_TIMEVAL (tv, &ts);
+ return 0;
}
-libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
-stub_warning (gettimeofday)
+#ifdef VERSION_gettimeofday
+weak_alias (___gettimeofday, __wgettimeofday);
+default_symbol_version (___gettimeofday, __gettimeofday, VERSION_gettimeofday);
+default_symbol_version (__wgettimeofday, gettimeofday, VERSION_gettimeofday);
+#else
+strong_alias (___gettimeofday, __gettimeofday)
+weak_alias (___gettimeofday, gettimeofday)
+#endif