[PATCH v2 01/16] linux: Fix vDSO macros build with time64 interfaces

classic Classic list List threaded Threaded
47 messages Options
123
Reply | Threaded
Open this post in threaded view
|

[PATCH v2 01/16] linux: Fix vDSO macros build with time64 interfaces

Adhemerval Zanella-2
Changes from previous version:

  - Reinstate syscall fallback on INLINE_VSYSCALL, it simplifies
    when the macro is used multiple times (as for clock_gettime
    and clock_getres).

--

As indicated on libc-help [1] the ec138c67cb commit broke 32-bit
builds when configured with --enable-kernel=5.1 or higher.  The
scenario 10 from [2] might also occur in this configuration and
INLINE_VSYSCALL will try to use the vDSO symbol and
HAVE_CLOCK_GETTIME64_VSYSCALL does not set HAVE_VSYSCALL prior its
usage.

Also, there is no easy way to just enable the code to use one
vDSO sysmbo since the macro INLINE_VSYSCALL is redefined if
HAVE_VSYSCALL is set.

Instead of adding more pre-processor handling and making the code
even more convoluted, this patch removes the requirement of defining
HAVE_VSYSCALL before including sysdep-vdso.h to enable vDSO usage.

The INLINE_VSYSCALL is now expected to be issued inside a
HAVE_*_VSYSCALL check, since it will try to use the internal vDSO
pointers.

Both clock_getres and clock_gettime vDSO code for time64_t were
removed since there is no vDSO setup code for the symbol (an
architecture can not set HAVE_CLOCK_GETTIME64_VSYSCALL).

Checked on i686-linux-gnu (default and with --enable-kernel=5.1),
x86_64-linux-gnu, aarch64-linux-gnu, and powerpc64le-linux-gnu.
I also checked against a build to mips64-linux-gnu and
sparc64-linux-gnu.

[1] https://sourceware.org/ml/libc-help/2019-12/msg00014.html
---
 .../unix/sysv/linux/aarch64/gettimeofday.c    |  4 --
 sysdeps/unix/sysv/linux/clock_getres.c        | 36 +++++++++++-------
 sysdeps/unix/sysv/linux/clock_gettime.c       | 38 +++++++++++--------
 sysdeps/unix/sysv/linux/getcpu.c              |  9 +----
 .../unix/sysv/linux/powerpc/gettimeofday.c    |  4 --
 sysdeps/unix/sysv/linux/powerpc/time.c        |  4 --
 sysdeps/unix/sysv/linux/sched_getcpu.c        | 15 +++-----
 sysdeps/unix/sysv/linux/sysdep-vdso.h         | 34 +----------------
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    |  4 --
 sysdeps/unix/sysv/linux/x86/time.c            |  8 ++--
 10 files changed, 58 insertions(+), 98 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
index 7e772e05ce..143c5c1507 100644
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
@@ -22,10 +22,6 @@
 
 #include <time.h>
 #include <sysdep.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
diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 9497f78787..52671fa641 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -20,9 +20,6 @@
 #include <errno.h>
 #include <time.h>
 
-#ifdef HAVE_CLOCK_GETRES_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 #include <shlib-compat.h>
 #include <kernel-features.h>
@@ -32,23 +29,34 @@ int
 __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 {
 #ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_clock_getres_time64
-  return INLINE_VSYSCALL (clock_getres, 2, clock_id, res);
+  /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
+# ifdef __NR_clock_getres_time64
+  return INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
 # else
-  return INLINE_SYSCALL (clock_getres_time64, 2, clock_id, res);
+#  ifdef HAVE_CLOCK_GETRES_VSYSCALL
+  return INLINE_VSYSCALL (clock_getres, 2, clock_id, res);
+#  else
+  return INLINE_SYSCALL_CALL (clock_getres, clock_id, res);
+#  endif
 # endif
 #else
+  int r;
+  /* Old 32-bit ABI with possible 64-bit time_t support.  */
 # ifdef __NR_clock_getres_time64
-  int ret = INLINE_SYSCALL (clock_getres_time64, 2, clock_id, res);
-  if (ret == 0 || errno != ENOSYS)
-    return ret;
+  r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
+  if (r == 0 || errno != ENOSYS)
+    return r;
 # endif
+  /* Fallback code that uses 32-bit support.  */
   struct timespec ts32;
-  int retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, &ts32);
-  if (! retval && res)
+# ifdef HAVE_CLOCK_GETRES_VSYSCALL
+  r = INLINE_VSYSCALL (clock_getres, 2, clock_id, &ts32);
+# else
+  r = INLINE_SYSCALL_CALL (clock_getres, clock_id, &ts32);
+# endif
+  if (r == 0)
     *res = valid_timespec_to_timespec64 (ts32);
-
-  return retval;
+  return r;
 #endif
 }
 
@@ -60,7 +68,7 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
   int retval;
 
   retval = __clock_getres64 (clock_id, &ts64);
-  if (! retval && res)
+  if (retval == 0 && res != NULL)
     *res = valid_timespec64_to_timespec (ts64);
 
   return retval;
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 875c4fe905..e895812704 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -21,10 +21,6 @@
 #include <errno.h>
 #include <time.h>
 #include "kernel-posix-cpu-timers.h"
-
-#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 #include <shlib-compat.h>
@@ -34,22 +30,34 @@ int
 __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 {
 #ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_clock_gettime64
-#  define __NR_clock_gettime64   __NR_clock_gettime
-#  define __vdso_clock_gettime64 __vdso_clock_gettime
+  /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
+# ifdef __NR_clock_gettime64
+  return INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
+# else
+#  ifdef HAVE_CLOCK_GETTIME_VSYSCALL
+  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
+#  else
+  return INLINE_SYSCALL_CALL (clock_gettime, clock_id, tp);
+#  endif
 # endif
-   return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
 #else
-# if defined HAVE_CLOCK_GETTIME64_VSYSCALL
-  int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
-  if (ret64 == 0 || errno != ENOSYS)
-    return ret64;
+  int r;
+  /* Old 32-bit ABI with possible 64-bit time_t support.  */
+# ifdef __NR_clock_gettime64
+  r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
+  if (r == 0 || errno != ENOSYS)
+    return r;
 # endif
+  /* Fallback code that uses 32-bit support.  */
   struct timespec tp32;
-  int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32);
-  if (ret == 0)
+# ifdef HAVE_CLOCK_GETTIME_VSYSCALL
+  r = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32);
+# else
+  r = INLINE_SYSCALL_CALL (clock_gettime, clock_id, &tp32);
+# endif
+  if (r == 0)
     *tp = valid_timespec_to_timespec64 (tp32);
-  return ret;
+  return r;
 #endif
 }
 
diff --git a/sysdeps/unix/sysv/linux/getcpu.c b/sysdeps/unix/sysv/linux/getcpu.c
index fdd27203af..efb4bb7627 100644
--- a/sysdeps/unix/sysv/linux/getcpu.c
+++ b/sysdeps/unix/sysv/linux/getcpu.c
@@ -18,20 +18,15 @@
 #include <errno.h>
 #include <sched.h>
 #include <sysdep.h>
-
-#ifdef HAVE_GETCPU_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 int
 __getcpu (unsigned int *cpu, unsigned int *node)
 {
-#ifdef __NR_getcpu
+#ifdef HAVE_GETCPU_VSYSCALL
   return INLINE_VSYSCALL (getcpu, 3, cpu, node, NULL);
 #else
-  __set_errno (ENOSYS);
-  return -1;
+  return INLINE_SYSCALL_CALL (getcpu, cpu, node, NULL);
 #endif
 }
 weak_alias (__getcpu, getcpu)
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 18d8f7cb7a..c40793fe64 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -17,10 +17,6 @@
 
 #include <time.h>
 #include <sysdep.h>
-
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 static int
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index 80a4c73416..f2b4c76be8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -18,10 +18,6 @@
 
 #include <time.h>
 #include <sysdep.h>
-
-#ifdef HAVE_TIME_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 static time_t
diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
index 65dd9fdda7..68ba7f3734 100644
--- a/sysdeps/unix/sysv/linux/sched_getcpu.c
+++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
@@ -18,22 +18,17 @@
 #include <errno.h>
 #include <sched.h>
 #include <sysdep.h>
-
-#ifdef HAVE_GETCPU_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 int
 sched_getcpu (void)
 {
-#ifdef __NR_getcpu
   unsigned int cpu;
-  int r = INLINE_VSYSCALL (getcpu, 3, &cpu, NULL, NULL);
-
-  return r == -1 ? r : cpu;
+  int r = -1;
+#ifdef HAVE_GETCPU_VSYSCALL
+  r = INLINE_VSYSCALL (getcpu, 3, &cpu, NULL, NULL);
 #else
-  __set_errno (ENOSYS);
-  return -1;
+  r = INLINE_SYSCALL_CALL (getcpu, &cpu, NULL, NULL);
 #endif
+  return r == -1 ? r : cpu;
 }
diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h b/sysdeps/unix/sysv/linux/sysdep-vdso.h
index cf614fbf8b..76a211e39b 100644
--- a/sysdeps/unix/sysv/linux/sysdep-vdso.h
+++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h
@@ -20,17 +20,14 @@
 # define SYSDEP_VDSO_LINUX_H
 
 #include <dl-vdso.h>
+#include <libc-vdso.h>
 
 #ifndef INTERNAL_VSYSCALL_CALL
 # define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)      \
      funcptr (args)
 #endif
 
-#ifdef HAVE_VSYSCALL
-
-# include <libc-vdso.h>
-
-# define INLINE_VSYSCALL(name, nr, args...)      \
+#define INLINE_VSYSCALL(name, nr, args...)      \
   ({      \
     __label__ out;      \
     __label__ iserr;      \
@@ -59,31 +56,4 @@
     sc_ret;      \
   })
 
