]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
elf: Move vDSO setup to rtld (BZ#24967)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 29 Nov 2019 13:44:59 +0000 (10:44 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 3 Jan 2020 14:22:07 +0000 (11:22 -0300)
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.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
31 files changed:
csu/init-first.c
elf/dl-support.c
elf/rtld.c
malloc/tst-interpose-aux.c
sysdeps/generic/dl-vdso-setup.c [new file with mode: 0644]
sysdeps/generic/dl-vdso-setup.h [new file with mode: 0644]
sysdeps/generic/dl-vdso.h [new file with mode: 0644]
sysdeps/generic/ldsodefs.h
sysdeps/powerpc/powerpc32/backtrace.c
sysdeps/powerpc/powerpc64/backtrace.c
sysdeps/unix/sysv/linux/aarch64/Makefile
sysdeps/unix/sysv/linux/arm/Makefile
sysdeps/unix/sysv/linux/dl-vdso-setup.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/dl-vdso-setup.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/dl-vdso.c [deleted file]
sysdeps/unix/sysv/linux/dl-vdso.h
sysdeps/unix/sysv/linux/gettimeofday.c
sysdeps/unix/sysv/linux/init-first.c [deleted file]
sysdeps/unix/sysv/linux/libc-vdso.h
sysdeps/unix/sysv/linux/mips/Makefile
sysdeps/unix/sysv/linux/powerpc/Makefile
sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
sysdeps/unix/sysv/linux/powerpc/init-first.c [deleted file]
sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
sysdeps/unix/sysv/linux/riscv/Makefile
sysdeps/unix/sysv/linux/riscv/flush-icache.c
sysdeps/unix/sysv/linux/s390/Makefile
sysdeps/unix/sysv/linux/sparc/Makefile
sysdeps/unix/sysv/linux/sysdep-vdso.h
sysdeps/unix/sysv/linux/time.c
sysdeps/unix/sysv/linux/x86/Makefile

index 669b779b703837594d931d8a95617b3efad086a1..1cd8a75098547ec30def6fb01521b901712ad8c2 100644 (file)
@@ -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.  */
index 508a5c1196dbb5c613ecd85b93139f2a19a1542b..ad791ab6abe6612a20ab1d7e39b7d7683424e2a7 100644 (file)
@@ -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"));
index 817fb86eacc98748af8056cb84bb08c2ef00a566..553cfbd1b74e05467e3c30e291f694ce40c4b0f4 100644 (file)
@@ -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
index 52696e92d372a8fb9fa698c509ef6da2ffe9e8dc..a0ab2e5903ee3872083eb19a029f2939b8b218a2 100644 (file)
@@ -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 (file)
index 0000000..6e25b02
--- /dev/null
@@ -0,0 +1 @@
+/* Empty.  */
diff --git a/sysdeps/generic/dl-vdso-setup.h b/sysdeps/generic/dl-vdso-setup.h
new file mode 100644 (file)
index 0000000..5ef7531
--- /dev/null
@@ -0,0 +1,28 @@
+/* ELF symbol initialization functions for VDSO objects.
+   Copyright (C) 2020 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 (file)
index 0000000..70379a8
--- /dev/null
@@ -0,0 +1,30 @@
+/* ELF symbol resolve functions for VDSO objects.
+   Copyright (C) 2020 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
index 0a5d3473f54448e971e8d1274f23aac403a7f790..497938ffa202ef260d942d153159a97550ac7fa1 100644 (file)
@@ -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
index 4a355886715cf3035622516e91cfe81c54ffe5e8..7c2d4726f8b76ce969cc6954f427d3cdcc2b74c5 100644 (file)
@@ -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
index ee8ba21f27ebd73740fc45841278b40be6fda3e8..65c260ab764c9c78d6805d3f5ad919682f1457c4 100644 (file)
@@ -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
index 57bbfeaac6a1f08f1faa9fe191dc0980992e4b9a..4bcae85bcac4ce21ad825bd36bf399e3aa91f782 100644 (file)
@@ -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.
index d7a2f6a8a7296052a2f1c311724e2573f19dbce4..abdf01f00c760b864d8a5984c94c937361cded63 100644 (file)
@@ -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 (file)
index 0000000..352fcae
--- /dev/null
@@ -0,0 +1,81 @@
+/* Data for vDSO support.  Linux version.
+   Copyright (C) 2020 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 (file)
index 0000000..9f5e4a3
--- /dev/null
@@ -0,0 +1,55 @@
+/* ELF symbol initialization functions for VDSO objects.  Linux version.
+   Copyright (C) 2020 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 (file)
index 08aefde..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ELF symbol resolve functions for VDSO objects.
-   Copyright (C) 2005-2020 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;
-}
index 4fe6fe1d1041617bd13a22875c11c3d3a47e51ea..12051b98e1f5fe7785956edb391522ac6ae4a14c 100644 (file)
 #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 */
index 80d6819e5aef00a79d5ed535c3a0f0f523593135..d5cdb224950e9254cbe568981f1de7179dcb1c5f 100644 (file)
@@ -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 (file)
index a215a1b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* vDSO internal symbols.  Linux generic version.
-   Copyright (C) 2019-2020 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>
index 1d7af16be8422fa8ff2ab9a5df3082d896a500aa..31ceafe9d8c0997cc23178ea155fca7ec8ad5a8e 100644 (file)
 #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 */
index 03044e73650eff5d2ff2706a8b633a02e15c64a3..026ba242cf0a1a9eb26ff9e9dbfd4860028c8973 100644 (file)
@@ -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.
index 1596238afa033e6e2808a16a127b43c7f2f06856..cc2f804d86b37f97c7e2a7de1e93a08cff57cd4b 100644 (file)
@@ -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
index ebd0d2f8808680e0647e95d377d2729d3d0bf265..81f7c73f3879942cdbf8bed56e9b794c97240f24 100644 (file)
@@ -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 (file)
index d20938c..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Initialization code run first thing by the ELF startup code.  Linux/PowerPC.
-   Copyright (C) 2007-2020 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>
index 2f18a762d8aa2ac2157efe8574ab443f480cbeda..8dae14057cd7cb9c8929fa085c389c7e560798a8 100644 (file)
 # 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 */
index b7ad31885c450245fb469196a92401f4fa4e8259..301b08239861b1898ca931b1b6d896c76a54e107 100644 (file)
@@ -1,7 +1,3 @@
-ifeq ($(subdir),elf)
-sysdep_routines        += dl-vdso
-endif
-
 ifeq ($(subdir),misc)
 sysdep_headers += sys/cachectl.h
 sysdep_routines += flush-icache
index f1565ab2dd273d797f580b7b414b4cf086c2ddd4..72caeb190f0f03876c1555deb6318158bcb9b51c 100644 (file)
@@ -39,7 +39,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
index 77f38523b5febbf7cfdabbb1608869050818ee6f..d9db1b54227be7fd8e6daac669220a97ab3bcf5a 100644 (file)
@@ -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
index fb3ee5b8a1e0d90a2b082dfbd3727e13c3249c74..b0d182a439ed6dc051603a8768107f265c33569e 100644 (file)
@@ -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
index f0cc384d78a12bf25aa70fff3cacebdba9b61956..dc6eaddbbf4a7689e45ec0a1c1eec94527f76e9b 100644 (file)
@@ -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);          \
index 2dc4cbe786d2d2fbe36348345935dc4df5191486..9d8e573c0a99dc7191d803379248e713320043d7 100644 (file)
@@ -24,6 +24,7 @@
 
 #ifdef SHARED
 # include <dl-vdso.h>
+# include <libc-vdso.h>
 
 static time_t
 time_syscall (time_t *t)
@@ -33,7 +34,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);
index 02ca36c6d26c51edbeab6399db8e5901f7f54806..b23b532590dcdeab6a2303bc45cef70a4ae37a84 100644 (file)
@@ -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