aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-06-03 10:22:13 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-09-17 17:09:24 -0300
commitb8a7c7da4e228d0f8fb39fdbc1a6cfd33a97a188 (patch)
tree5546878e48aea11ed1b4b5e7195331c8a5e7943b /sysdeps
parentb8386c2859e61c5c80ca98e987665a3179bd7e52 (diff)
downloadglibc-b8a7c7da4e228d0f8fb39fdbc1a6cfd33a97a188.tar.xz
glibc-b8a7c7da4e228d0f8fb39fdbc1a6cfd33a97a188.zip
Refactor vDSO initialization code
Linux vDSO initialization code the internal function pointers require a lot of duplicated boilerplate over different architectures. This patch aims to simplify not only the code but the required definition to enable a vDSO symbol. The changes are: 1. Consolidate all init-first.c on only one implementation and enable the symbol based on HAVE_*_VSYSCALL existence. 2. Set the HAVE_*_VSYSCALL to the architecture expected names string. 3. Add a new internal implementation, get_vdso_mangle_symbol, which returns a mangled function pointer. Currently the clock_gettime, clock_getres, gettimeofday, getcpu, and time are handled in an arch-independent way, powerpc still uses some arch-specific vDSO symbol handled in a specific init-first implementation. Checked on aarch64-linux-gnu, arm-linux-gnueabihf, i386-linux-gnu, mips64-linux-gnu, powerpc64le-linux-gnu, s390x-linux-gnu, sparc64-linux-gnu, and x86_64-linux-gnu. * sysdeps/powerpc/powerpc32/backtrace.c (is_sigtramp_address, is_sigtramp_address_rt): Use HAVE_SIGTRAMP_{RT}32 instead of SHARED. * sysdeps/powerpc/powerpc64/backtrace.c (is_sigtramp_address): Likewise. * sysdeps/unix/sysv/linux/aarch64/init-first.c: Remove file. * sysdeps/unix/sysv/linux/aarch64/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/arm/init-first.c: Likewise. * sysdeps/unix/sysv/linux/arm/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/mips/init-first.c: Likewise. * sysdeps/unix/sysv/linux/mips/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/i386/init-first.c: Likewise. * sysdeps/unix/sysv/linux/riscv/init-first.c: Likewise. * sysdeps/unix/sysv/linux/riscv/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/s390/init-first.c: Likewise. * sysdeps/unix/sysv/linux/s390/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/sparc/init-first.c: Likewise. * sysdeps/unix/sysv/linux/sparc/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/x86/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/init-first.c: Likewise. * sysdeps/unix/sysv/linux/aarch64/sysdep.h (HAVE_CLOCK_GETRES_VSYSCALL, HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL): Define value based on kernel exported name. * sysdeps/unix/sysv/linux/arm/sysdep.h (HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/i386/sysdep.h (HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/mips/sysdep.h (HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/powerpc/sysdep.h (HAVE_CLOCK_GETRES_VSYSCALL, HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETCPU_VSYSCALL, HAVE_TIME_VSYSCALL, HAVE_GET_TBFREQ, HAVE_SIGTRAMP_RT64, HAVE_SIGTRAMP_32, HAVE_SIGTRAMP_RT32i, HAVE_GETTIMEOFDAY_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/riscv/sysdep.h (HAVE_CLOCK_GETRES_VSYSCALL, HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL, HAVE_GETCPU_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/s390/sysdep.h (HAVE_CLOCK_GETRES_VSYSCALL, HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL, HAVE_GETCPU_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/sparc/sysdep.h (HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/x86_64/sysdep.h (HAVE_CLOCK_GETTIME_VSYSCALL, HAVE_GETTIMEOFDAY_VSYSCALL, HAVE_GETCPU_VSYSCALL): Likewise. * sysdeps/unix/sysv/linux/dl-vdso.h (VDSO_NAME, VDSO_HASH): Define to invalid names if architecture does not define them. (get_vdso_mangle_symbol): New symbol. * sysdeps/unix/sysv/linux/init-first.c: New file. * sysdeps/unix/sysv/linux/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/init-first.c (gettimeofday, clock_gettime, clock_getres, getcpu, time): Remove declaration. (__libc_vdso_platform_setup_arch): Likewise and use get_vdso_mangle_symbol to setup vDSO symbols. (sigtramp_rt64, sigtramp32, sigtramp_rt32, get_tbfreq): Add attribute_hidden. * sysdeps/unix/sysv/linux/powerpc/libc-vdso.h: Likewise. * sysdeps/unix/sysv/linux/sysdep-vdso.h (VDSO_SYMBOL): Remove definition.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/powerpc/powerpc32/backtrace.c4
-rw-r--r--sysdeps/powerpc/powerpc64/backtrace.c2
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/gettimeofday.c2
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/init-first.c44
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/sysdep.h6
-rw-r--r--sysdeps/unix/sysv/linux/arm/init-first.c41
-rw-r--r--sysdeps/unix/sysv/linux/arm/libc-vdso.h29
-rw-r--r--sysdeps/unix/sysv/linux/arm/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/dl-vdso.h21
-rw-r--r--sysdeps/unix/sysv/linux/i386/init-first.c46
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/init-first.c80
-rw-r--r--sysdeps/unix/sysv/linux/libc-vdso.h (renamed from sysdeps/unix/sysv/linux/aarch64/libc-vdso.h)28
-rw-r--r--sysdeps/unix/sysv/linux/mips/init-first.c40
-rw-r--r--sysdeps/unix/sysv/linux/mips/libc-vdso.h29
-rw-r--r--sysdeps/unix/sysv/linux/mips/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/gettimeofday.c3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/init-first.c51
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/libc-vdso.h12
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sysdep.h16
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/time.c2
-rw-r--r--sysdeps/unix/sysv/linux/riscv/init-first.c54
-rw-r--r--sysdeps/unix/sysv/linux/riscv/libc-vdso.h34
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sysdep.h8
-rw-r--r--sysdeps/unix/sysv/linux/s390/init-first.c56
-rw-r--r--sysdeps/unix/sysv/linux/s390/libc-vdso.h35
-rw-r--r--sysdeps/unix/sysv/linux/s390/sysdep.h8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/init-first.c42
-rw-r--r--sysdeps/unix/sysv/linux/sparc/libc-vdso.h29
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/sysdep-vdso.h2
-rw-r--r--sysdeps/unix/sysv/linux/x86/libc-vdso.h33
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/init-first.c48
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sysdep.h6
34 files changed, 177 insertions, 650 deletions
diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c
index 971401a405..2e6a859d9f 100644
--- a/sysdeps/powerpc/powerpc32/backtrace.c
+++ b/sysdeps/powerpc/powerpc32/backtrace.c
@@ -54,7 +54,7 @@ struct signal_frame_32 {
static inline int
is_sigtramp_address (void *nip)
{
-#ifdef SHARED
+#ifdef HAVE_SIGTRAMP_RT32
if (nip == VDSO_SYMBOL (sigtramp32))
return 1;
#endif
@@ -71,7 +71,7 @@ struct rt_signal_frame_32 {
static inline int
is_sigtramp_address_rt (void * nip)
{
-#ifdef SHARED
+#ifdef HAVE_SIGTRAMP_32
if (nip == VDSO_SYMBOL (sigtramp_rt32))
return 1;
#endif
diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c
index 8f83093434..234d9c00dc 100644
--- a/sysdeps/powerpc/powerpc64/backtrace.c
+++ b/sysdeps/powerpc/powerpc64/backtrace.c
@@ -57,7 +57,7 @@ struct signal_frame_64 {
static inline int
is_sigtramp_address (void *nip)
{
-#ifdef SHARED
+#ifdef HAVE_SIGTRAMP_RT64
if (nip == VDSO_SYMBOL (sigtramp_rt64))
return 1;
#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
index 1ec98bf161..4ff74fa285 100644
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
@@ -38,7 +38,7 @@ __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
# define INIT_ARCH()
libc_ifunc_hidden (__gettimeofday, __gettimeofday,
- (get_vdso_symbol ("__kernel_gettimeofday")
+ (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
?: __gettimeofday_vsyscall))
libc_hidden_def (__gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/aarch64/init-first.c b/sysdeps/unix/sysv/linux/aarch64/init-first.c
deleted file mode 100644
index 16b28be835..0000000000
--- a/sysdeps/unix/sysv/linux/aarch64/init-first.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* 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>
-
-int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
-int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
-int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
-
-static inline void
-_libc_vdso_platform_setup (void)
-{
- void *p = get_vdso_symbol ("__kernel_gettimeofday");
- PTR_MANGLE (p);
- VDSO_SYMBOL(gettimeofday) = p;
-
- p = get_vdso_symbol ("__kernel_clock_gettime");
- PTR_MANGLE (p);
- VDSO_SYMBOL(clock_gettime) = p;
-
- p = get_vdso_symbol ("__kernel_clock_getres");
- PTR_MANGLE (p);
- VDSO_SYMBOL(clock_getres) = p;
-}
-
-#define VDSO_SETUP _libc_vdso_platform_setup
-
-#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 37d70ca4af..53b515aab6 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -160,9 +160,9 @@
# endif
/* List of system calls which are supported as vsyscalls. */
-# define HAVE_CLOCK_GETRES_VSYSCALL 1
-# define HAVE_CLOCK_GETTIME_VSYSCALL 1
-# define HAVE_GETTIMEOFDAY_VSYSCALL 1
+# define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres"
+# define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime"
+# define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday"
/* Previously AArch64 used the generic version without the libc_hidden_def
which lead in a non existent __send symbol in libc.so. */
diff --git a/sysdeps/unix/sysv/linux/arm/init-first.c b/sysdeps/unix/sysv/linux/arm/init-first.c
deleted file mode 100644
index 56ae7393c4..0000000000
--- a/sysdeps/unix/sysv/linux/arm/init-first.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Initialization code run first thing by the ELF startup code. Linux/ARM.
- Copyright (C) 2015-2019 Free Software Foundation, Inc.
-
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <dl-vdso.h>
-#include <libc-vdso.h>
-#include <sysdep-vdso.h>
-
-int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
-int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
-
-static inline void
-_libc_vdso_platform_setup (void)
-{
- void *p = get_vdso_symbol ("__vdso_gettimeofday");
- PTR_MANGLE (p);
- VDSO_SYMBOL (gettimeofday) = p;
-
- p = get_vdso_symbol ("__vdso_clock_gettime");
- PTR_MANGLE (p);
- VDSO_SYMBOL (clock_gettime) = p;
-}
-
-#define VDSO_SETUP _libc_vdso_platform_setup
-
-#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/arm/libc-vdso.h b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
deleted file mode 100644
index 6b7a825bf1..0000000000
--- a/sysdeps/unix/sysv/linux/arm/libc-vdso.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* VDSO function pointer declarations. Linux/ARM.
- Copyright (C) 2015-2019 Free Software Foundation, Inc.
-
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library. If not, see
- <https://www.gnu.org/licenses/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <sysdep-vdso.h>
-
-extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
- attribute_hidden;
-extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h
index 9eea48de14..f9cc9335f5 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -392,8 +392,8 @@ __local_syscall_error: \
#define VDSO_HASH 61765110
/* List of system calls which are supported as vsyscalls. */
-#define HAVE_CLOCK_GETTIME_VSYSCALL 1
-#define HAVE_GETTIMEOFDAY_VSYSCALL 1
+#define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_gettimeofday"
+#define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_clock_gettime"
#define LOAD_ARGS_0()
#define ASM_ARGS_0
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
index 5e40eac3ee..19ffd30c7e 100644
--- a/sysdeps/unix/sysv/linux/dl-vdso.h
+++ b/sysdeps/unix/sysv/linux/dl-vdso.h
@@ -19,16 +19,25 @@
#ifndef _DL_VDSO_H
#define _DL_VDSO_H 1
-#include <assert.h>
#include <ldsodefs.h>
#include <dl-hash.h>
-#include <libc-vdso.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). */
+
+#ifndef VDSO_NAME
+# define VDSO_NAME "LINUX_0.0"
+#endif
+#ifndef VDSO_HASH
+# define VDSO_HASH 0
+#endif
+
static inline void *
get_vdso_symbol (const char *symbol)
{
@@ -36,4 +45,12 @@ get_vdso_symbol (const char *symbol)
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;
+}
+
#endif /* dl-vdso.h */
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
deleted file mode 100644
index e785664637..0000000000
--- a/sysdeps/unix/sysv/linux/i386/init-first.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Initialization code run first thing by the ELF startup code. Linux/i386.
- Copyright (C) 2015-2019 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <time.h>
-#include <sysdep.h>
-#include <dl-vdso.h>
-#include <sysdep-vdso.h>
-
-long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
- attribute_hidden;
-
-static long int
-clock_gettime_syscall (clockid_t id, struct timespec *tp)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (clock_gettime, err, 2, id, tp);
-}
-
-static inline void
-__vdso_platform_setup (void)
-{
- void *p = get_vdso_symbol ("__vdso_clock_gettime");
- if (p == NULL)
- p = clock_gettime_syscall;
- PTR_MANGLE (p);
- VDSO_SYMBOL (clock_gettime) = p;
-}
-
-#define VDSO_SETUP __vdso_platform_setup
-
-#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index cdba552af7..7066ddc214 100644
--- a/