-# define INTERNAL_VSYSCALL(name, err, nr, args...)      \
-  ({      \
-    __label__ out;      \
-    long v_ret;      \
-      \
-    __typeof (__vdso_##name) vdsop = __vdso_##name;      \
-    PTR_DEMANGLE (vdsop);      \
-    if (vdsop != NULL)      \
-      {      \
- v_ret = INTERNAL_VSYSCALL_CALL (vdsop, err, nr, ##args);      \
- if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)      \
-    || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)      \
-  goto out;      \
-      }      \
-    v_ret = INTERNAL_SYSCALL (name, err, nr, ##args);      \
-  out:      \
-    v_ret;      \
-  })
-#else
-
-# define INLINE_VSYSCALL(name, nr, args...) \
-   INLINE_SYSCALL (name, nr, ##args)
-# define INTERNAL_VSYSCALL(name, err, nr, args...) \
-   INTERNAL_SYSCALL (name, err, nr, ##args)
-
-#endif /* USE_VSYSCALL && defined HAVE_VSYSCALL */
-
 #endif /* SYSDEP_VDSO_LINUX_H  */
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index 190127d31e..8015c40210 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -18,10 +18,6 @@
 
 #include <time.h>
 #include <sysdep.h>
-
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 static int
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
index 4a03c46d21..85a9fc8a08 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -18,16 +18,16 @@
 
 #include <time.h>
 #include <sysdep.h>
-
-#ifdef HAVE_TIME_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
 #include <sysdep-vdso.h>
 
 static time_t
 time_vsyscall (time_t *t)
 {
+#ifdef HAVE_TIME_VSYSCALL
   return INLINE_VSYSCALL (time, 1, t);
+#else
+  return INLINE_SYSCALL_CALL (time, t);
+#endif
 }
 
 #ifdef SHARED
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v2 02/16] x86: Make x32 use x86 time implementation

Adhemerval Zanella-2
Changes from previous version:

  - Remove unused x32 gettimeofday.c.

--

This is the only use of auto-generation syscall which uses a vDSO
plus IFUNC and the current x86 generic implementation already covers
the expected semantic.

Checked on x86_64-linux-gnu-x32.
---
 sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c | 1 -
 sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list  | 1 -
 2 files changed, 2 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c

diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
deleted file mode 100644
index cd342f33ad..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
+++ /dev/null
@@ -1 +0,0 @@
-#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 786c884232..58ea31d1fd 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
@@ -2,4 +2,3 @@
 
 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
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 03/16] Remove vDSO support from make-syscall.sh

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
The auto-generated vDSO call shows some issues:

  - It requires sync the auto-generated C file with current glibc
    implementation;
  - It still uses symbol redirections hacks where libc-symbols.h
    provide macros that uses compiler builtins
    (libc_ifunc_redirected for instance);
  - It does not handle all required compiler handling
    (inhibit_stack_protector on iFUNC resolver).
  - No architecure uses it.

Checked with a build against all major ABIs.
---
 sysdeps/unix/make-syscalls.sh | 45 +----------------------------------
 1 file changed, 1 insertion(+), 44 deletions(-)

diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
index fe24bbc78f..c07626677f 100644
--- a/sysdeps/unix/make-syscalls.sh
+++ b/sysdeps/unix/make-syscalls.sh
@@ -149,14 +149,6 @@ emit_weak_aliases()
 echo "$calls" |
 while read file srcfile caller syscall args strong weak; do
 
-  vdso_syscall=
-  case x"$syscall" in
-  *:*@*)
-    vdso_syscall="${syscall#*:}"
-    syscall="${syscall%:*}"
-    ;;
-  esac
-
   case x"$syscall" in
   x-) callnum=_ ;;
   *)
@@ -233,10 +225,9 @@ while read file srcfile caller syscall args strong weak; do
   if test $shared_only = t; then
     # The versioned symbols are only in the shared library.
     echo "shared-only-routines += $file"
-    test -n "$vdso_syscall" || echo "\$(objpfx)${file}.os: \\"
+    echo "\$(objpfx)${file}.os: \\"
   else
     object_suffixes='$(object-suffixes)'
-    test -z "$vdso_syscall" || object_suffixes='$(object-suffixes-noshared)'
     echo "\
 \$(foreach p,\$(sysd-rules-targets),\
 \$(foreach o,${object_suffixes},\$(objpfx)\$(patsubst %,\$p,$file)\$o)): \\"
@@ -268,40 +259,6 @@ while read file srcfile caller syscall args strong weak; do
   echo ' ) | $(compile-syscall) '"\
 \$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))"
 
-  if test -n "$vdso_syscall"; then
-    # In the shared library, we're going to emit an IFUNC using a vDSO function.
-    # $vdso_syscall looks like "[hidden email]" where "name" is the symbol
-    # name in the vDSO and KERNEL_X.Y is its symbol version.
-    vdso_symbol="${vdso_syscall%@*}"
-    vdso_symver="${vdso_syscall#*@}"
-    vdso_symver=`echo "$vdso_symver" | sed 's/\./_/g'`
-    cat <<EOF
-
-\$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
- \$(..)sysdeps/unix/make-syscalls.sh
- \$(make-target-directory)
- (echo '#define ${strong} __redirect_${strong}'; \\
- echo '#include <dl-vdso.h>'; \\
- echo '#undef ${strong}'; \\
- echo '#define vdso_ifunc_init()'; \\
- echo '__ifunc (__redirect_${strong}, ${strong},'; \\
- echo '         get_vdso_symbol ("${vdso_symbol}"), void,'; \\
- echo '         vdso_ifunc_init)'; \\
-EOF
-    # This is doing "hidden_def (${strong})", but the compiler
-    # doesn't know that we've defined ${strong} in the same file, so
-    # we can't do it the normal way.
-    cat <<EOF
- echo 'asm (".globl __GI_${strong}");'; \\
- echo 'asm ("__GI_${strong} = ${strong}");'; \\
-EOF
-    emit_weak_aliases
-    cat <<EOF
- ) | \$(compile-stdin.c) \
-\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))
-EOF
-  fi
-
   if test $shared_only = t; then
     # The versioned symbols are only in the shared library.
     echo endif
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 04/16] linux: Update x86 vDSO symbols

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
Add the missing time and clock_getres vDSO symbol names on x86.
For time, the iFUNC already uses expected name so it affects only
the static build.

The clock_getres is a new implementation added on Linux 5.3
(f66501dc53e72).

Checked on x86-linux-gnu and i686-linux-gnu.
---
 sysdeps/unix/sysv/linux/i386/sysdep.h   | 2 ++
 sysdeps/unix/sysv/linux/x86/time.c      | 4 ----
 sysdeps/unix/sysv/linux/x86_64/sysdep.h | 2 ++
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 7066ddc214..b2e750d490 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -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 HAVE_CLOCK_GETRES_VSYSCALL     "__vdso_clock_getres"
 
 /* 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
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
index 85a9fc8a08..67188a2ceb 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -23,11 +23,7 @@
 static time_t
 time_vsyscall (time_t *t)
 {
-#ifdef HAVE_TIME_VSYSCALL
   return INLINE_VSYSCALL (time, 1, t);
-#else
-  return INLINE_SYSCALL_CALL (time, t);
-#endif
 }
 
 #ifdef SHARED
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 475b7d991a..965fd4b851 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -376,7 +376,9 @@
 /* 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 HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
+# define HAVE_CLOCK_GETRES_VSYSCALL     "__vdso_clock_getres"
 
 # define SINGLE_THREAD_BY_GLOBAL 1
 
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 05/16] linux: Update mips vDSO symbols

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
The clock_getres is a new implementation added on Linux 5.4
(abed3d826f2f).

Checked with a build against mips-linux-gnu and mips64-linux-gnu.
---
 sysdeps/unix/sysv/linux/mips/sysdep.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sysdeps/unix/sysv/linux/mips/sysdep.h b/sysdeps/unix/sysv/linux/mips/sysdep.h
index 82a3cf9f3d..c2bec03806 100644
--- a/sysdeps/unix/sysv/linux/mips/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/sysdep.h
@@ -22,6 +22,7 @@
 /* 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_CLOCK_GETRES_VSYSCALL      "__vdso_clock_getres"
 
 #ifndef __ASSEMBLER__
 
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 06/16] linux: Consolidate Linux gettimeofday

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
The IFUNC bypass to vDSO is used when USE_IFUNC_GETTIMEOFDAY is set.
Currently aarch64, powerpc*, and x86 defines it.  Otherwise the
generic implementation is used, which calls clock_gettime.

Checked on aarch64-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu-power4, x86_64-linux-gnu,
and i686-linux-gnu.
---
 .../unix/sysv/linux/aarch64/gettimeofday.c    | 38 +------------
 sysdeps/unix/sysv/linux/gettimeofday.c        | 57 +++++++++++++++++++
 .../unix/sysv/linux/powerpc/gettimeofday.c    | 35 +-----------
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    | 33 +----------
 4 files changed, 63 insertions(+), 100 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c

diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
index 143c5c1507..f28260c8e9 100644
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
@@ -16,39 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-/* 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.  */
-
-#include <time.h>
-#include <sysdep.h>
-#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 *restrict tv, void *restrict 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 (__gettimeofday,
-    (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
-    ?: __gettimeofday_vsyscall))
-
-#else
-int
-__gettimeofday (struct timeval *restrict tv, void *restrict tz)
-{
-  return __gettimeofday_vsyscall (tv, tz);
-}
-#endif
-weak_alias (__gettimeofday, gettimeofday)
+#define USE_IFUNC_GETTIMEOFDAY
+#include <sysdeps/unix/sysv/linux/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
new file mode 100644
index 0000000000..600da6b468
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -0,0 +1,57 @@
+/* gettimeofday - set time.  Linux 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
+   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/>.  */
+
+/* Some architecture might optimize the gettimeofday by setting the plt direct
+   to vDSO symbol by using a IFUNC.  */
+#ifdef USE_IFUNC_GETTIMEOFDAY
+# include <time.h>
+# include <sysdep.h>
+# include <sysdep-vdso.h>
+
+# ifdef SHARED
+#  include <dl-vdso.h>
+
+static int
+__gettimeofday_syscall (struct timeval *restrict tv, void *restrict tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof *tz);
+  return INLINE_SYSCALL_CALL (gettimeofday, tv, tz);
+}
+
+# undef INIT_ARCH
+# define INIT_ARCH() \
+  void *vdso_gettimeofday = get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+libc_ifunc (__gettimeofday,
+    vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
+      : (void *) __gettimeofday_syscall)
+
+# else
+int
+__gettimeofday (struct timeval *restrict tv, void *restrict tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof *tz);
+
+  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+}
+# endif
+weak_alias (__gettimeofday, gettimeofday)
+#else /* USE_IFUNC_GETTIMEOFDAY  */
+# include <time/gettimeofday.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index c40793fe64..b2137f0d2d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,36 +15,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <sysdep.h>
-#include <sysdep-vdso.h>
-
-static int
-__gettimeofday_syscall (struct timeval *restrict tv, void *restrict 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 (__gettimeofday,
-    vdso_gettimeofday
-    ? VDSO_IFUNC_RET (vdso_gettimeofday)
-    : (void *) __gettimeofday_syscall);
-#else
-int
-__gettimeofday (struct timeval *restrict tv, void *restrict tz)
-{
-  return __gettimeofday_syscall (tv, tz);
-}
-#endif
-weak_alias (__gettimeofday, gettimeofday)
+#define USE_IFUNC_GETTIMEOFDAY
+#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 8015c40210..39e662c514 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -16,34 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <sysdep.h>
-#include <sysdep-vdso.h>
-
-static int
-__gettimeofday_syscall (struct timeval *restrict tv, void *restrict 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()
-/* If the vDSO is not available we fall back to syscall.  */
-libc_ifunc (__gettimeofday,
-    (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
-    ?: __gettimeofday_syscall));
-
-#else
-int
-__gettimeofday (struct timeval *restrict tv, void *restrict tz)
-{
-  return __gettimeofday_syscall (tv, tz);
-}
-#endif
-weak_alias (__gettimeofday, gettimeofday)
+#define USE_IFUNC_GETTIMEOFDAY
+#include <sysdeps/unix/sysv/linux/gettimeofday.c>
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 07/16] linux: Consolidate time implementation

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
The IFUNC bypass to vDSO is used when USE_IFUNC_TIME is set.
Currently powerpc and x86 defines it.  Otherwise the generic
implementation is used, which calls clock_gettime.

Checked on powerpc64le-linux-gnu, powerpc64-linux-gnu,
powerpc-linux-gnu-power4, x86_64-linux-gnu, and i686-linux-gnu.
---
 sysdeps/unix/sysv/linux/powerpc/time.c | 32 +---------------
 sysdeps/unix/sysv/linux/time.c         | 51 ++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86/time.c     | 27 +-------------
 3 files changed, 55 insertions(+), 55 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/time.c

diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index f2b4c76be8..3622ef48f6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -16,33 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <sysdep.h>
-#include <sysdep-vdso.h>
-
-static time_t
-time_vsyscall (time_t *t)
-{
-  return INLINE_VSYSCALL (time, 1, t);
-}
-
-#ifdef SHARED
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-
-# 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 (time,
-    vdso_time
-    ? VDSO_IFUNC_RET (vdso_time)
-    : (void *) time_vsyscall);
-
-#else
-time_t
-time (time_t *t)
-{
-  return time_vsyscall (t);
-}
-#endif /* !SHARED */
+#define USE_IFUNC_TIME
+#include <sysdeps/unix/sysv/linux/time.c>
diff --git a/sysdeps/unix/sysv/linux/time.c b/sysdeps/unix/sysv/linux/time.c
new file mode 100644
index 0000000000..0598958c9c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/time.c
@@ -0,0 +1,51 @@
+/* time -- Get number of seconds since Epoch.  Linux 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
+   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/>.  */
+
+/* Some architecture might optimize the time by setting the plt direct
+   to vDSO symbol by using a IFUNC.  */
+#ifdef USE_IFUNC_TIME
+# include <time.h>
+# include <sysdep.h>
+# include <sysdep-vdso.h>
+
+#ifdef SHARED
+# include <dl-vdso.h>
+
+static time_t
+time_syscall (time_t *t)
+{
+  return INLINE_SYSCALL_CALL (time, t);
+}
+
+# undef INIT_ARCH
+# define INIT_ARCH() \
+  void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL);
+libc_ifunc (time,
+    vdso_time ? VDSO_IFUNC_RET (vdso_time)
+      : (void *) time_syscall);
+
+# else
+time_t
+time (time_t *t)
+{
+  return INLINE_VSYSCALL (time, 1, t);
+}
+# endif /* !SHARED */
+#else /* USE_IFUNC_TIME  */
+# include <time/time.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
index 67188a2ceb..7b1d7bac76 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -16,28 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <sysdep.h>
-#include <sysdep-vdso.h>
-
-static time_t
-time_vsyscall (time_t *t)
-{
-  return INLINE_VSYSCALL (time, 1, t);
-}
-
-#ifdef SHARED
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-
-#undef INIT_ARCH
-#define INIT_ARCH()
-/* If the vDSO is not available we fall back on the syscall.  */
-libc_ifunc (time, (get_vdso_symbol ("__vdso_time") ?: time_vsyscall))
-#else
-time_t
-time (time_t *t)
-{
-  return time_vsyscall (t);
-}
-#endif
+#define USE_IFUNC_TIME
+#include <sysdeps/unix/sysv/linux/time.c>
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v3 08/16] elf: Enable relro for static build

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
Changes from previous version:

  - The tests were removed and instead I will use the ones proposed
    by Florian's patch 'elf: Add tests for working RELRO protection'
    [1].  I also plan to send additional coverage for '.data.rel.ro'
    which trigger failures for the static case on both partial and
    full relro which is fixed by this patch once the patch is
    upstream.

