[v3,09/16] elf: Move vDSO setup to rtld (BZ#24967)
Commit Message
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
Comments
On 18/12/19 3:17 am, Adhemerval Zanella wrote:
> 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
>
OK with some minor nits fixed, see below.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
> 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.
Update copyright year.
> + 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.
Update copyright year.
> + 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.
Update copyright year.
> + 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
Fix indentation.
> +# ifdef HAVE_GETTIMEOFDAY_VSYSCALL
> +PROCINFO_CLASS int (*_dl_vdso_gettimeofday) (struct timeval *, void *) RELRO;
> +#endif
Fix indentation.
> +# 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.
Update copyright year.
> + 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
>
On 02/01/2020 09:55, Siddhesh Poyarekar wrote:
> On 18/12/19 3:17 am, Adhemerval Zanella wrote:
>> 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
>>
>
> OK with some minor nits fixed, see below.
>
> Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
>> 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.
>
> Update copyright year.
Ack.
>
>> + 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.
>
> Update copyright year.
Ack.
>> 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.
>
> Update copyright year.
Ack.
>
>> + 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
>
> Fix indentation.
Ack.
>
>> +# ifdef HAVE_GETTIMEOFDAY_VSYSCALL
>> +PROCINFO_CLASS int (*_dl_vdso_gettimeofday) (struct timeval *, void *) RELRO;
>> +#endif
>
> Fix indentation.
Ack.
Hi Adhemerval, Siddhesh
> On 02/01/2020 09:55, Siddhesh Poyarekar wrote:
> > On 18/12/19 3:17 am, Adhemerval Zanella wrote:
> >> 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
> >>
> >
> > OK with some minor nits fixed, see below.
> >
> > Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
>
> >> 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.
> >
> > Update copyright year.
>
> Ack.
>
> >
> >> + 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.
> >
> > Update copyright year.
>
> Ack.
>
> >> 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.
> >
> > Update copyright year.
>
> Ack.
>
> >
> >> + 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
> >
> > Fix indentation.
>
> Ack.
>
> >
> >> +# ifdef HAVE_GETTIMEOFDAY_VSYSCALL
> >> +PROCINFO_CLASS int (*_dl_vdso_gettimeofday) (struct timeval *,
> >> void *) RELRO; +#endif
> >
> > Fix indentation.
>
> Ack.
Unfortunately this patch caused regression on my ARMv7 32 bit setup.
Please find filled in bugzilla entry:
https://sourceware.org/bugzilla/show_bug.cgi?id=25352
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 07/01/2020 13:13, Lukasz Majewski wrote:
>
> Unfortunately this patch caused regression on my ARMv7 32 bit setup.
> Please find filled in bugzilla entry:
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=25352
Are you sure you are testing it properly? As indicated by Andreas, it
seems a mismatch between ld.so and libc.so. I just setup a debian 9
VM with both a 4.9 and 5.4 kernel and a simple test:
--
#include <time.h>
int main ()
{
clock_gettime (CLOCK_REALTIME, &(struct timespec) {});
clock_gettime (CLOCK_MONOTONIC, &(struct timespec) {});
clock_gettime (CLOCK_BOOTTIME, &(struct timespec) {});
return 0;
}
--
does show the expected results. On 4.9 kernel I am seeing:
15:36:06 syscall_0x193(0, 0xbed9a3d8, 0xc8, 0, 0xbed9a3d8, 0) = -1 ENOSYS (Function not implemented)
15:36:06 clock_gettime(CLOCK_BOOTTIME, {tv_sec=1303, tv_nsec=570795799}) = 0
15:36:06 exit_group(0) = ?
15:36:06 +++ exited with 0 +++
While on a 5.4 kernel:
syscall_0x193(0, 0xbedfb3e8, 0xc8, 0, 0xbedfb3e8, 0) = 0
syscall_0x193(0x1, 0xbedfb3e8, 0xc8, 0, 0xbedfb3e8, 0x1) = 0
syscall_0x193(0x7, 0xbedfb3e8, 0xc8, 0, 0xbedfb3e8, 0x7) = 0
(arm clock_gettime64 vDSO was added on 5.5).
@@ -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. */
@@ -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"));
@@ -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
@@ -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;
}
new file mode 100644
@@ -0,0 +1 @@
+/* Empty. */
new file mode 100644
@@ -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
new file mode 100644
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
@@ -1,5 +1,4 @@
ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
sysdep-rtld-routines += aeabi_read_tp libc-do-syscall
endif
new file mode 100644
@@ -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
new file mode 100644
@@ -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
deleted file mode 100644
@@ -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;
-}
@@ -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 */
@@ -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)
deleted file mode 100644
@@ -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>
@@ -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 */
@@ -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.
@@ -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
@@ -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 ();
deleted file mode 100644
@@ -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>
@@ -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 */
@@ -1,7 +1,3 @@
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
-
ifeq ($(subdir),misc)
sysdep_headers += sys/cachectl.h
sysdep_routines += flush-icache
@@ -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
@@ -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
@@ -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
@@ -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); \
@@ -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);
@@ -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