Message ID | 20191025120832.27667-10-adhemerval.zanella@linaro.org |
---|---|
State | Accepted |
Commit | 5e46749c64d51f50f8511ed99c1266d7c13e182b |
Headers | show |
Series | Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions. | expand |
Hi Adhemerval, > Use clock_gettime to implement gettimeofday > > Changes from previous version: > > - Do not remove Linux arch-specific implementations. > > -- > > Consolidate generic gettimeofday implementation to use clock_gettime. > Linux ports that still provide gettimeofday through vDSO are not > changed. > > Remove sysdeps/unix/clock_gettime.c, which implemented clock_gettime > using gettimeofday; new OS ports must provide a real implementation of > clock_gettime. > > Rename sysdeps/mach/gettimeofday.c to sysdeps/mach/clock_gettime.c and > convert into an implementation of clock_gettime. It only supports > CLOCK_REALTIME; Mach does not appear to have any support for monotonic > clocks. It uses __host_get_time, which provides at best microsecond > resolution. Hurd is currently using sysdeps/posix/clock_getres.c for > clock_getres; its output for CLOCK_REALTIME is based on > sysconf (_SC_CLK_TCK), and I do not know whether that gives the > correct result. > > Unlike settimeofday, there are no known uses of gettimeofday's > vestigial "get time zone" feature that are not bugs. (The per-process > timezone support in localtime and friends is unrelated, and the > programs that set the kernel's offset between the hardware clock and > UTC do not need to read it back.) Therefore, this feature is dummied > out. Henceforth, if gettimeofday's "struct timezone" argument is not > NULL, it will write zeroes to both fields. Any program that is > actually looking at this data will thus think it is running in UTC, > which is probably more correct than whatever it was doing before. > > [__]gettimeofday no longer has any internal callers, so we can now > remove its internal prototype and PLT bypass aliases. The > __gettimeofday@GLIBC_2.0 export remains, in case it is used by any > third-party code. > > It also allows to simplify the arch-specific implementation on x86 and > powerpc to remove the hack to disable the internal route to non iFUNC > variant for internal symbol. > > This patch also fixes a missing optimization on aarch64, powerpc, and > x86 where the code used on static build do not use the vDSO. > > Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, > powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu. > > Co-authored-by: Zack Weinberg <zackw@panix.com> > --- > NEWS | 15 ++++ > include/sys/time.h | 2 - > sysdeps/{unix => mach}/clock_gettime.c | 37 +++++----- > sysdeps/mach/gettimeofday.c | 43 ------------ > sysdeps/posix/gettimeofday.c | 67 ------------------ > sysdeps/unix/syscalls.list | 1 - > .../unix/sysv/linux/aarch64/gettimeofday.c | 34 ++++----- > .../sysv/linux/{i386 => alpha}/gettimeofday.c | 25 ++----- > .../unix/sysv/linux/alpha/osf_gettimeofday.c | 11 ++- > sysdeps/unix/sysv/linux/gettimeofday.c | 49 ------------- > .../unix/sysv/linux/powerpc/gettimeofday.c | 69 > +++++-------------- sysdeps/unix/sysv/linux/x86/gettimeofday.c | > 43 +++++------- .../unix/sysv/linux/x86_64/x32/gettimeofday.c | 1 + > .../unix/sysv/linux/x86_64/x32/syscalls.list | 1 - > time/gettimeofday.c | 32 ++++++--- > 15 files changed, 121 insertions(+), 309 deletions(-) > rename sysdeps/{unix => mach}/clock_gettime.c (65%) > delete mode 100644 sysdeps/mach/gettimeofday.c > delete mode 100644 sysdeps/posix/gettimeofday.c > rename sysdeps/unix/sysv/linux/{i386 => alpha}/gettimeofday.c (58%) > delete mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c > create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c > > diff --git a/NEWS b/NEWS > index 6d109f84f0..12d6af2fc0 100644 > --- a/NEWS > +++ b/NEWS > @@ -21,6 +21,21 @@ 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. We have also arranged for call sites > that > + pass a non-null ‘tzp’ argument to gettimeofday to receive > compile-time > + warnings, if the compiler makes this possible. > + > 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 similarity index 65% > rename from sysdeps/unix/clock_gettime.c > rename to 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 similarity index 58% > rename from sysdeps/unix/sysv/linux/i386/gettimeofday.c > rename to 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 > e6cc522dd1..f602d8dcf9 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)); > > - tv64_to_tv32 (tv32, &tv); > + struct timespec ts; > + __clock_gettime (CLOCK_REALTIME, &ts); > + > + ts64_to_tv32 (tv32, &ts); IMHO, this shall be replaced with valid_* functions from include/time.h > return 0; > } > > 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 Reviewed-by: Lukasz Majewski <lukma@denx.de> Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Mon, 28 Oct 2019, Lukasz Majewski wrote: > > 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)); > > > > - tv64_to_tv32 (tv32, &tv); > > + struct timespec ts; > > + __clock_gettime (CLOCK_REALTIME, &ts); > > + > > + ts64_to_tv32 (tv32, &ts); > > IMHO, this shall be replaced with valid_* functions from include/time.h This is dealing with an alpha-specific timeval32 structure; I don't see how the functions in include/time.h are applicable. -- Joseph S. Myers joseph@codesourcery.com
Hi Joseph, > On Mon, 28 Oct 2019, Lukasz Majewski wrote: > > > > 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)); > > > > > > - tv64_to_tv32 (tv32, &tv); > > > + struct timespec ts; > > > + __clock_gettime (CLOCK_REALTIME, &ts); > > > + > > > + ts64_to_tv32 (tv32, &ts); > > > > IMHO, this shall be replaced with valid_* functions from > > include/time.h > > This is dealing with an alpha-specific timeval32 structure; Maybe I did not noticed it earlier. The tv32-compat.h defines [1]: struct timeval32 { int32_t tv_sec; int32_t tv_usec; }; and conversion functions - like ts64_to_tv32() are to handle this specific type. I do think that if struct timeval32 is alpha specific, then the conversion functions shall be kept. > I don't > see how the functions in include/time.h are applicable. > Ok. Note: [1] - https://patchwork.ozlabs.org/patch/1184084/ Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
diff --git a/NEWS b/NEWS index 6d109f84f0..12d6af2fc0 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,21 @@ 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. We have also arranged for call sites that + pass a non-null ‘tzp’ argument to gettimeofday to receive compile-time + warnings, if the compiler makes this possible. + 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 similarity index 65% rename from sysdeps/unix/clock_gettime.c rename to 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 similarity index 58% rename from sysdeps/unix/sysv/linux/i386/gettimeofday.c rename to 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 e6cc522dd1..f602d8dcf9 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)); - tv64_to_tv32 (tv32, &tv); + struct timespec ts; + __clock_gettime (CLOCK_REALTIME, &ts); + + ts64_to_tv32 (tv32, &ts); return 0; } 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