--

The code is similar to the one at elf/dl-reloc.c, where it checks for
the l_relro_size from the link_map (obtained from PT_GNU_RELRO header
from program headers) and calls_dl_protected_relro.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
aarch64-linux-gnu, s390x-linux-gnu, and sparc64-linux-gnu.  I also
check with --enable-static pie on x86_64-linux-gnu, i686-linux-gnu,
and aarch64-linux-gnu which seems the only architectures where
static PIE is actually working (as per 9d7a3741c9e, on
arm-linux-gnueabihf, powerpc64{le}-linux-gnu, and s390x-linux-gnu
I am seeing runtime issues not related to my patch).

[1] https://sourceware.org/ml/libc-alpha/2019-10/msg00059.html
---
 elf/dl-support.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/elf/dl-support.c b/elf/dl-support.c
index 5526d5ee6e..b2b1b12f6f 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -367,14 +367,24 @@ _dl_non_dynamic_init (void)
   if (_dl_platform != NULL)
     _dl_platformlen = strlen (_dl_platform);
 
-  /* Scan for a program header telling us the stack is nonexecutable.  */
   if (_dl_phdr != NULL)
-    for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
-      if (_dl_phdr[i].p_type == PT_GNU_STACK)
+    for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
+      switch (ph->p_type)
  {
-  _dl_stack_flags = _dl_phdr[i].p_flags;
+ /* Check if the stack is nonexecutable.  */
+ case PT_GNU_STACK:
+  _dl_stack_flags = ph->p_flags;
+  break;
+
+ case PT_GNU_RELRO:
+  _dl_main_map.l_relro_addr = ph->p_vaddr;
+  _dl_main_map.l_relro_size = ph->p_memsz;
   break;
  }
+
+  /* Setup relro on the binary itself.  */
+  if (_dl_main_map.l_relro_size != 0)
+    _dl_protect_relro (&_dl_main_map);
 }
 
 #ifdef DL_SYSINFO_IMPLEMENTATION
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v3 09/16] elf: Move vDSO setup to rtld (BZ#24967)

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
Changes from previous version:

  - Do not GLRO access on ifunc resolver, ut rather call the vDSO
    resolve function instead (dl_vdso_vsym).

--

This patch moves the vDSO setup from libc to loader code, just after
the vDSO link_map setup.  For static case the initialization
is moved to _dl_non_dynamic_init instead.

Instead of using the mangled pointer, the vDSO data is set as
attribute_relro (on _rtld_global_ro for shared or _dl_vdso_* for
static).  It is read-only even with partial relro.

It fixes BZ#24967 now that the vDSO pointer is setup earlier than
malloc interposition is called.

Also, vDSO calls should not be a problem for static dlopen as
indicated by BZ#20802.  The vDSO pointer would be zero-initialized
and the syscall will be issued instead.

Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
arm-linux-gnueabihf, powerpc64le-linux-gnu, powerpc64-linux-gnu,
powerpc-linux-gnu, s390x-linux-gnu, sparc64-linux-gnu, and
sparcv9-linux-gnu.  I also run some tests on mips.
---
 csu/init-first.c                              |  4 -
 elf/dl-support.c                              |  7 ++
 elf/rtld.c                                    |  7 +-
 malloc/tst-interpose-aux.c                    |  5 ++
 sysdeps/generic/dl-vdso-setup.c               |  1 +
 sysdeps/generic/dl-vdso-setup.h               | 28 ++++++
 sysdeps/generic/dl-vdso.h                     | 30 +++++++
 sysdeps/generic/ldsodefs.h                    |  6 ++
 sysdeps/powerpc/powerpc32/backtrace.c         | 16 ++--
 sysdeps/powerpc/powerpc64/backtrace.c         |  8 +-
 sysdeps/unix/sysv/linux/aarch64/Makefile      |  1 -
 sysdeps/unix/sysv/linux/arm/Makefile          |  1 -
 sysdeps/unix/sysv/linux/dl-vdso-setup.c       | 81 +++++++++++++++++
 sysdeps/unix/sysv/linux/dl-vdso-setup.h       | 55 ++++++++++++
 sysdeps/unix/sysv/linux/dl-vdso.c             | 48 ----------
 sysdeps/unix/sysv/linux/dl-vdso.h             | 30 ++++---
 sysdeps/unix/sysv/linux/gettimeofday.c        |  3 +-
 sysdeps/unix/sysv/linux/init-first.c          | 90 -------------------
 sysdeps/unix/sysv/linux/libc-vdso.h           | 30 +------
 sysdeps/unix/sysv/linux/mips/Makefile         |  2 -
 sysdeps/unix/sysv/linux/powerpc/Makefile      |  1 -
 .../sysv/linux/powerpc/get_timebase_freq.c    |  5 +-
 sysdeps/unix/sysv/linux/powerpc/init-first.c  | 50 -----------
 sysdeps/unix/sysv/linux/powerpc/libc-vdso.h   | 10 ---
 sysdeps/unix/sysv/linux/riscv/Makefile        |  4 -
 sysdeps/unix/sysv/linux/riscv/flush-icache.c  |  2 +-
 sysdeps/unix/sysv/linux/s390/Makefile         |  4 -
 sysdeps/unix/sysv/linux/sparc/Makefile        |  4 -
 sysdeps/unix/sysv/linux/sysdep-vdso.h         |  6 +-
 sysdeps/unix/sysv/linux/time.c                |  3 +-
 sysdeps/unix/sysv/linux/x86/Makefile          |  4 -
 31 files changed, 257 insertions(+), 289 deletions(-)
 create mode 100644 sysdeps/generic/dl-vdso-setup.c
 create mode 100644 sysdeps/generic/dl-vdso-setup.h
 create mode 100644 sysdeps/generic/dl-vdso.h
 create mode 100644 sysdeps/unix/sysv/linux/dl-vdso-setup.c
 create mode 100644 sysdeps/unix/sysv/linux/dl-vdso-setup.h
 delete mode 100644 sysdeps/unix/sysv/linux/dl-vdso.c
 delete mode 100644 sysdeps/unix/sysv/linux/init-first.c
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/init-first.c

diff --git a/csu/init-first.c b/csu/init-first.c
index e0f489ee6d..891719a839 100644
--- a/csu/init-first.c
+++ b/csu/init-first.c
@@ -74,10 +74,6 @@ _init (int argc, char **argv, char **envp)
   _dl_non_dynamic_init ();
 #endif
 
-#ifdef VDSO_SETUP
-  VDSO_SETUP ();
-#endif
-
   __init_misc (argc, argv, envp);
 
   /* Initialize ctype data.  */
diff --git a/elf/dl-support.c b/elf/dl-support.c
index b2b1b12f6f..81d44b0343 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -34,6 +34,8 @@
 #include <unsecvars.h>
 #include <hp-timing.h>
 #include <stackinfo.h>
+#include <dl-vdso.h>
+#include <dl-vdso-setup.h>
 
 extern char *__progname;
 char **_dl_argv = &__progname; /* This is checked for some error messages.  */
@@ -201,6 +203,8 @@ struct link_map *_dl_sysinfo_map;
 # include "get-dynamic-info.h"
 #endif
 #include "setup-vdso.h"
+/* Define the vDSO function pointers.  */
+#include <dl-vdso-setup.c>
 
 /* During the program run we must not modify the global data of
    loaded shared object simultanously in two threads.  Therefore we
@@ -315,6 +319,9 @@ _dl_non_dynamic_init (void)
      so they can influence _dl_init_paths.  */
   setup_vdso (NULL, NULL);
 
+  /* With vDSO setup we can initialize the function pointers.  */
+  setup_vdso_pointers ();
+
   /* Initialize the data structures for the search paths for shared
      objects.  */
   _dl_init_paths (getenv ("LD_LIBRARY_PATH"));
diff --git a/elf/rtld.c b/elf/rtld.c
index dd8fc5e6c6..a06e13c657 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -39,6 +39,8 @@
 #include <dl-osinfo.h>
 #include <dl-procinfo.h>
 #include <dl-prop.h>
+#include <dl-vdso.h>
+#include <dl-vdso-setup.h>
 #include <tls.h>
 #include <stap-probe.h>
 #include <stackinfo.h>
@@ -833,7 +835,7 @@ security_init (void)
   _dl_random = NULL;
 }
 
