@@ -491,6 +491,12 @@ for linking")
int foo = INITIAL_FOO_VALUE;
libc_hidden_data_weak (foo)
+ If the internal foo should use a different internal symbol (for instance
+ if the symbol is exported as an IFUNC, but internal calls should use a
+ default version) then you may use:
+
+ libc_hidden_def_redir (foo_internal, foo)
+
If foo is normally just an alias (strong or weak) to some other function,
you should use the normal strong_alias first, then add libc_hidden_def
or libc_hidden_weak:
@@ -548,6 +554,7 @@ for linking")
# define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name);
# define hidden_data_ver(local, name) hidden_ver(local, name)
# define hidden_def(name) __hidden_ver1(__GI_##name, name, name);
+# define hidden_def_redir(redir, name) __hidden_ver1(redir, __GI_##name, redir);
# define hidden_data_def(name) hidden_def(name)
# define hidden_tls_def(name) \
__hidden_ver2 (__thread, __GI_##name, name, name);
@@ -575,6 +582,7 @@ for linking")
hidden_proto doesn't make sense for assembly but the equivalent
is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */
# define hidden_def(name) strong_alias (name, __GI_##name)
+# define hidden_def_redir(redir, name) strong_alias(redir, __GI_##name);
# define hidden_weak(name) hidden_def (name)
# define hidden_ver(local, name) strong_alias (local, __GI_##name)
# define hidden_data_def(name) strong_data_alias (name, __GI_##name)
@@ -605,6 +613,7 @@ for linking")
# endif /* Not __ASSEMBLER__ */
# define hidden_weak(name)
# define hidden_def(name)
+# define hidden_def_redir(redir, name)
# define hidden_ver(local, name)
# define hidden_data_weak(name)
# define hidden_data_def(name)
@@ -617,6 +626,7 @@ for linking")
# define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)
# define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs)
# define libc_hidden_def(name) hidden_def (name)
+# define libc_hidden_def_redir(redir, name) hidden_def_redir (redir, name)
# define libc_hidden_weak(name) hidden_weak (name)
# ifdef LINK_OBSOLETE_RPC
/* libc_hidden_nolink_sunrpc should only get used in sunrpc code. */
@@ -633,6 +643,7 @@ for linking")
# define libc_hidden_proto(name, attrs...)
# define libc_hidden_tls_proto(name, attrs...)
# define libc_hidden_def(name)
+# define libc_hidden_def_redir(redir, name)
# define libc_hidden_weak(name)
# define libc_hidden_ver(local, name)
# define libc_hidden_data_def(name)
@@ -315,6 +315,8 @@ struct libc_do_syscall_args
/* List of system calls which are supported as vsyscalls. */
# define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime"
# define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
+# define HAVE_TIME_VSYSCALL "__vdso_time"
+# define USE_TIME_VSYSCALL_IFUNC 1
/* Define a macro which expands inline into the wrapper code for a system
call. This use is for internal calls that do not need to handle errors
deleted file mode 100644
@@ -1,34 +0,0 @@
-/* time -- Get number of seconds since Epoch. Linux/i386 version.
- 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
- <http://www.gnu.org/licenses/>. */
-
-#ifdef SHARED
-# define time __redirect_time
-#endif
-
-#include <time.h>
-
-#ifdef SHARED
-# undef time
-# define time_type __redirect_time
-
-# undef libc_hidden_def
-# define libc_hidden_def(name) \
- __hidden_ver1 (__time_syscall, __GI_time, __time_syscall);
-#endif
-
-#include <sysdeps/unix/sysv/linux/x86/time.c>
@@ -24,6 +24,7 @@
#define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
#define HAVE_GETCPU_VSYSCALL "__kernel_getcpu"
#define HAVE_TIME_VSYSCALL "__kernel_time"
+#define USE_TIME_VSYSCALL_IFUNC 1
#define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday"
#define HAVE_GET_TBFREQ "__kernel_get_tbfreq"
deleted file mode 100644
@@ -1,83 +0,0 @@
-/* time system call for Linux/PowerPC.
- Copyright (C) 2013-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
- <http://www.gnu.org/licenses/>. */
-
-#ifdef SHARED
-# ifndef __powerpc64__
-# define time __redirect_time
-# else
-# define __redirect_time time
-# endif
-
-# include <time.h>
-# include <sysdep.h>
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-# include <dl-machine.h>
-
-# ifndef __powerpc64__
-# undef time
-
-time_t
-__time_vsyscall (time_t *t)
-{
- return INLINE_VSYSCALL (time, 1, t);
-}
-
-/* __GI_time 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 (__time_vsyscall, __GI_time, __time_vsyscall);
-
-# endif /* !__powerpc64__ */
-
-static time_t
-time_syscall (time_t *t)
-{
- struct timeval tv;
- time_t result;
-
- if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0)
- result = (time_t) -1;
- else
- result = (time_t) tv.tv_sec;
-
- if (t != NULL)
- *t = result;
- return result;
-}
-
-# define INIT_ARCH() \
- void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL);
-
-/* If the vDSO is not available we fall back to the syscall. */
-libc_ifunc_hidden (__redirect_time, time,
- vdso_time
- ? VDSO_IFUNC_RET (vdso_time)
- : (void *) time_syscall);
-libc_hidden_def (time)
-
-#else
-
-#include <sysdeps/posix/time.c>
-
-#endif /* !SHARED */
@@ -15,27 +15,68 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <stddef.h>
+/* Currently we have 3 possible time implementations, which is also selected
+ in the order:
+
+ 1. Wire-up __NR_time with a vDSO implementation (currently only x86 and
+ powerpc).
+ 2. Only wire-up __NR_time (usually old kABIs).
+ 3. Using internal gettimeofday (which may call a vDSO as well). */
+
+#define time __redirect_time
#include <time.h>
+#undef time
+#include <sys/time.h>
#include <sysdep.h>
+#ifdef HAVE_TIME_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
+#include <libc-vdso.h>
-#ifdef __NR_time
-
-time_t
-time (time_t *t)
+static time_t
+time_syscall (time_t *t)
{
+ time_t res;
+#ifdef __NR_time
INTERNAL_SYSCALL_DECL (err);
- time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
+ res = INTERNAL_VSYSCALL (time, err, 1, NULL);
/* There cannot be any error. */
+#else
+ struct timeval tv;
+ /* gettimeofday does not fail with valid 'tv' and null timezone. */
+ __gettimeofday (&tv, NULL);
+ res = tv.tv_sec;
+#endif
if (t != NULL)
*t = res;
return res;
}
-libc_hidden_def (time)
+#if HAVE_IFUNC && defined USE_TIME_VSYSCALL_IFUNC
+/* Route externals calls direct to vDSO and static and internal calls to
+ fallback implementation (which also might call the vDSO). */
+# ifdef SHARED
+# undef INIT_ARCH
+# define INIT_ARCH() \
+ void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL);
+
+libc_ifunc_redirected (__redirect_time, time,
+ vdso_time
+ ? VDSO_IFUNC_RET (vdso_time)
+ : (void *) time_syscall);
+libc_hidden_def_redir (time_syscall, time)
+# else
+strong_alias (time_syscall, time)
+# endif /* SHARED */
#else
-# include <sysdeps/posix/time.c>
+time_t
+time (time_t *t)
+{
+ return time_syscall (t);
+}
+libc_hidden_def_redir (time, time)
#endif
deleted file mode 100644
@@ -1,60 +0,0 @@
-/* time -- Get number of seconds since Epoch. Linux/x86 version.
- 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
- <http://www.gnu.org/licenses/>. */
-
-#include <time.h>
-
-#ifdef SHARED
-
-#include <dl-vdso.h>
-#include <errno.h>
-#include <sysdep-vdso.h>
-
-static time_t
-__time_syscall (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
-# ifndef time_type
-/* The i386 time.c includes this file with a defined time_type macro.
- For x86_64 we have to define it to time as the internal symbol is the
- ifunc'ed one. */
-# define time_type time
-# endif
-
-#undef INIT_ARCH
-#define INIT_ARCH()
-
-/* If the vDSO is not available we fall back on the syscall. */
-libc_ifunc_hidden (time_type, time,
- (get_vdso_symbol ("__vdso_time") ?: __time_syscall))
-libc_hidden_def (time)
-
-#else
-
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
-#endif
@@ -376,6 +376,8 @@
/* List of system calls which are supported as vsyscalls. */
# define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime"
# define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
+# define HAVE_TIME_VSYSCALL "__vdso_time"
+# define USE_TIME_VSYSCALL_IFUNC 1
# define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
# define SINGLE_THREAD_BY_GLOBAL 1