-#include "setup-vdso.h"
+#include <setup-vdso.h>
 
 /* The library search path.  */
 static const char *library_path attribute_relro;
@@ -1538,6 +1540,9 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
      so they can influence _dl_init_paths.  */
   setup_vdso (main_map, &first_preload);
 
+  /* With vDSO setup we can initialize the function pointers.  */
+  setup_vdso_pointers ();
+
 #ifdef DL_SYSDEP_OSCHECK
   DL_SYSDEP_OSCHECK (_dl_fatal_printf);
 #endif
diff --git a/malloc/tst-interpose-aux.c b/malloc/tst-interpose-aux.c
index bbe321e843..8cbc3e6fea 100644
--- a/malloc/tst-interpose-aux.c
+++ b/malloc/tst-interpose-aux.c
@@ -28,6 +28,7 @@
 #include <sys/mman.h>
 #include <sys/uio.h>
 #include <unistd.h>
+#include <time.h>
 
 #if INTERPOSE_THREADS
 #include <pthread.h>
@@ -96,6 +97,7 @@ struct __attribute__ ((aligned (__alignof__ (max_align_t)))) allocation_header
 {
   size_t allocation_index;
   size_t allocation_size;
+  struct timespec ts;
 };
 
 /* Array of known allocations, to track invalid frees.  */
@@ -166,6 +168,9 @@ malloc_internal (size_t size)
       .allocation_index = index,
       .allocation_size = allocation_size
     };
+  /* BZ#24967: Check if calling a symbol which may use the vDSO does not fail.
+     The CLOCK_REALTIME should be supported on all systems.  */
+  clock_gettime (CLOCK_REALTIME, &allocations[index]->ts);
   return allocations[index] + 1;
 }
 
diff --git a/sysdeps/generic/dl-vdso-setup.c b/sysdeps/generic/dl-vdso-setup.c
new file mode 100644
index 0000000000..6e25b021ab
--- /dev/null
+++ b/sysdeps/generic/dl-vdso-setup.c
@@ -0,0 +1 @@
+/* Empty.  */
diff --git a/sysdeps/generic/dl-vdso-setup.h b/sysdeps/generic/dl-vdso-setup.h
new file mode 100644
index 0000000000..3d79bae317
--- /dev/null
+++ b/sysdeps/generic/dl-vdso-setup.h
@@ -0,0 +1,28 @@
+/* ELF symbol initialization functions for VDSO objects.
+   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
+   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/>.  */
+
+#ifndef _DL_VDSO_INIT_H
+#define _DL_VDSO_INIT_H
+
+/* Initialize the VDSO functions pointers.  */
+static inline void __attribute__ ((always_inline))
+setup_vdso_pointers (void)
+{
+}
+
+#endif
diff --git a/sysdeps/generic/dl-vdso.h b/sysdeps/generic/dl-vdso.h
new file mode 100644
index 0000000000..5651f49a1a
--- /dev/null
+++ b/sysdeps/generic/dl-vdso.h
@@ -0,0 +1,30 @@
+/* ELF symbol resolve functions for VDSO objects.
+   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
+   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/>.  */
+
+#ifndef _DL_VDSO_H
+#define _DL_VDSO_H 1
+
+/* Function for resolving symbols in the VDSO link map.  Return the
+   address of the vdso symbol NAME. */
+static inline void *
+dl_vdso_vsym (const char *name)
+{
+  return NULL;
+}
+
+#endif
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index fc25a81e1c..8cbd0e87cc 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -608,6 +608,12 @@ struct rtld_global_ro
   /* At startup time we set up the normal DSO data structure for it,
      and this points to it.  */
   EXTERN struct link_map *_dl_sysinfo_map;
+
+# define PROCINFO_DECL
+# ifndef PROCINFO_CLASS
+#  define PROCINFO_CLASS EXTERN
+# endif
+# include <dl-vdso-setup.c>
 #endif
 
   /* Mask for more hardware capabilities that are available on some
diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c
index 2e6a859d9f..f2a57480a5 100644
--- a/sysdeps/powerpc/powerpc32/backtrace.c
+++ b/sysdeps/powerpc/powerpc32/backtrace.c
@@ -51,14 +51,14 @@ struct signal_frame_32 {
   /* We don't care about the rest, since IP value is at 'mctx' field.  */
 };
 
-static inline int
+static inline bool
 is_sigtramp_address (void *nip)
 {
 #ifdef HAVE_SIGTRAMP_RT32
-  if (nip == VDSO_SYMBOL (sigtramp32))
-    return 1;
+  if (nip == GLRO (dl_vdso_sigtramp_32))
+    return true;
 #endif
-  return 0;
+  return false;
 }
 
 struct rt_signal_frame_32 {
@@ -68,14 +68,14 @@ struct rt_signal_frame_32 {
   /* We don't care about the rest, since IP value is at 'uc' field.  */
 };
 
-static inline int
+static inline bool
 is_sigtramp_address_rt (void * nip)
 {
 #ifdef HAVE_SIGTRAMP_32
-  if (nip == VDSO_SYMBOL (sigtramp_rt32))
-    return 1;
+  if (nip == GLRO (dl_vdso_sigtramp_rt32))
+    return true;
 #endif
-  return 0;
+  return false;
 }
 
 int
diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c
index 234d9c00dc..8ed5bc1585 100644
--- a/sysdeps/powerpc/powerpc64/backtrace.c
+++ b/sysdeps/powerpc/powerpc64/backtrace.c
@@ -54,14 +54,14 @@ struct signal_frame_64 {
   /* We don't care about the rest, since the IP value is at 'uc' field.  */
 };
 
-static inline int
+static inline bool
 is_sigtramp_address (void *nip)
 {
 #ifdef HAVE_SIGTRAMP_RT64
-  if (nip == VDSO_SYMBOL (sigtramp_rt64))
-    return 1;
+  if (nip == GLRO (dl_vdso_sigtramp_rt64))
+    return true;
 #endif
-  return 0;
+  return false;
 }
 
 int
diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
index 57bbfeaac6..4bcae85bca 100644
--- a/sysdeps/unix/sysv/linux/aarch64/Makefile
+++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
@@ -5,7 +5,6 @@ shared-only-routines += libc-__read_tp
 endif
 
 ifeq ($(subdir),elf)
-sysdep_routines     += dl-vdso
 sysdep-rtld-routines += __read_tp
 ifeq ($(build-shared),yes)
 # This is needed for DSO loading from static binaries.
diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index d7a2f6a8a7..abdf01f00c 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -1,5 +1,4 @@
 ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
 sysdep-rtld-routines += aeabi_read_tp libc-do-syscall
 endif
 
diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.c b/sysdeps/unix/sysv/linux/dl-vdso-setup.c
new file mode 100644
index 0000000000..1069879f1a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.c
@@ -0,0 +1,81 @@
+/* Data for vDSO support.  Linux 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
+   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/>.  */
+
+/* This file is included in three different modes for both static (libc.a)
+   and shared (rtld) modes:
+
+   1. PROCINFO_DECL is defined, meaning we are only interested in
+      declarations.  For static it requires use the extern keywork along with
+      the attribute_relro while for shared it will be embedded in the
+      rtld_global_ro.
+
+   2. PROCINFO_DECL and SHARED are not defined.  Nothing to do, the default
+      zero initializion is suffice.
+
+   3. PROCINFO_DECL is not defined while SHARED is.  Similar to 2., the zero
+      initialization of rtld_global_ro is suffice.  */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#ifndef SHARED
+# define RELRO attribute_relro
+#else
+# define RELRO
+#endif
+
+#if defined PROCINFO_DECL || !defined SHARED
+# ifdef HAVE_CLOCK_GETTIME_VSYSCALL
+PROCINFO_CLASS int (*_dl_vdso_clock_gettime) (clockid_t,
+      struct timespec *) RELRO;
+#endif
+# ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+PROCINFO_CLASS int (*_dl_vdso_gettimeofday) (struct timeval *, void *) RELRO;
+#endif
+# ifdef HAVE_TIME_VSYSCALL
+PROCINFO_CLASS time_t (*_dl_vdso_time) (time_t *) RELRO;
+# endif
+# ifdef HAVE_GETCPU_VSYSCALL
+PROCINFO_CLASS int (*_dl_vdso_getcpu) (unsigned *, unsigned *, void *) RELRO;
+# endif
+# ifdef HAVE_CLOCK_GETRES_VSYSCALL
+PROCINFO_CLASS int (*_dl_vdso_clock_getres) (clockid_t,
+     struct timespec *) RELRO;
+# endif
+
+/* PowerPC specific ones.  */
+# ifdef HAVE_GET_TBFREQ
+PROCINFO_CLASS uint64_t (*_dl_vdso_get_tbfreq)(void) RELRO;
+# endif
+/* The sigtramp are used on powerpc backtrace without using
+   INLINE_VSYSCALL, so there is no need to set their type.  */
+# ifdef HAVE_SIGTRAMP_RT64
+PROCINFO_CLASS void *_dl_vdso_sigtramp_rt64 RELRO;
+# endif
+# ifdef HAVE_SIGTRAMP_RT32
+PROCINFO_CLASS void *_dl_vdso_sigtramp_rt32 RELRO;
+# endif
+# ifdef HAVE_SIGTRAMP_32
+PROCINFO_CLASS void *_dl_vdso_sigtramp_32 RELRO;
+# endif
+#endif
+
+#undef RELRO
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.h b/sysdeps/unix/sysv/linux/dl-vdso-setup.h
new file mode 100644
index 0000000000..f4e76202fc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.h
@@ -0,0 +1,55 @@
+/* ELF symbol initialization functions for VDSO objects.  Linux 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
+   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/>.  */
+
+#ifndef _DL_VDSO_INIT_H
+#define _DL_VDSO_INIT_H
+
+/* Initialize the VDSO functions pointers.  */
+static inline void __attribute__ ((always_inline))
+setup_vdso_pointers (void)
+{
+#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
+  GLRO(dl_vdso_clock_gettime) = dl_vdso_vsym (HAVE_CLOCK_GETTIME_VSYSCALL);
+#endif
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+  GLRO(dl_vdso_gettimeofday) = dl_vdso_vsym (HAVE_GETTIMEOFDAY_VSYSCALL);
+#endif
+#ifdef HAVE_TIME_VSYSCALL
+  GLRO(dl_vdso_time) = dl_vdso_vsym (HAVE_TIME_VSYSCALL);
+#endif
+#ifdef HAVE_GETCPU_VSYSCALL
+  GLRO(dl_vdso_getcpu) = dl_vdso_vsym (HAVE_GETCPU_VSYSCALL);
+#endif
+#ifdef HAVE_CLOCK_GETRES_VSYSCALL
+  GLRO(dl_vdso_clock_getres) = dl_vdso_vsym (HAVE_CLOCK_GETRES_VSYSCALL);
+#endif
+#ifdef HAVE_GET_TBFREQ
+  GLRO(dl_vdso_get_tbfreq) = dl_vdso_vsym (HAVE_GET_TBFREQ);
+#endif
+#ifdef HAVE_SIGTRAMP_RT64
+  GLRO(dl_vdso_sigtramp_rt64) = dl_vdso_vsym (HAVE_SIGTRAMP_RT64);
+#endif
+#ifdef HAVE_SIGTRAMP_RT32
+  GLRO(dl_vdso_sigtramp_rt32) = dl_vdso_vsym (HAVE_SIGTRAMP_RT32);
+#endif
+#ifdef HAVE_SIGTRAMP_32
+  GLRO(dl_vdso_sigtramp_32) = dl_vdso_vsym (HAVE_SIGTRAMP_32);
+#endif
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.c b/sysdeps/unix/sysv/linux/dl-vdso.c
deleted file mode 100644
index 5577f2103c..0000000000
--- a/sysdeps/unix/sysv/linux/dl-vdso.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ELF symbol resolve functions for VDSO objects.
-   Copyright (C) 2005-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 "config.h"
-#include <ldsodefs.h>
-
-
-void *
-_dl_vdso_vsym (const char *name, const struct r_found_version *vers)
-{
-  struct link_map *map = GLRO (dl_sysinfo_map);
-  void *value = NULL;
-
-
-  if (map != NULL)
-    {
-      /* Use a WEAK REF so we don't error out if the symbol is not found.  */
-      ElfW (Sym) wsym;
-      memset (&wsym, 0, sizeof (ElfW (Sym)));
-      wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
-
-      /* Search the scope of the vdso map.  */
-      const ElfW (Sym) *ref = &wsym;
-      lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
-   map->l_local_scope,
-   vers, 0, 0, NULL);
-
-      if (ref != NULL)
- value = DL_SYMBOL_ADDRESS (result, ref);
-    }
-
-  return value;
-}
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
index 19ffd30c7e..d1e782b81f 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso.h
+++ b/sysdeps/unix/sysv/linux/dl-vdso.h
@@ -22,11 +22,6 @@
 #include <ldsodefs.h>
 #include <dl-hash.h>
 
-/* Functions for resolving symbols in the VDSO link map.  */
-extern void *_dl_vdso_vsym (const char *name,
-    const struct r_found_version *version)
-      attribute_hidden;
-
 /* If the architecture support vDSO it should define which is the expected
    kernel version and hash value through both VDSO_NAME and VDSO_HASH
    (usually defined at architecture sysdep.h).  */
@@ -38,19 +33,26 @@ extern void *_dl_vdso_vsym (const char *name,
 # define VDSO_HASH 0
 #endif
 
+/* Functions for resolving symbols in the VDSO link map.  */
 static inline void *
-get_vdso_symbol (const char *symbol)
+dl_vdso_vsym (const char *name)
 {
+  struct link_map *map = GLRO (dl_sysinfo_map);
+  if (map == NULL)
+    return NULL;
+
+  /* Use a WEAK REF so we don't error out if the symbol is not found.  */
+  ElfW (Sym) wsym = { 0 };
+  wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
+
   struct r_found_version rfv = { VDSO_NAME, VDSO_HASH, 1, NULL };
-  return _dl_vdso_vsym (symbol, &rfv);
-}
 
-static inline void *
-get_vdso_mangle_symbol (const char *symbol)
-{
-  void *vdsop = get_vdso_symbol (symbol);
-  PTR_MANGLE (vdsop);
-  return vdsop;
+  /* Search the scope of the vdso map.  */
+  const ElfW (Sym) *ref = &wsym;
+  lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
+       map->l_local_scope,
+       &rfv, 0, 0, NULL);
+  return ref != NULL ? DL_SYMBOL_ADDRESS (result, ref) : NULL;
 }
 
 #endif /* dl-vdso.h */
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
index 600da6b468..6945be269c 100644
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -25,6 +25,7 @@
 
 # ifdef SHARED
 #  include <dl-vdso.h>
+# include <libc-vdso.h>
 
 static int
 __gettimeofday_syscall (struct timeval *restrict tv, void *restrict tz)
@@ -36,7 +37,7 @@ __gettimeofday_syscall (struct timeval *restrict tv, void *restrict tz)
 
 # undef INIT_ARCH
 # define INIT_ARCH() \
-  void *vdso_gettimeofday = get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+  void *vdso_gettimeofday = dl_vdso_vsym (HAVE_GETTIMEOFDAY_VSYSCALL)
 libc_ifunc (__gettimeofday,
     vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
       : (void *) __gettimeofday_syscall)
diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c
deleted file mode 100644
index d005d13322..0000000000
--- a/sysdeps/unix/sysv/linux/init-first.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* vDSO internal symbols.  Linux generic 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
-   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 <dl-vdso.h>
-#include <libc-vdso.h>
-
-/* vDSO symbol used on clock_gettime implementation.  */
-#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
-int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
-  attribute_hidden;
-#endif
-/* vDSO symbol used on clock_gettime64 implementation.  */
-#ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
-int (*VDSO_SYMBOL(clock_gettime64)) (clockid_t, struct __timespec64 *)
-  attribute_hidden;
-#endif
-/* vDSO symbol used on clock_getres implementation.  */
-#ifdef HAVE_CLOCK_GETRES_VSYSCALL
-int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *)
-  attribute_hidden;
-#endif
-/* vDSO symbol used on gettimeofday implementation.  */
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
-  attribute_hidden;
-#endif
-/* vDSO symbol used on GNU extension getcpu implementation.  */
-#ifdef HAVE_GETCPU_VSYSCALL
-long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *)
-   attribute_hidden;
-#endif
-/* vDSO symbol used on time implementation.  */
-#ifdef HAVE_TIME_VSYSCALL
-time_t (*VDSO_SYMBOL(time)) (time_t *) attribute_hidden;
-#endif
-
-static inline void
-__libc_vdso_platform_setup (void)
-{
-#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
-  VDSO_SYMBOL(clock_gettime)
-    = get_vdso_mangle_symbol (HAVE_CLOCK_GETTIME_VSYSCALL);
-#endif
-
-#ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
-  VDSO_SYMBOL(clock_gettime64)
-    = get_vdso_mangle_symbol (HAVE_CLOCK_GETTIME64_VSYSCALL);
-#endif
-
-#ifdef HAVE_CLOCK_GETRES_VSYSCALL
-  VDSO_SYMBOL(clock_getres)
-    = get_vdso_mangle_symbol (HAVE_CLOCK_GETRES_VSYSCALL);
-#endif
-
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-  VDSO_SYMBOL(gettimeofday)
-    = get_vdso_mangle_symbol (HAVE_GETTIMEOFDAY_VSYSCALL);
-#endif
-
-#ifdef HAVE_GETCPU_VSYSCALL
-  VDSO_SYMBOL(getcpu) = get_vdso_mangle_symbol (HAVE_GETCPU_VSYSCALL);
-#endif
-
-#ifdef HAVE_TIME_VSYSCALL
-  VDSO_SYMBOL(time) = get_vdso_mangle_symbol (HAVE_TIME_VSYSCALL);
-#endif
-
-#ifdef VDSO_SETUP_ARCH
-  VDSO_SETUP_ARCH ();
-#endif
-}
-
-#define VDSO_SETUP __libc_vdso_platform_setup
-
-#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/libc-vdso.h b/sysdeps/unix/sysv/linux/libc-vdso.h
index c6d505bab3..004faf0a97 100644
--- a/sysdeps/unix/sysv/linux/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/libc-vdso.h
@@ -19,37 +19,9 @@
 #ifndef _LIBC_VDSO_H
 #define _LIBC_VDSO_H
 
-#define VDSO_SYMBOL(__name) __vdso_##__name
-
 /* Adjust the return IFUNC value from a vDSO symbol accordingly required
    by the ELFv1 ABI.  It is used by the architecture to create an ODP
    entry since the kernel vDSO does not provide it.  */
-#ifndef VDSO_IFUNC_RET
-# define VDSO_IFUNC_RET(__value) (__value)
-#endif
+#define VDSO_IFUNC_RET(__value) (__value)
 
-#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
-extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
-  attribute_hidden;
-#endif
-#ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
-extern int (*VDSO_SYMBOL(clock_gettime64)) (clockid_t, struct __timespec64 *)
-  attribute_hidden;
-#endif
-#ifdef HAVE_CLOCK_GETRES_VSYSCALL
-extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *)
-  attribute_hidden;
 #endif
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-extern int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
-  attribute_hidden;
-#endif
-#ifdef HAVE_GETCPU_VSYSCALL
-extern long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *)
-  attribute_hidden;
-#endif
-#ifdef HAVE_TIME_VSYSCALL
-extern time_t (*VDSO_SYMBOL(time)) (time_t *) attribute_hidden;
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile
index 03044e7365..026ba242cf 100644
--- a/sysdeps/unix/sysv/linux/mips/Makefile
+++ b/sysdeps/unix/sysv/linux/mips/Makefile
@@ -60,8 +60,6 @@ ifeq ($(subdir),elf)
 ifeq ($(build-shared),yes)
 # This is needed for DSO loading from static binaries.
 sysdep-dl-routines += dl-static
-
-sysdep_routines += dl-vdso
 endif
 # If the compiler doesn't use GNU.stack note,
 # this test is expected to fail.
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index 1596238afa..cc2f804d86 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -13,7 +13,6 @@ gen-as-const-headers += ucontext_i.sym
 endif
 
 ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
 ifeq ($(build-shared),yes)
 # This is needed for DSO loading from static binaries.
 sysdep-dl-routines += dl-static
diff --git a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
index 29b6624b9a..11eb2b126d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
+++ b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
@@ -21,7 +21,7 @@
 
 #include <libc-internal.h>
 #include <not-cancel.h>
-#include <libc-vdso.h>
+#include <sysdep-vdso.h>
 
 static uint64_t
 get_timebase_freq_fallback (void)
@@ -101,8 +101,7 @@ uint64_t
 __get_timebase_freq (void)
 {
   /* The vDSO does not have a fallback mechanism (such calling a syscall).  */
-  __typeof (VDSO_SYMBOL (get_tbfreq)) vdsop = VDSO_SYMBOL (get_tbfreq);
-  PTR_DEMANGLE (vdsop);
+  uint64_t (*vdsop)(void) = GLRO(dl_vdso_get_tbfreq);
   if (vdsop == NULL)
     return get_timebase_freq_fallback ();
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c
deleted file mode 100644
index 92a4af83af..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/init-first.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Initialization code run first thing by the ELF startup code.  Linux/PowerPC.
-   Copyright (C) 2007-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 <dl-vdso.h>
-#include <libc-vdso.h>
-
-unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void) attribute_hidden;
-#if defined(__PPC64__) || defined(__powerpc64__)
-void *VDSO_SYMBOL(sigtramp_rt64) attribute_hidden;
-#else
-void *VDSO_SYMBOL(sigtramp32) attribute_hidden;
-void *VDSO_SYMBOL(sigtramp_rt32) attribute_hidden;
-#endif
-
-static inline void
-__libc_vdso_platform_setup_arch (void)
-{
-  VDSO_SYMBOL (get_tbfreq) = get_vdso_mangle_symbol (HAVE_GET_TBFREQ);
-
-  /* PPC64 uses only one signal trampoline symbol, while PPC32 will use
-     two depending if SA_SIGINFO is used (__kernel_sigtramp_rt32) or not
-     (__kernel_sigtramp32).
-     There is no need to pointer mangle these symbol because they will
-     used only for pointer comparison.  */
-#if defined(__PPC64__) || defined(__powerpc64__)
-  VDSO_SYMBOL(sigtramp_rt64) =  get_vdso_symbol (HAVE_SIGTRAMP_RT64);
-#else
-  VDSO_SYMBOL(sigtramp32) = get_vdso_symbol (HAVE_SIGTRAMP_32);
-  VDSO_SYMBOL(sigtramp_rt32) = get_vdso_symbol (HAVE_SIGTRAMP_RT32);
-#endif
-}
-
-#define VDSO_SETUP_ARCH __libc_vdso_platform_setup_arch
-
-#include <sysdeps/unix/sysv/linux/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
index cb7da3b289..adc06d48b0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
@@ -54,14 +54,4 @@
 # define VDSO_IFUNC_RET(value)  ((void *) (value))
 #endif
 
-#include_next <libc-vdso.h>
-
-extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
-#if defined(__PPC64__) || defined(__powerpc64__)
-extern void *VDSO_SYMBOL(sigtramp_rt64);
-#else
-extern void *VDSO_SYMBOL(sigtramp32);
-extern void *VDSO_SYMBOL(sigtramp_rt32);
-#endif
-
 #endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/riscv/Makefile b/sysdeps/unix/sysv/linux/riscv/Makefile
index b7ad31885c..301b082398 100644
--- a/sysdeps/unix/sysv/linux/riscv/Makefile
+++ b/sysdeps/unix/sysv/linux/riscv/Makefile
@@ -1,7 +1,3 @@
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
-
 ifeq ($(subdir),misc)
 sysdep_headers += sys/cachectl.h
 sysdep_routines += flush-icache
diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
index c5bd60d9c2..e967e40deb 100644
--- a/sysdeps/unix/sysv/linux/riscv/flush-icache.c
+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
@@ -38,7 +38,7 @@ __riscv_flush_icache_syscall (void *start, void *end, unsigned long int flags)
 static func_type
 __lookup_riscv_flush_icache (void)
 {
-  func_type func = get_vdso_symbol ("__vdso_flush_icache");
+  func_type func = dl_vdso_vsym ("__vdso_flush_icache");
 
   /* If there is no vDSO entry then call the system call directly.  All Linux
      versions provide the vDSO entry, but QEMU's user-mode emulation doesn't
diff --git a/sysdeps/unix/sysv/linux/s390/Makefile b/sysdeps/unix/sysv/linux/s390/Makefile
index 77f38523b5..d9db1b5422 100644
--- a/sysdeps/unix/sysv/linux/s390/Makefile
+++ b/sysdeps/unix/sysv/linux/s390/Makefile
@@ -11,10 +11,6 @@ ifeq ($(subdir),stdlib)
 gen-as-const-headers += ucontext_i.sym
 endif
 
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
-
 ifeq ($(subdir),nptl)
 libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
       elision-trylock
diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile
index fb3ee5b8a1..b0d182a439 100644
--- a/sysdeps/unix/sysv/linux/sparc/Makefile
+++ b/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -7,10 +7,6 @@ librt-routines += rt-sysdep
 librt-shared-only-routines += rt-sysdep
 endif
 
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
-
 ifeq ($(subdir),sysvipc)
 sysdep_routines += getshmlba
 endif
diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h b/sysdeps/unix/sysv/linux/sysdep-vdso.h
index 76a211e39b..772313f97e 100644
--- a/sysdeps/unix/sysv/linux/sysdep-vdso.h
+++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h
@@ -19,8 +19,7 @@
 #ifndef SYSDEP_VDSO_LINUX_H
 # define SYSDEP_VDSO_LINUX_H
 
-#include <dl-vdso.h>
-#include <libc-vdso.h>
+#include <ldsodefs.h>
 
 #ifndef INTERNAL_VSYSCALL_CALL
 # define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)      \
@@ -34,8 +33,7 @@
     INTERNAL_SYSCALL_DECL (sc_err);      \
     long int sc_ret;      \
       \
-    __typeof (__vdso_##name) vdsop = __vdso_##name;      \
-    PTR_DEMANGLE (vdsop);      \
+    __typeof (GLRO(dl_vdso_##name)) vdsop = GLRO(dl_vdso_##name);      \
     if (vdsop != NULL)      \
       {      \
  sc_ret = INTERNAL_VSYSCALL_CALL (vdsop, sc_err, nr, ##args);      \
diff --git a/sysdeps/unix/sysv/linux/time.c b/sysdeps/unix/sysv/linux/time.c
index 0598958c9c..a7e4cbeb96 100644
--- a/sysdeps/unix/sysv/linux/time.c
+++ b/sysdeps/unix/sysv/linux/time.c
@@ -25,6 +25,7 @@
 
 #ifdef SHARED
 # include <dl-vdso.h>
+# include <libc-vdso.h>
 
 static time_t
 time_syscall (time_t *t)
@@ -34,7 +35,7 @@ time_syscall (time_t *t)
 
 # undef INIT_ARCH
 # define INIT_ARCH() \
-  void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL);
+  void *vdso_time = dl_vdso_vsym (HAVE_TIME_VSYSCALL);
 libc_ifunc (time,
     vdso_time ? VDSO_IFUNC_RET (vdso_time)
       : (void *) time_syscall);
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index 02ca36c6d2..b23b532590 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -20,10 +20,6 @@ CFLAGS-elision-timed.c += -mrtm
 CFLAGS-elision-trylock.c += -mrtm
 endif
 
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
-
 ifeq ($(subdir),setjmp)
 tests += tst-saved_mask-1
 endif
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v2 10/16] linux: Add support for clock_gettime64 vDSO

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
Changes from previous version:

  - Rename HAVE_CLOCK_GETTIME_VSYSCALL to
    HAVE_CLOCK_GETTIME64_VSYSCALL on 64 bit time_t architectures.

--

No architecture currently defines the vDSO symbol.  On archictures
with 64-bit time_t the HAVE_CLOCK_GETTIME_VSYSCALL is renamed to
HAVE_CLOCK_GETTIME64_VSYSCALL, it simplifies clock_gettime code.
---
 sysdeps/unix/sysv/linux/aarch64/sysdep.h |  2 +-
 sysdeps/unix/sysv/linux/clock_gettime.c  | 19 +++++++++++--------
 sysdeps/unix/sysv/linux/dl-vdso-setup.c  |  4 ++++
 sysdeps/unix/sysv/linux/dl-vdso-setup.h  |  3 +++
 sysdeps/unix/sysv/linux/powerpc/sysdep.h |  4 ++++
 sysdeps/unix/sysv/linux/riscv/sysdep.h   |  2 +-
 sysdeps/unix/sysv/linux/s390/sysdep.h    |  4 ++++
 sysdeps/unix/sysv/linux/sparc/sysdep.h   |  6 +++++-
 sysdeps/unix/sysv/linux/x86_64/sysdep.h  |  2 +-
 9 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 53b515aab6..26aa2f9779 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -161,7 +161,7 @@
 
 /* List of system calls which are supported as vsyscalls.  */
 # define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
-# define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
+# define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday"
 
 /* Previously AArch64 used the generic version without the libc_hidden_def
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index e895812704..9be1f779e3 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -30,21 +30,24 @@ int
 __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 {
 #ifdef __ASSUME_TIME64_SYSCALLS
-  /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
-# ifdef __NR_clock_gettime64
-  return INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
+  /* 64 bit ABIs or newer 32-bit ABIs that only support 64-bit time_t.  */
+# ifndef __NR_clock_gettime64
+#  define __NR_clock_gettime64 __NR_clock_gettime
+# endif
+# ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
+  return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
 # else
-#  ifdef HAVE_CLOCK_GETTIME_VSYSCALL
-  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
-#  else
-  return INLINE_SYSCALL_CALL (clock_gettime, clock_id, tp);
-#  endif
+  return INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
 # endif
 #else
   int r;
   /* Old 32-bit ABI with possible 64-bit time_t support.  */
 # ifdef __NR_clock_gettime64
+#  ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
+  r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
+#  else
   r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
+#  endif
   if (r == 0 || errno != ENOSYS)
     return r;
 # endif
diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.c b/sysdeps/unix/sysv/linux/dl-vdso-setup.c
index 1069879f1a..b0b692f78c 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso-setup.c
+++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.c
@@ -45,6 +45,10 @@
 PROCINFO_CLASS int (*_dl_vdso_clock_gettime) (clockid_t,
       struct timespec *) RELRO;
 #endif
+# ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
+PROCINFO_CLASS int (*_dl_vdso_clock_gettime64) (clockid_t,
+ struct __timespec64 *) RELRO;
+#endif
 # ifdef HAVE_GETTIMEOFDAY_VSYSCALL
 PROCINFO_CLASS int (*_dl_vdso_gettimeofday) (struct timeval *, void *) RELRO;
 #endif
diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.h b/sysdeps/unix/sysv/linux/dl-vdso-setup.h
index f4e76202fc..8a89e100c8 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso-setup.h
+++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.h
@@ -26,6 +26,9 @@ setup_vdso_pointers (void)
 #ifdef HAVE_CLOCK_GETTIME_VSYSCALL
   GLRO(dl_vdso_clock_gettime) = dl_vdso_vsym (HAVE_CLOCK_GETTIME_VSYSCALL);
 #endif
+#ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
+  GLRO(dl_vdso_clock_gettime64) = dl_vdso_vsym (HAVE_CLOCK_GETTIME64_VSYSCALL);
+#endif
 #ifdef HAVE_GETTIMEOFDAY_VSYSCALL
   GLRO(dl_vdso_gettimeofday) = dl_vdso_vsym (HAVE_GETTIMEOFDAY_VSYSCALL);
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index a29f286ad7..c42659a9c4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -21,7 +21,11 @@
 
 /* List of system calls which are supported as vsyscalls.  */
 #define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
+#if defined(__PPC64__) || defined(__powerpc64__)
+#define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime"
+#else
 #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
+#endif
 #define HAVE_GETCPU_VSYSCALL "__kernel_getcpu"
 #define HAVE_TIME_VSYSCALL "__kernel_time"
 #define HAVE_GETTIMEOFDAY_VSYSCALL      "__kernel_gettimeofday"
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
index bfbcf60feb..7f43595cb0 100644
--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -126,7 +126,7 @@
 
 /* List of system calls which are supported as vsyscalls.  */
 # define HAVE_CLOCK_GETRES_VSYSCALL "__vdso_clock_getres"
-# define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime"
+# define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
 # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
 
diff --git a/sysdeps/unix/sysv/linux/s390/sysdep.h b/sysdeps/unix/sysv/linux/s390/sysdep.h
index 97d78e246c..030bd59ad0 100644
--- a/sysdeps/unix/sysv/linux/s390/sysdep.h
+++ b/sysdeps/unix/sysv/linux/s390/sysdep.h
@@ -21,6 +21,10 @@
 
 /* List of system calls which are supported as vsyscalls.  */
 #define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
+#ifdef __s390x__
+#define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime"
+#else
 #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
+#endif
 #define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday"
 #define HAVE_GETCPU_VSYSCALL "__kernel_getcpu"
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h
index f38144c912..739f361384 100644
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h
@@ -45,7 +45,11 @@
 # define VDSO_HASH  61765110
 
 /* List of system calls which are supported as vsyscalls.  */
-# define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime"
+# ifdef __arch64__
+#  define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
+# else
+#  define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
+# endif
 # define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
 
 #undef INLINE_SYSCALL
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 965fd4b851..57a64dce31 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -374,7 +374,7 @@
 # define VDSO_HASH  61765110
 
 /* List of system calls which are supported as vsyscalls.  */
-# define HAVE_CLOCK_GETTIME_VSYSCALL    "__vdso_clock_gettime"
+# define HAVE_CLOCK_GETTIME64_VSYSCALL  "__vdso_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL     "__vdso_gettimeofday"
 # define HAVE_TIME_VSYSCALL             "__vdso_time"
 # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 11/16] linux: Optimize fallback 32-bit clock_gettime

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
This patch avoid probing the __NR_clock_getttime64 syscall each time
__clock_gettime64 is issued on a kernel without 64 bit time support.
Once ENOSYS is obtained, only 32-bit clock_gettime are used.

The following snippet:

  clock_gettime (CLOCK_REALTIME, &(struct timespec) { 0 });
  clock_gettime (CLOCK_MONOTONIC, &(struct timespec) { 0 });
  clock_gettime (CLOCK_BOOTTIME, &(struct timespec) { 0 });
  clock_gettime (20, &(struct timespec) { 0 });

On a kernel without 64 bit time support and with vDSO support results
on the following syscalls:

  syscall_0x193(0, 0xff87ba30, [...]) = -1 ENOSYS (Function not implemented)
  clock_gettime(CLOCK_BOOTTIME, {tv_sec=927082, tv_nsec=474382032}) = 0
  clock_gettime(0x14 /* CLOCK_??? */, 0xff87b9f8) = -1 EINVAL (Invalid argument)

While on a kernel without vDSO support:

  syscall_0x193(0, 0xbec95550, 0xb6ed2000, 0x1, 0xbec95550, 0) = -1 (errno 38)
  clock_gettime(CLOCK_REALTIME, {tv_sec=1576615930, tv_nsec=638250162}) = 0
  clock_gettime(CLOCK_MONOTONIC, {tv_sec=1665478, tv_nsec=638779620}) = 0
  clock_gettime(CLOCK_BOOTTIME, {tv_sec=1675418, tv_nsec=292932704}) = 0
  clock_gettime(0x14 /* CLOCK_??? */, 0xbec95530) = -1 EINVAL (Invalid argument)

Checked on i686-linux-gnu on 4.15 kernel.
---
 sysdeps/unix/sysv/linux/clock_gettime.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 9be1f779e3..2a8ad0acc5 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -43,13 +43,21 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
   int r;
   /* Old 32-bit ABI with possible 64-bit time_t support.  */
 # ifdef __NR_clock_gettime64
+  /* Avoid issue a __NR_clock_gettime64 syscall on kernels that do not
+     support 64-bit time_t.  */
+  static int time64_support = 1;
+  if (atomic_load_relaxed (&time64_support) == 1)
+    {
 #  ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
-  r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
+      r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
 #  else
-  r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
+      r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
 #  endif
-  if (r == 0 || errno != ENOSYS)
-    return r;
+      if (r == 0 || errno != ENOSYS)
+ return r;
+
+      atomic_store_relaxed (&time64_support, 0);
+    }
 # endif
   /* Fallback code that uses 32-bit support.  */
   struct timespec tp32;
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 12/16] linux: Enable vDSO clock_gettime64 for i386

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
It was added on Linux 5.3 (commit 22ca962288c0a).

Checked on i686-linux-gnu with 5.3.0 kernel.
---
 sysdeps/unix/sysv/linux/i386/sysdep.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index b2e750d490..5156587d95 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -314,6 +314,7 @@ struct libc_do_syscall_args
 
 /* List of system calls which are supported as vsyscalls.  */
 # define HAVE_CLOCK_GETTIME_VSYSCALL    "__vdso_clock_gettime"
+# define HAVE_CLOCK_GETTIME64_VSYSCALL  "__vdso_clock_gettime64"
 # define HAVE_GETTIMEOFDAY_VSYSCALL     "__vdso_gettimeofday"
 # define HAVE_TIME_VSYSCALL             "__vdso_time"
 # define HAVE_CLOCK_GETRES_VSYSCALL     "__vdso_clock_getres"
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 13/16] linux: Enable vDSO clock_gettime64 for arm

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
It was added on Linux 5.5 (commit 74d06efb9c2f9).
---
 sysdeps/unix/sysv/linux/arm/sysdep.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h
index e9e022e037..b5ef17d1a8 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -393,6 +393,7 @@ __local_syscall_error: \
 
 /* List of system calls which are supported as vsyscalls.  */
 #define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime"
+#define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime64"
 #define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
 
 #define LOAD_ARGS_0()
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 14/16] linux: Enable vDSO clock_gettime64 for mips

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
It was added on Linux 5.4 (commit 1f66c45db3302).
---
 sysdeps/unix/sysv/linux/mips/sysdep.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sysdeps/unix/sysv/linux/mips/sysdep.h b/sysdeps/unix/sysv/linux/mips/sysdep.h
index c2bec03806..67a2f74df2 100644
--- a/sysdeps/unix/sysv/linux/mips/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/sysdep.h
@@ -16,11 +16,16 @@
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sgidefs.h>
+
 #define VDSO_NAME  "LINUX_2.6"
 #define VDSO_HASH  61765110
 
 /* List of system calls which are supported as vsyscalls.  */
 #define HAVE_CLOCK_GETTIME_VSYSCALL     "__vdso_clock_gettime"
+#if _MIPS_SIM != _ABI64
+#define HAVE_CLOCK_GETTIME64_VSYSCALL   "__vdso_clock_gettime64"
+#endif
 #define HAVE_GETTIMEOFDAY_VSYSCALL      "__vdso_gettimeofday"
 #define HAVE_CLOCK_GETRES_VSYSCALL      "__vdso_clock_getres"
 
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH v2 15/16] linux: Add support for clock_getres64 vDSO

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
Changes from previous version:

  - Rename HAVE_CLOCK_GETTIME_VSYSCALL to
    HAVE_CLOCK_GETTIME64_VSYSCALL on 64 bit time_t architectures.

--

No architecture currently defines the vDSO symbol.  On archictures
with 64-bit time_t the HAVE_CLOCK_GETRES_VSYSCALL is renamed to
HAVE_CLOCK_GETRES64_VSYSCALL, it simplifies clock_gettime code.
---
 sysdeps/unix/sysv/linux/aarch64/sysdep.h |  2 +-
 sysdeps/unix/sysv/linux/clock_getres.c   | 17 ++++++++++-------
 sysdeps/unix/sysv/linux/dl-vdso-setup.c  |  4 ++++
 sysdeps/unix/sysv/linux/dl-vdso-setup.h  |  3 +++
 sysdeps/unix/sysv/linux/powerpc/sysdep.h |  3 ++-
 sysdeps/unix/sysv/linux/riscv/sysdep.h   |  2 +-
 sysdeps/unix/sysv/linux/s390/sysdep.h    |  3 ++-
 sysdeps/unix/sysv/linux/x86_64/sysdep.h  |  2 +-
 8 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 26aa2f9779..f50b3f95b9 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -160,7 +160,7 @@
 # endif
 
 /* List of system calls which are supported as vsyscalls.  */
-# define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
+# define HAVE_CLOCK_GETRES64_VSYSCALL "__kernel_clock_getres"
 # define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday"
 
diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 52671fa641..3d59f11d71 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -30,20 +30,23 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 {
 #ifdef __ASSUME_TIME64_SYSCALLS
   /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
-# ifdef __NR_clock_getres_time64
-  return INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
+# ifndef __NR_clock_getres_time64
+#  define __NR_clock_getres_time64 __NR_clock_getres
+# endif
+# ifdef HAVE_CLOCK_GETRES64_VSYSCALL
+  return INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
 # else
-#  ifdef HAVE_CLOCK_GETRES_VSYSCALL
-  return INLINE_VSYSCALL (clock_getres, 2, clock_id, res);
-#  else
-  return INLINE_SYSCALL_CALL (clock_getres, clock_id, res);
-#  endif
+  return INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
 # endif
 #else
   int r;
   /* Old 32-bit ABI with possible 64-bit time_t support.  */
 # ifdef __NR_clock_getres_time64
+#  ifdef HAVE_CLOCK_GETRES64_VSYSCALL
+  r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
+#  else
   r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
+#  endif
   if (r == 0 || errno != ENOSYS)
     return r;
 # endif
diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.c b/sysdeps/unix/sysv/linux/dl-vdso-setup.c
index b0b692f78c..594316342a 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso-setup.c
+++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.c
@@ -62,6 +62,10 @@ PROCINFO_CLASS int (*_dl_vdso_getcpu) (unsigned *, unsigned *, void *) RELRO;
 PROCINFO_CLASS int (*_dl_vdso_clock_getres) (clockid_t,
      struct timespec *) RELRO;
 # endif
+# ifdef HAVE_CLOCK_GETRES64_VSYSCALL
+PROCINFO_CLASS int (*_dl_vdso_clock_getres_time64) (clockid_t,
+    struct __timespec64 *) RELRO;
+# endif
 
 /* PowerPC specific ones.  */
 # ifdef HAVE_GET_TBFREQ
diff --git a/sysdeps/unix/sysv/linux/dl-vdso-setup.h b/sysdeps/unix/sysv/linux/dl-vdso-setup.h
index 8a89e100c8..036f62b1c4 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso-setup.h
+++ b/sysdeps/unix/sysv/linux/dl-vdso-setup.h
@@ -41,6 +41,9 @@ setup_vdso_pointers (void)
 #ifdef HAVE_CLOCK_GETRES_VSYSCALL
   GLRO(dl_vdso_clock_getres) = dl_vdso_vsym (HAVE_CLOCK_GETRES_VSYSCALL);
 #endif
+#ifdef HAVE_CLOCK_GETRES64_VSYSCALL
+  GLRO(dl_vdso_clock_getres_time64) = dl_vdso_vsym (HAVE_CLOCK_GETRES64_VSYSCALL);
+#endif
 #ifdef HAVE_GET_TBFREQ
   GLRO(dl_vdso_get_tbfreq) = dl_vdso_vsym (HAVE_GET_TBFREQ);
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index c42659a9c4..d36aa6dbcb 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -20,10 +20,11 @@
 #define VDSO_HASH  123718565
 
 /* List of system calls which are supported as vsyscalls.  */
-#define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
 #if defined(__PPC64__) || defined(__powerpc64__)
+#define HAVE_CLOCK_GETRES64_VSYSCALL "__kernel_clock_getres"
 #define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime"
 #else
+#define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
 #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
 #endif
 #define HAVE_GETCPU_VSYSCALL "__kernel_getcpu"
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
index 7f43595cb0..201bf9a91b 100644
--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -125,7 +125,7 @@
 # define VDSO_HASH  182943605
 
 /* List of system calls which are supported as vsyscalls.  */
-# define HAVE_CLOCK_GETRES_VSYSCALL "__vdso_clock_getres"
+# define HAVE_CLOCK_GETRES64_VSYSCALL "__vdso_clock_getres"
 # define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
 # define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
 # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
diff --git a/sysdeps/unix/sysv/linux/s390/sysdep.h b/sysdeps/unix/sysv/linux/s390/sysdep.h
index 030bd59ad0..2df5705050 100644
--- a/sysdeps/unix/sysv/linux/s390/sysdep.h
+++ b/sysdeps/unix/sysv/linux/s390/sysdep.h
@@ -20,10 +20,11 @@
 #define VDSO_HASH  123718585
 
 /* List of system calls which are supported as vsyscalls.  */
-#define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
 #ifdef __s390x__
+#define HAVE_CLOCK_GETRES64_VSYSCALL "__kernel_clock_getres"
 #define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime"
 #else
+#define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
 #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
 #endif
 #define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday"
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 57a64dce31..8a699de6b7 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -378,7 +378,7 @@
 # define HAVE_GETTIMEOFDAY_VSYSCALL     "__vdso_gettimeofday"
 # define HAVE_TIME_VSYSCALL             "__vdso_time"
 # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
-# define HAVE_CLOCK_GETRES_VSYSCALL     "__vdso_clock_getres"
+# define HAVE_CLOCK_GETRES64_VSYSCALL   "__vdso_clock_getres"
 
 # define SINGLE_THREAD_BY_GLOBAL 1
 
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 16/16] linux: Optimize fallback 32-bit clock_getres

Adhemerval Zanella-2
In reply to this post by Adhemerval Zanella-2
This patch avoid probing the __NR_clock_getttime64 syscall each time
__clock_gettime64 is issued on a kernel without 64 bit time support.
Once ENOSYS is obtained, only 32-bit clock_gettime are used.

The following snippet:

  clock_getres (CLOCK_REALTIME, &(struct timespec) { 0 });
  clock_getres (CLOCK_MONOTONIC, &(struct timespec) { 0 });
  clock_getres (CLOCK_BOOTTIME, &(struct timespec) { 0 });
  clock_getres (20, &(struct timespec) { 0 });

On a kernel without 64 bit time support issues the syscalls:

  syscall_0x196(0, 0xffb83330, [...]) = -1 ENOSYS (Function not implemented)
  clock_getres(CLOCK_REALTIME, {tv_sec=0, tv_nsec=1}) = 0
  clock_getres(CLOCK_MONOTONIC, {tv_sec=0, tv_nsec=1}) = 0
  clock_getres(CLOCK_BOOTTIME, {tv_sec=0, tv_nsec=1}) = 0

Checked on i686-linux-gnu on 4.15 kernel.
---
 sysdeps/unix/sysv/linux/clock_getres.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 3d59f11d71..c1e1cf60c6 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -42,13 +42,21 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
   int r;
   /* Old 32-bit ABI with possible 64-bit time_t support.  */
 # ifdef __NR_clock_getres_time64
+  /* Avoid issue a __NR_clock_getres_time64 syscall on kernels that do not
+     support 64-bit time_t.  */
+  static int time64_support = 1;
+  if (atomic_load_relaxed (&time64_support) == 1)
+    {
 #  ifdef HAVE_CLOCK_GETRES64_VSYSCALL
-  r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
+      r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
 #  else
-  r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
+      r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
 #  endif
-  if (r == 0 || errno != ENOSYS)
-    return r;
+      if (r == 0 || errno != ENOSYS)
+ return r;
+
+      atomic_store_relaxed (&time64_support, 0);
+    }
 # endif
   /* Fallback code that uses 32-bit support.  */
   struct timespec ts32;
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 06/16] linux: Consolidate Linux gettimeofday

Andreas Schwab
In reply to this post by Adhemerval Zanella-2
On Dez 17 2019, Adhemerval Zanella wrote:

> diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
> new file mode 100644
> index 0000000000..600da6b468
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/gettimeofday.c
> @@ -0,0 +1,57 @@
> +/* gettimeofday - set time.  Linux 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
> +   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/>.  */
> +
> +/* Some architecture might optimize the gettimeofday by setting the plt direct
> +   to vDSO symbol by using a IFUNC.  */
> +#ifdef USE_IFUNC_GETTIMEOFDAY
> +# include <time.h>
> +# include <sysdep.h>
> +# include <sysdep-vdso.h>

I think you want to include <string.h> for memset.

Andreas.

--
Andreas Schwab, SUSE Labs, [hidden email]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 11/16] linux: Optimize fallback 32-bit clock_gettime

Andreas Schwab
In reply to this post by Adhemerval Zanella-2
On Dez 17 2019, Adhemerval Zanella wrote:

> diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
> index 9be1f779e3..2a8ad0acc5 100644
> --- a/sysdeps/unix/sysv/linux/clock_gettime.c
> +++ b/sysdeps/unix/sysv/linux/clock_gettime.c
> @@ -43,13 +43,21 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
>    int r;
>    /* Old 32-bit ABI with possible 64-bit time_t support.  */
>  # ifdef __NR_clock_gettime64
> +  /* Avoid issue a __NR_clock_gettime64 syscall on kernels that do not
> +     support 64-bit time_t.  */
> +  static int time64_support = 1;
> +  if (atomic_load_relaxed (&time64_support) == 1)

Just != 0 should be enough.

Andreas.

--
Andreas Schwab, SUSE Labs, [hidden email]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 16/16] linux: Optimize fallback 32-bit clock_getres

Andreas Schwab
In reply to this post by Adhemerval Zanella-2
On Dez 17 2019, Adhemerval Zanella wrote:

> diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
> index 3d59f11d71..c1e1cf60c6 100644
> --- a/sysdeps/unix/sysv/linux/clock_getres.c
> +++ b/sysdeps/unix/sysv/linux/clock_getres.c
> @@ -42,13 +42,21 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
>    int r;
>    /* Old 32-bit ABI with possible 64-bit time_t support.  */
>  # ifdef __NR_clock_getres_time64
> +  /* Avoid issue a __NR_clock_getres_time64 syscall on kernels that do not
> +     support 64-bit time_t.  */
> +  static int time64_support = 1;
> +  if (atomic_load_relaxed (&time64_support) == 1)

Just != 0 should be enough.

Andreas.

--
Andreas Schwab, SUSE Labs, [hidden email]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 06/16] linux: Consolidate Linux gettimeofday

Adhemerval Zanella-2
In reply to this post by Andreas Schwab


On 18/12/2019 05:46, Andreas Schwab wrote:

> On Dez 17 2019, Adhemerval Zanella wrote:
>
>> diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
>> new file mode 100644
>> index 0000000000..600da6b468
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/gettimeofday.c
>> @@ -0,0 +1,57 @@
>> +/* gettimeofday - set time.  Linux 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
>> +   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/>.  */
>> +
>> +/* Some architecture might optimize the gettimeofday by setting the plt direct
>> +   to vDSO symbol by using a IFUNC.  */
>> +#ifdef USE_IFUNC_GETTIMEOFDAY
>> +# include <time.h>
>> +# include <sysdep.h>
>> +# include <sysdep-vdso.h>
>
> I think you want to include <string.h> for memset.
>
> Andreas.
>

Ack.
123