* [PATCH v2] Add x86 32 bit vDSO time function support
@ 2014-10-09 18:31 Adhemerval Zanella
2014-10-09 20:50 ` Nathan Lynch
0 siblings, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-10-09 18:31 UTC (permalink / raw)
To: GNU C. Library
Hi,
This is a respin of my x86 vDSO cleanup / time support. The new ftime testcase
showed the initial patch was not really generating correct code for internal
ifunc for i386. Similar to a previous bug that was presented in ppc32, linker
creates an incorrect PLT stub for internal __gettimeofday usage. I tried some
binutils (2.23, 2.24, master), but all show the same behavior. x86_64 is ok,
I checked and ftime does call __gettimeofday from vDSO.
I didn't dig into this issue, so if someone with more experience in i386 ABI
could take a look it will helpful. Currently I'm setting the internal
getimeofday for i386 to its syscall version.
Checked on i386 and x86_64 on a 3.10 kernel and on a 3.16 kernel.
--
2014-10-09 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Stefani Seibold <stefani@seibold.net>
* sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
(sysdep_routines): Add dl-vdso here, ...
* sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
(sysdep_routines): ... not here.
* sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: set syscall
fallback when vDSO is not presented.
* sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime):
Define with libc_hidden_proto/libc_hidden_data_def definitions.
(_libc_vdso_platform_setup): Rename to __vdso_platform_setup.
* sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
* sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
* sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
* sysdeps/unix/sysv/linux/x86/libc-vdso.h: ... here.
* sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
* sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
* sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
fallback configurable symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
* sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
be able to redefine fallback symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
* sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
---
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
new file mode 100644
index 0000000..2b58fd5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -0,0 +1,39 @@
+/* gettimeofday - get the time. Linux/i386 version.
+ Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the syscall. */
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+# define GETTIMEOFAY_FALLBACK (void*) (&__gettimeofday_syscall)
+# undef libc_ifunc_hidden_def
+# define libc_ifunc_hidden_def(name) \
+ libc_ifunc_hidden_def1 (__GI_##name, __gettimeofday_syscall)
+
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
new file mode 100644
index 0000000..dc3b1ba
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
@@ -0,0 +1,52 @@
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+ __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
+
+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)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ if (p == NULL)
+ p = clock_gettime_syscall;
+ PTR_MANGLE (p);
+ __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP __vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
new file mode 100644
index 0000000..45b8a50
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -0,0 +1,37 @@
+/* time -- Get number of seconds since Epoch. Linux/i386 version.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the old vsyscall. */
+static time_t
+__time_syscall (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+# define TIME_FALLBACK (void*) &__time_syscall
+# undef libc_ifunc_hidden_def
+# define libc_ifunc_hidden_def(name) \
+ libc_ifunc_hidden_def1 (__GI_##name, __time_syscall)
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index 0281f87..d6be472 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -19,3 +19,7 @@ libpthread-sysdep_routines += init-arch
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
new file mode 100644
index 0000000..2547a8c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
@@ -0,0 +1,38 @@
+/* Get the current value of a clock. Linux/x86 version.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define SYSCALL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ long int v_ret; \
+ PTR_DEMANGLE (f); \
+ v_ret = (*f) (id, tp); \
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
+ v_ret = -1; \
+ } \
+ v_ret; })
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ (*f) (id, tp); })
+#endif
+
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
new file mode 100644
index 0000000..54a3c1f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -0,0 +1,53 @@
+/* gettimeofday - get the time. Linux/x86 version.
+ 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+ ?: GETTIMEOFAY_FALLBACK);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+libc_ifunc_hidden_def(__gettimeofday)
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+libc_hidden_def (__gettimeofday)
+
+#endif
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
new file mode 100644
index 0000000..f291924
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
@@ -0,0 +1,31 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005-2014 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/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
new file mode 100644
index 0000000..f567d12
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -0,0 +1,49 @@
+/* time -- Get number of seconds since Epoch. Linux/x86 version.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#ifdef SHARED
+
+#include <dl-vdso.h>
+
+void *time_ifunc (void) __asm__ ("time");
+
+void *
+time_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
+}
+asm (".type time, %gnu_indirect_function");
+
+libc_ifunc_hidden_def(time)
+
+#else
+
+# include <sysdep.h>
+
+time_t
+time (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
new file mode 100644
index 0000000..4b6d721
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
@@ -0,0 +1,29 @@
+/* timespec_get -- returns the calendar time based on a given time base.
+ Linux/x86 version.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ (*f) (id, tp); })
+#endif
+
+#include <sysdeps/unix/sysv/linux/timespec_get.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index d6a9d36..9b82155 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -13,7 +13,3 @@ endif
ifeq ($(subdir),misc)
gen-as-const-headers += sigaltstack-offsets.sym
endif
-
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
deleted file mode 100644
index f291924..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Resolve function pointers to VDSO functions.
- Copyright (C) 2005-2014 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/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef SHARED
-
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
-
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
deleted file mode 100644
index f712110..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define SYSCALL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- long int v_ret; \
- PTR_DEMANGLE (f); \
- v_ret = f (id, tp); \
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
- v_ret = -1; \
- } \
- v_ret; })
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
index 440ca7f..defefbc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
@@ -18,42 +18,9 @@
#include <sys/time.h>
#ifdef SHARED
-
-# include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
-
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
- let us do it in C because it doesn't know we're defining __gettimeofday
- here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
+# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
index fb090df..827751a 100644
--- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
+++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
@@ -20,20 +20,20 @@
# include <time.h>
# include <sysdep.h>
# include <dl-vdso.h>
-# include <bits/libc-vdso.h>
+# include <libc-vdso.h>
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
__attribute__ ((nocommon));
-strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
-
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
static inline void
-_libc_vdso_platform_setup (void)
+__vdso_platform_setup (void)
{
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
@@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
if (p == NULL)
p = __syscall_clock_gettime;
PTR_MANGLE (p);
- __GI___vdso_clock_gettime = p;
+ __vdso_clock_gettime = p;
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
/* If the vDSO is not available we fall back on the old vsyscall. */
@@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
__vdso_getcpu = p;
}
-# define VDSO_SETUP _libc_vdso_platform_setup
+# define VDSO_SETUP __vdso_platform_setup
#endif
#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
index 79f1fab..ec1393b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
@@ -16,45 +16,9 @@
<http://www.gnu.org/licenses/>. */
#ifdef SHARED
-/* Redefine time so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef time
-#define time __redirect_time
-#include <time.h>
-
-#include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_time) __libc_time;
-void *time_ifunc (void) __asm__ ("__libc_time");
-
-void *
-time_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
-}
-__asm (".type __libc_time, %gnu_indirect_function");
-
-#undef time
-strong_alias (__libc_time, time)
-libc_hidden_ver (__libc_time, time)
-
-#else
-
-# include <time.h>
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
deleted file mode 100644
index cb26068..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../timespec_get.c"
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-10-09 18:31 [PATCH v2] Add x86 32 bit vDSO time function support Adhemerval Zanella
@ 2014-10-09 20:50 ` Nathan Lynch
2014-11-03 20:30 ` Adhemerval Zanella
0 siblings, 1 reply; 27+ messages in thread
From: Nathan Lynch @ 2014-10-09 20:50 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: GNU C. Library
On 10/09/2014 01:31 PM, Adhemerval Zanella wrote:
> diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
> new file mode 100644
> index 0000000..dc3b1ba
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/init-first.c
> @@ -0,0 +1,52 @@
> +/* Initialization code run first thing by the ELF startup code. Linux/i386.
> + Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifdef SHARED
> +# include <time.h>
> +# include <sysdep.h>
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
> +
> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> + __attribute__ ((nocommon));
> +libc_hidden_proto (__vdso_clock_gettime)
> +libc_hidden_data_def (__vdso_clock_gettime)
> +
> +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)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
Perhaps:
PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
(here and several other places)
> +
> + void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
> + if (p == NULL)
> + p = clock_gettime_syscall;
> + PTR_MANGLE (p);
> + __vdso_clock_gettime = p;
> +}
> +
> +# define VDSO_SETUP __vdso_platform_setup
> +#endif
> +
> +#include <csu/init-first.c>
[...]
> diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> new file mode 100644
> index 0000000..2547a8c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> @@ -0,0 +1,38 @@
> +/* Get the current value of a clock. Linux/x86 version.
> + Copyright (C) 2014 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 <libc-vdso.h>
> +
> +#ifdef SHARED
> +# define SYSCALL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + long int v_ret; \
> + PTR_DEMANGLE (f); \
> + v_ret = (*f) (id, tp); \
> + if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
> + __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
> + v_ret = -1; \
> + } \
> + v_ret; })
Does introducing the dispatch through function pointer here cause a
measurable performance regression on i386 kernels which lack the VDSO?
If so, is that a concern?
When I've tried this approach on ARM, it appears to do so (around 5%
slowdown).
> +# define INTERNAL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + PTR_DEMANGLE (f); \
> + (*f) (id, tp); })
> +#endif
I'm probably missing something, but I am failing to see the need for an
INTERNAL_GETTIME definition in
sysdeps/unix/sysv/linux/x86/clock_gettime.c. I know this patch is
merely moving existing code, but sysdeps/unix/sysv/linux/clock_gettime.c
does not use INTERNAL_GETTIME, and neither does
sysdeps/unix/clock_gettime.c.
INTERNAL_GETTIME is needed for timespec_get, but I am not seeing the
need to duplicate it for clock_gettime.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-10-09 20:50 ` Nathan Lynch
@ 2014-11-03 20:30 ` Adhemerval Zanella
2014-11-03 21:42 ` Adhemerval Zanella
2014-11-03 23:51 ` Nathan Lynch
0 siblings, 2 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-11-03 20:30 UTC (permalink / raw)
To: Nathan Lynch; +Cc: GNU C. Library
On 09-10-2014 17:50, Nathan Lynch wrote:
> On 10/09/2014 01:31 PM, Adhemerval Zanella wrote:
>> +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)
>> +{
>> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> Perhaps:
>
> PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
>
> (here and several other places)
Thanks, I fixed it on all the places nows.
>
>> +#ifdef SHARED
>> +# define SYSCALL_GETTIME(id, tp) \
>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>> + long int v_ret; \
>> + PTR_DEMANGLE (f); \
>> + v_ret = (*f) (id, tp); \
>> + if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
>> + __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
>> + v_ret = -1; \
>> + } \
>> + v_ret; })
> Does introducing the dispatch through function pointer here cause a
> measurable performance regression on i386 kernels which lack the VDSO?
> If so, is that a concern?
>
> When I've tried this approach on ARM, it appears to do so (around 5%
> slowdown).
Using a simple benchmark (in attachments) the difference in such scenarios is not
as drastic as ARM it seems:
kernel: Linux birita 3.13.0-39
CPU: Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
EGLIBC 2.19-0ubuntu6.3: 1415.12 cycles
GLIBC 2.20 master: 1421.66 cycles
>
>
>> +# define INTERNAL_GETTIME(id, tp) \
>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>> + PTR_DEMANGLE (f); \
>> + (*f) (id, tp); })
>> +#endif
> I'm probably missing something, but I am failing to see the need for an
> INTERNAL_GETTIME definition in
> sysdeps/unix/sysv/linux/x86/clock_gettime.c. I know this patch is
> merely moving existing code, but sysdeps/unix/sysv/linux/clock_gettime.c
> does not use INTERNAL_GETTIME, and neither does
> sysdeps/unix/clock_gettime.c.
>
> INTERNAL_GETTIME is needed for timespec_get, but I am not seeing the
> need to duplicate it for clock_gettime.
i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
sysdeps/unix/sysv/linux/clock_gettime.c:
26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
and then if INTERNAL_GETTIME is not defined, it will as:
37 #ifndef INTERNAL_GETTIME
38 # define INTERNAL_GETTIME(id, tp) \
39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
40 #endif
And without proper set the PTR_DEMANGLE is not called either.
With PREPARE_VERSION_KNOWN fixes, is it ok to commit?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-11-03 20:30 ` Adhemerval Zanella
@ 2014-11-03 21:42 ` Adhemerval Zanella
2014-11-03 23:51 ` Nathan Lynch
1 sibling, 0 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-11-03 21:42 UTC (permalink / raw)
To: Nathan Lynch; +Cc: GNU C. Library
[-- Attachment #1: Type: text/plain, Size: 2794 bytes --]
On 03-11-2014 18:30, Adhemerval Zanella wrote:
> On 09-10-2014 17:50, Nathan Lynch wrote:
>> On 10/09/2014 01:31 PM, Adhemerval Zanella wrote:
>>> +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)
>>> +{
>>> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
>> Perhaps:
>>
>> PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
>>
>> (here and several other places)
> Thanks, I fixed it on all the places nows.
>
>>> +#ifdef SHARED
>>> +# define SYSCALL_GETTIME(id, tp) \
>>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>>> + long int v_ret; \
>>> + PTR_DEMANGLE (f); \
>>> + v_ret = (*f) (id, tp); \
>>> + if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
>>> + __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
>>> + v_ret = -1; \
>>> + } \
>>> + v_ret; })
>> Does introducing the dispatch through function pointer here cause a
>> measurable performance regression on i386 kernels which lack the VDSO?
>> If so, is that a concern?
>>
>> When I've tried this approach on ARM, it appears to do so (around 5%
>> slowdown).
> Using a simple benchmark (in attachments) the difference in such scenarios is not
> as drastic as ARM it seems:
>
> kernel: Linux birita 3.13.0-39
> CPU: Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
>
> EGLIBC 2.19-0ubuntu6.3: 1415.12 cycles
> GLIBC 2.20 master: 1421.66 cycles
>
>>
>>> +# define INTERNAL_GETTIME(id, tp) \
>>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>>> + PTR_DEMANGLE (f); \
>>> + (*f) (id, tp); })
>>> +#endif
>> I'm probably missing something, but I am failing to see the need for an
>> INTERNAL_GETTIME definition in
>> sysdeps/unix/sysv/linux/x86/clock_gettime.c. I know this patch is
>> merely moving existing code, but sysdeps/unix/sysv/linux/clock_gettime.c
>> does not use INTERNAL_GETTIME, and neither does
>> sysdeps/unix/clock_gettime.c.
>>
>> INTERNAL_GETTIME is needed for timespec_get, but I am not seeing the
>> need to duplicate it for clock_gettime.
> i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
>
> sysdeps/unix/sysv/linux/clock_gettime.c:
>
> 26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
>
> and then if INTERNAL_GETTIME is not defined, it will as:
>
> 37 #ifndef INTERNAL_GETTIME
> 38 # define INTERNAL_GETTIME(id, tp) \
> 39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
> 40 #endif
>
> And without proper set the PTR_DEMANGLE is not called either.
>
> With PREPARE_VERSION_KNOWN fixes, is it ok to commit?
>
Send the missing simple benchmark.
[-- Attachment #2: test-vdso-i386.c --]
[-- Type: text/x-csrc, Size: 1191 bytes --]
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdint.h>
#ifdef __x86_64__
# define HP_TIMING_NOW(Var) \
({ unsigned int _hi, _lo; \
asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
(Var) = ((unsigned long long int) _hi << 32) | _lo; })
#else
# define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var))
#endif
/* Compute the difference between START and END, storing into DIFF. */
#define HP_TIMING_DIFF(Diff, Start, End) ((Diff) = (End) - (Start))
/* Accumulate ADD into SUM. No attempt is made to be thread-safe. */
#define HP_TIMING_ACCUM_NT(Sum, Diff) ((Sum) += (Diff))
/* We use 64bit values for the times. */
typedef unsigned long long int hp_timing_t;
#define NITER 10000000UL
int main ()
{
const clockid_t id = CLOCK_REALTIME;
uint64_t i;
hp_timing_t start, end, diff;
int ret = 0;
HP_TIMING_NOW (start);
for (i=0; i<NITER; ++i)
{
struct timespec ts;
ret += clock_gettime (id, &ts);
}
HP_TIMING_NOW (end);
HP_TIMING_DIFF (diff, start, end);
double callcyc = (double)diff / (double)NITER;
printf ("%2.2lf cycles\n", callcyc);
return ret;
}
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-11-03 20:30 ` Adhemerval Zanella
2014-11-03 21:42 ` Adhemerval Zanella
@ 2014-11-03 23:51 ` Nathan Lynch
2014-11-05 12:51 ` Adhemerval Zanella
1 sibling, 1 reply; 27+ messages in thread
From: Nathan Lynch @ 2014-11-03 23:51 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: GNU C. Library
On 11/03/2014 02:30 PM, Adhemerval Zanella wrote:
> On 09-10-2014 17:50, Nathan Lynch wrote:
>> On 10/09/2014 01:31 PM, Adhemerval Zanella wrote:
>>
>>> +#ifdef SHARED
>>> +# define SYSCALL_GETTIME(id, tp) \
>>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>>> + long int v_ret; \
>>> + PTR_DEMANGLE (f); \
>>> + v_ret = (*f) (id, tp); \
>>> + if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
>>> + __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
>>> + v_ret = -1; \
>>> + } \
>>> + v_ret; })
>> Does introducing the dispatch through function pointer here cause a
>> measurable performance regression on i386 kernels which lack the VDSO?
>> If so, is that a concern?
>>
>> When I've tried this approach on ARM, it appears to do so (around 5%
>> slowdown).
>
> Using a simple benchmark (in attachments) the difference in such scenarios is not
> as drastic as ARM it seems:
>
> kernel: Linux birita 3.13.0-39
> CPU: Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
>
> EGLIBC 2.19-0ubuntu6.3: 1415.12 cycles
> GLIBC 2.20 master: 1421.66 cycles
OK.
>>> +# define INTERNAL_GETTIME(id, tp) \
>>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>>> + PTR_DEMANGLE (f); \
>>> + (*f) (id, tp); })
>>> +#endif
>> I'm probably missing something, but I am failing to see the need for an
>> INTERNAL_GETTIME definition in
>> sysdeps/unix/sysv/linux/x86/clock_gettime.c. I know this patch is
>> merely moving existing code, but sysdeps/unix/sysv/linux/clock_gettime.c
>> does not use INTERNAL_GETTIME, and neither does
>> sysdeps/unix/clock_gettime.c.
>>
>> INTERNAL_GETTIME is needed for timespec_get, but I am not seeing the
>> need to duplicate it for clock_gettime.
>
> i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
>
> sysdeps/unix/sysv/linux/clock_gettime.c:
>
> 26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
>
> and then if INTERNAL_GETTIME is not defined, it will as:
>
> 37 #ifndef INTERNAL_GETTIME
> 38 # define INTERNAL_GETTIME(id, tp) \
> 39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
> 40 #endif
>
> And without proper set the PTR_DEMANGLE is not called either.
I think my point might be better expressed as: why is INTERNAL_GETTIME
defined in linux/clock_gettime.c at all? It is not used in the
clock_gettime implementation.
The only use in glibc of a macro by that name is in
linux/timespec_get.c, and the arch can override it in its own
timespec_get.c (as x86_64 currently does).
> With PREPARE_VERSION_KNOWN fixes, is it ok to commit?
I have no objection, FWIW.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-11-03 23:51 ` Nathan Lynch
@ 2014-11-05 12:51 ` Adhemerval Zanella
2014-11-05 16:22 ` Nathan Lynch
0 siblings, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-11-05 12:51 UTC (permalink / raw)
To: libc-alpha
On 03-11-2014 21:51, Nathan Lynch wrote:
>> i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
>>
>> sysdeps/unix/sysv/linux/clock_gettime.c:
>>
>> 26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
>>
>> and then if INTERNAL_GETTIME is not defined, it will as:
>>
>> 37 #ifndef INTERNAL_GETTIME
>> 38 # define INTERNAL_GETTIME(id, tp) \
>> 39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
>> 40 #endif
>>
>> And without proper set the PTR_DEMANGLE is not called either.
> I think my point might be better expressed as: why is INTERNAL_GETTIME
> defined in linux/clock_gettime.c at all? It is not used in the
> clock_gettime implementation.
>
> The only use in glibc of a macro by that name is in
> linux/timespec_get.c, and the arch can override it in its own
> timespec_get.c (as x86_64 currently does).
>
I see your point and I removed its definition now for x86. Below it's the revised
patchset.
Tested on x86_64 and i386 on a 3.5.0-51 and on a 3.16-rc1 kernel.
--
2014-11-04 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Stefani Seibold <stefani@seibold.net>
* sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
(sysdep_routines): Add dl-vdso here, ...
* sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
(sysdep_routines): ... not here.
* sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: set syscall
fallback when vDSO is not presented.
* sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime):
Define with libc_hidden_proto/libc_hidden_data_def definitions.
(_libc_vdso_platform_setup): Rename to __vdso_platform_setup.
* sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
* sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
* sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
* sysdeps/unix/sysv/linux/x86/libc-vdso.h: ... here.
* sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
* sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
* sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
fallback configurable symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
* sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
be able to redefine fallback symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
* sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
---
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
new file mode 100644
index 0000000..2b58fd5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -0,0 +1,39 @@
+/* gettimeofday - get the time. Linux/i386 version.
+ Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the syscall. */
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+# define GETTIMEOFAY_FALLBACK (void*) (&__gettimeofday_syscall)
+# undef libc_ifunc_hidden_def
+# define libc_ifunc_hidden_def(name) \
+ libc_ifunc_hidden_def1 (__GI_##name, __gettimeofday_syscall)
+
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
new file mode 100644
index 0000000..f0a3327
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
@@ -0,0 +1,52 @@
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+ __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
+
+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)
+{
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ if (p == NULL)
+ p = clock_gettime_syscall;
+ PTR_MANGLE (p);
+ __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP __vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
new file mode 100644
index 0000000..45b8a50
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -0,0 +1,37 @@
+/* time -- Get number of seconds since Epoch. Linux/i386 version.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the old vsyscall. */
+static time_t
+__time_syscall (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+# define TIME_FALLBACK (void*) &__time_syscall
+# undef libc_ifunc_hidden_def
+# define libc_ifunc_hidden_def(name) \
+ libc_ifunc_hidden_def1 (__GI_##name, __time_syscall)
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index 0281f87..d6be472 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -19,3 +19,7 @@ libpthread-sysdep_routines += init-arch
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
new file mode 100644
index 0000000..c3964de
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
@@ -0,0 +1,34 @@
+/* Get the current value of a clock. Linux/x86 version.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define SYSCALL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ long int v_ret; \
+ PTR_DEMANGLE (f); \
+ v_ret = (*f) (id, tp); \
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
+ v_ret = -1; \
+ } \
+ v_ret; })
+#endif
+
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
new file mode 100644
index 0000000..b4734b0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -0,0 +1,53 @@
+/* gettimeofday - get the time. Linux/x86 version.
+ 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+ ?: GETTIMEOFAY_FALLBACK);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+libc_ifunc_hidden_def(__gettimeofday)
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+libc_hidden_def (__gettimeofday)
+
+#endif
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
new file mode 100644
index 0000000..f291924
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
@@ -0,0 +1,31 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005-2014 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/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
new file mode 100644
index 0000000..c1aee0a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -0,0 +1,49 @@
+/* time -- Get number of seconds since Epoch. Linux/x86 version.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#ifdef SHARED
+
+#include <dl-vdso.h>
+
+void *time_ifunc (void) __asm__ ("time");
+
+void *
+time_ifunc (void)
+{
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
+}
+asm (".type time, %gnu_indirect_function");
+
+libc_ifunc_hidden_def(time)
+
+#else
+
+# include <sysdep.h>
+
+time_t
+time (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
new file mode 100644
index 0000000..4b6d721
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
@@ -0,0 +1,29 @@
+/* timespec_get -- returns the calendar time based on a given time base.
+ Linux/x86 version.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ (*f) (id, tp); })
+#endif
+
+#include <sysdeps/unix/sysv/linux/timespec_get.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index d6a9d36..9b82155 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -13,7 +13,3 @@ endif
ifeq ($(subdir),misc)
gen-as-const-headers += sigaltstack-offsets.sym
endif
-
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
deleted file mode 100644
index f291924..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Resolve function pointers to VDSO functions.
- Copyright (C) 2005-2014 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/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef SHARED
-
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
-
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
deleted file mode 100644
index f712110..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define SYSCALL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- long int v_ret; \
- PTR_DEMANGLE (f); \
- v_ret = f (id, tp); \
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
- v_ret = -1; \
- } \
- v_ret; })
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
index 440ca7f..defefbc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
@@ -18,42 +18,9 @@
#include <sys/time.h>
#ifdef SHARED
-
-# include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
-
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
- let us do it in C because it doesn't know we're defining __gettimeofday
- here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
+# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
index fb090df..827751a 100644
--- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
+++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
@@ -20,20 +20,20 @@
# include <time.h>
# include <sysdep.h>
# include <dl-vdso.h>
-# include <bits/libc-vdso.h>
+# include <libc-vdso.h>
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
__attribute__ ((nocommon));
-strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
-
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
static inline void
-_libc_vdso_platform_setup (void)
+__vdso_platform_setup (void)
{
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
@@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
if (p == NULL)
p = __syscall_clock_gettime;
PTR_MANGLE (p);
- __GI___vdso_clock_gettime = p;
+ __vdso_clock_gettime = p;
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
/* If the vDSO is not available we fall back on the old vsyscall. */
@@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
__vdso_getcpu = p;
}
-# define VDSO_SETUP _libc_vdso_platform_setup
+# define VDSO_SETUP __vdso_platform_setup
#endif
#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
index 79f1fab..ec1393b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
@@ -16,45 +16,9 @@
<http://www.gnu.org/licenses/>. */
#ifdef SHARED
-/* Redefine time so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef time
-#define time __redirect_time
-#include <time.h>
-
-#include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_time) __libc_time;
-void *time_ifunc (void) __asm__ ("__libc_time");
-
-void *
-time_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
-}
-__asm (".type __libc_time, %gnu_indirect_function");
-
-#undef time
-strong_alias (__libc_time, time)
-libc_hidden_ver (__libc_time, time)
-
-#else
-
-# include <time.h>
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
deleted file mode 100644
index cb26068..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../timespec_get.c"
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-11-05 12:51 ` Adhemerval Zanella
@ 2014-11-05 16:22 ` Nathan Lynch
2014-11-14 19:19 ` Adhemerval Zanella
0 siblings, 1 reply; 27+ messages in thread
From: Nathan Lynch @ 2014-11-05 16:22 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: libc-alpha
On 11/05/2014 06:51 AM, Adhemerval Zanella wrote:
> On 03-11-2014 21:51, Nathan Lynch wrote:
>>> i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
>>>
>>> sysdeps/unix/sysv/linux/clock_gettime.c:
>>>
>>> 26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
>>>
>>> and then if INTERNAL_GETTIME is not defined, it will as:
>>>
>>> 37 #ifndef INTERNAL_GETTIME
>>> 38 # define INTERNAL_GETTIME(id, tp) \
>>> 39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
>>> 40 #endif
>>>
>>> And without proper set the PTR_DEMANGLE is not called either.
>> I think my point might be better expressed as: why is INTERNAL_GETTIME
>> defined in linux/clock_gettime.c at all? It is not used in the
>> clock_gettime implementation.
>>
>> The only use in glibc of a macro by that name is in
>> linux/timespec_get.c, and the arch can override it in its own
>> timespec_get.c (as x86_64 currently does).
>>
> I see your point and I removed its definition now for x86. Below it's the revised
> patchset.
I have no further concerns, thanks.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-11-05 16:22 ` Nathan Lynch
@ 2014-11-14 19:19 ` Adhemerval Zanella
2014-11-27 17:38 ` Adhemerval Zanella
0 siblings, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-11-14 19:19 UTC (permalink / raw)
To: libc-alpha
On 05-11-2014 14:22, Nathan Lynch wrote:
> On 11/05/2014 06:51 AM, Adhemerval Zanella wrote:
>> On 03-11-2014 21:51, Nathan Lynch wrote:
>>>> i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
>>>>
>>>> sysdeps/unix/sysv/linux/clock_gettime.c:
>>>>
>>>> 26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
>>>>
>>>> and then if INTERNAL_GETTIME is not defined, it will as:
>>>>
>>>> 37 #ifndef INTERNAL_GETTIME
>>>> 38 # define INTERNAL_GETTIME(id, tp) \
>>>> 39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
>>>> 40 #endif
>>>>
>>>> And without proper set the PTR_DEMANGLE is not called either.
>>> I think my point might be better expressed as: why is INTERNAL_GETTIME
>>> defined in linux/clock_gettime.c at all? It is not used in the
>>> clock_gettime implementation.
>>>
>>> The only use in glibc of a macro by that name is in
>>> linux/timespec_get.c, and the arch can override it in its own
>>> timespec_get.c (as x86_64 currently does).
>>>
>> I see your point and I removed its definition now for x86. Below it's the revised
>> patchset.
>
> I have no further concerns, thanks.
>
Ping, is this patch ok to commit?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-11-14 19:19 ` Adhemerval Zanella
@ 2014-11-27 17:38 ` Adhemerval Zanella
0 siblings, 0 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-11-27 17:38 UTC (permalink / raw)
To: libc-alpha
On 14-11-2014 17:19, Adhemerval Zanella wrote:
> On 05-11-2014 14:22, Nathan Lynch wrote:
>> On 11/05/2014 06:51 AM, Adhemerval Zanella wrote:
>>> On 03-11-2014 21:51, Nathan Lynch wrote:
>>>>> i386 does not define HAVE_CLOCK_GETTIME_VSYSCALL and thus:
>>>>>
>>>>> sysdeps/unix/sysv/linux/clock_gettime.c:
>>>>>
>>>>> 26: # define INTERNAL_VSYSCALL INTERNAL_SYSCALL
>>>>>
>>>>> and then if INTERNAL_GETTIME is not defined, it will as:
>>>>>
>>>>> 37 #ifndef INTERNAL_GETTIME
>>>>> 38 # define INTERNAL_GETTIME(id, tp) \
>>>>> 39 INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
>>>>> 40 #endif
>>>>>
>>>>> And without proper set the PTR_DEMANGLE is not called either.
>>>> I think my point might be better expressed as: why is INTERNAL_GETTIME
>>>> defined in linux/clock_gettime.c at all? It is not used in the
>>>> clock_gettime implementation.
>>>>
>>>> The only use in glibc of a macro by that name is in
>>>> linux/timespec_get.c, and the arch can override it in its own
>>>> timespec_get.c (as x86_64 currently does).
>>>>
>>> I see your point and I removed its definition now for x86. Below it's the revised
>>> patchset.
>> I have no further concerns, thanks.
>>
> Ping, is this patch ok to commit?
>
Ping.
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2] Add x86 32 bit vDSO time function support
@ 2014-11-19 7:53 Stefani Seibold
0 siblings, 0 replies; 27+ messages in thread
From: Stefani Seibold @ 2014-11-19 7:53 UTC (permalink / raw)
To: GNU C. Library; +Cc: Stefani Seibold, Adhemerval Zanella
Linux 3.15 adds support for clock_gettime, gettimeofday, and time vDSO
(commit id 37c975545ec63320789962bf307f000f08fabd48). This patch adds
GLIBC supports to use such symbol when they are available.
Along with x86 vDSO support, this patch cleanup x86_64 code by moving
all common code to x86 common folder. Only init-first.c is different
between implementations, since they differ substantially (x86_64 has
getcpu symbol where x86 does not).
This is a respin of https://sourceware.org/ml/libc-alpha/2014-04/msg00384.html
Checked on x86 and x86_64 with a 3.16-rc2 kernel.
--
2014-11-19 No changes since last version, resend for applying to the glibc master brach
2014-06-27 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Stefani Seibold <stefani@seibold.net>
* sysdeps/unix/sysv/linux/i386/Makefile [sysdep_routines]: Add dl-vdso
object.
* sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: add support
to vDSO.
* sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
* sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
* sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
* sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h: ... here.
* sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
* sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
* sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
fallback configurable symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
* sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
be able to redefine fallback symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
* sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
---
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index acc3021..3222f46 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -21,3 +21,7 @@ endif
ifeq ($(subdir),stdlib)
gen-as-const-headers += ucontext_i.sym
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
new file mode 100644
index 0000000..c45438c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the syscall. */
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+# define GETTIMEOFAY_FALLBACK __gettimeofday_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
new file mode 100644
index 0000000..10b0a97
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
@@ -0,0 +1,53 @@
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+ __attribute__ ((nocommon));
+strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime 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
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ if (p == NULL)
+ p = clock_gettime_syscall;
+ PTR_MANGLE (p);
+ __GI___vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
new file mode 100644
index 0000000..616ec77
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the old vsyscall. */
+static time_t
+__time_syscall (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+# define TIME_FALLBACK (void*)__time_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
new file mode 100644
index 0000000..f291924
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
@@ -0,0 +1,31 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005-2014 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/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
new file mode 100644
index 0000000..f712110
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
@@ -0,0 +1,20 @@
+#include "bits/libc-vdso.h"
+
+#ifdef SHARED
+# define SYSCALL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ long int v_ret; \
+ PTR_DEMANGLE (f); \
+ v_ret = f (id, tp); \
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
+ v_ret = -1; \
+ } \
+ v_ret; })
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ f (id, tp); })
+#endif
+
+#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
new file mode 100644
index 0000000..71f48bb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+ ?: (void *) GETTIMEOFAY_FALLBACK);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
+ let us do it in C because it doesn't know we're defining __gettimeofday
+ here in this file. */
+asm (".globl __GI___gettimeofday\n"
+ "__GI___gettimeofday = __gettimeofday");
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+libc_hidden_def (__gettimeofday)
+
+#endif
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
new file mode 100644
index 0000000..183754b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#ifdef SHARED
+
+#include <dl-vdso.h>
+
+void *time_ifunc (void) __asm__ ("time");
+
+void *
+time_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
+}
+asm (".type time, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (time)" but the compiler won't let us do
+ it in C because it doesn't know we're defining __gettimeofday here in
+ this file. */
+asm (".globl __GI_time\n"
+ "__GI_time = time");
+
+#else
+
+# include <sysdep.h>
+
+time_t
+time (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
new file mode 100644
index 0000000..cb26068
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
@@ -0,0 +1,10 @@
+#include "bits/libc-vdso.h"
+
+#ifdef SHARED
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ f (id, tp); })
+#endif
+
+#include "../timespec_get.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
deleted file mode 100644
index f291924..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Resolve function pointers to VDSO functions.
- Copyright (C) 2005-2014 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/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef SHARED
-
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
-
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
deleted file mode 100644
index f712110..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define SYSCALL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- long int v_ret; \
- PTR_DEMANGLE (f); \
- v_ret = f (id, tp); \
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
- v_ret = -1; \
- } \
- v_ret; })
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
index 440ca7f..b0fa0e4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
@@ -18,42 +18,9 @@
#include <sys/time.h>
#ifdef SHARED
-
-# include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
-
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
- let us do it in C because it doesn't know we're defining __gettimeofday
- here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
+# define GETTIMEOFAY_FALLBACK VSYSCALL_ADDR_vgettimeofday
#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
index 79f1fab..ec1393b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
@@ -16,45 +16,9 @@
<http://www.gnu.org/licenses/>. */
#ifdef SHARED
-/* Redefine time so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef time
-#define time __redirect_time
-#include <time.h>
-
-#include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_time) __libc_time;
-void *time_ifunc (void) __asm__ ("__libc_time");
-
-void *
-time_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
-}
-__asm (".type __libc_time, %gnu_indirect_function");
-
-#undef time
-strong_alias (__libc_time, time)
-libc_hidden_ver (__libc_time, time)
-
-#else
-
-# include <time.h>
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
deleted file mode 100644
index cb26068..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../timespec_get.c"
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v2] Add x86 32 bit vDSO time function support
@ 2014-06-27 21:21 Adhemerval Zanella
2014-06-27 21:58 ` Roland McGrath
0 siblings, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-06-27 21:21 UTC (permalink / raw)
To: GNU C. Library; +Cc: Stefani Seibold
Linux 3.15 adds support for clock_gettime, gettimeofday, and time vDSO
(commit id 37c975545ec63320789962bf307f000f08fabd48). This patch adds
GLIBC supports to use such symbol when they are available.
Along with x86 vDSO support, this patch cleanup x86_64 code by moving
all common code to x86 common folder. Only init-first.c is different
between implementations, since they differ substantially (x86_64 has
getcpu symbol where x86 does not).
This is a respin of https://sourceware.org/ml/libc-alpha/2014-04/msg00384.html
Checked on x86 and x86_64 with a 3.16-rc2 kernel.
--
2014-06-27 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Stefani Seibold <stefani@seibold.net>
* sysdeps/unix/sysv/linux/i386/Makefile [sysdep_routines]: Add dl-vdso
object.
* sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: add support
to vDSO.
* sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
* sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
* sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
* sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h: ... here.
* sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
* sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
* sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
fallback configurable symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
* sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
be able to redefine fallback symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
* sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
---
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index acc3021..3222f46 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -21,3 +21,7 @@ endif
ifeq ($(subdir),stdlib)
gen-as-const-headers += ucontext_i.sym
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
new file mode 100644
index 0000000..c45438c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the syscall. */
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+# define GETTIMEOFAY_FALLBACK __gettimeofday_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
new file mode 100644
index 0000000..10b0a97
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
@@ -0,0 +1,53 @@
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+ __attribute__ ((nocommon));
+strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime 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
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ if (p == NULL)
+ p = clock_gettime_syscall;
+ PTR_MANGLE (p);
+ __GI___vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
new file mode 100644
index 0000000..616ec77
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the old vsyscall. */
+static time_t
+__time_syscall (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+# define TIME_FALLBACK (void*)__time_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
new file mode 100644
index 0000000..f291924
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
@@ -0,0 +1,31 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005-2014 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/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
new file mode 100644
index 0000000..f712110
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
@@ -0,0 +1,20 @@
+#include "bits/libc-vdso.h"
+
+#ifdef SHARED
+# define SYSCALL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ long int v_ret; \
+ PTR_DEMANGLE (f); \
+ v_ret = f (id, tp); \
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
+ v_ret = -1; \
+ } \
+ v_ret; })
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ f (id, tp); })
+#endif
+
+#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
new file mode 100644
index 0000000..71f48bb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+ ?: (void *) GETTIMEOFAY_FALLBACK);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
+ let us do it in C because it doesn't know we're defining __gettimeofday
+ here in this file. */
+asm (".globl __GI___gettimeofday\n"
+ "__GI___gettimeofday = __gettimeofday");
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+libc_hidden_def (__gettimeofday)
+
+#endif
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
new file mode 100644
index 0000000..183754b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#ifdef SHARED
+
+#include <dl-vdso.h>
+
+void *time_ifunc (void) __asm__ ("time");
+
+void *
+time_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
+}
+asm (".type time, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (time)" but the compiler won't let us do
+ it in C because it doesn't know we're defining __gettimeofday here in
+ this file. */
+asm (".globl __GI_time\n"
+ "__GI_time = time");
+
+#else
+
+# include <sysdep.h>
+
+time_t
+time (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
new file mode 100644
index 0000000..cb26068
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
@@ -0,0 +1,10 @@
+#include "bits/libc-vdso.h"
+
+#ifdef SHARED
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ f (id, tp); })
+#endif
+
+#include "../timespec_get.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
deleted file mode 100644
index f291924..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Resolve function pointers to VDSO functions.
- Copyright (C) 2005-2014 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/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef SHARED
-
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
-
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
deleted file mode 100644
index f712110..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define SYSCALL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- long int v_ret; \
- PTR_DEMANGLE (f); \
- v_ret = f (id, tp); \
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
- v_ret = -1; \
- } \
- v_ret; })
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
index 440ca7f..b0fa0e4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
@@ -18,42 +18,9 @@
#include <sys/time.h>
#ifdef SHARED
-
-# include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
-
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
- let us do it in C because it doesn't know we're defining __gettimeofday
- here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
+# define GETTIMEOFAY_FALLBACK VSYSCALL_ADDR_vgettimeofday
#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
index 79f1fab..ec1393b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
@@ -16,45 +16,9 @@
<http://www.gnu.org/licenses/>. */
#ifdef SHARED
-/* Redefine time so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef time
-#define time __redirect_time
-#include <time.h>
-
-#include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_time) __libc_time;
-void *time_ifunc (void) __asm__ ("__libc_time");
-
-void *
-time_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
-}
-__asm (".type __libc_time, %gnu_indirect_function");
-
-#undef time
-strong_alias (__libc_time, time)
-libc_hidden_ver (__libc_time, time)
-
-#else
-
-# include <time.h>
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
deleted file mode 100644
index cb26068..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../timespec_get.c"
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-06-27 21:21 Adhemerval Zanella
@ 2014-06-27 21:58 ` Roland McGrath
2014-06-29 15:57 ` Adhemerval Zanella
0 siblings, 1 reply; 27+ messages in thread
From: Roland McGrath @ 2014-06-27 21:58 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: GNU C. Library, Stefani Seibold
> * sysdeps/unix/sysv/linux/i386/Makefile [sysdep_routines]: Add dl-vdso
> object.
* sysdeps/unix/sysv/linux/i386/Makefile [$(subdir) = elf]
(sysdep_routines): Add dl-vdso object.
> * sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: add support
> to vDSO.
"support to use vDSO"?
> --- a/sysdeps/unix/sysv/linux/i386/Makefile
> +++ b/sysdeps/unix/sysv/linux/i386/Makefile
> @@ -21,3 +21,7 @@ endif
> ifeq ($(subdir),stdlib)
> gen-as-const-headers += ucontext_i.sym
> endif
> +
> +ifeq ($(subdir),elf)
> +sysdep_routines += dl-vdso
> +endif
Instead just move that from x86_64/Makefile to x86/Makefile so it's shared.
> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> + __attribute__ ((nocommon));
> +strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
Use libc_hidden_data_def.
> +static inline void
> +_libc_vdso_platform_setup (void)
Don't use a _libc_ prefix like that on a static symbol.
Just use a descriptive name.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/time.c
> @@ -0,0 +1,33 @@
> +/* Copyright (C) 2014 Free Software Foundation, Inc.
First line is a descriptive comment.
> +# define TIME_FALLBACK (void*)__time_syscall
# define TIME_FALLBACK ((void *) &__time_syscall)
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
[...]
> +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
libc_hidden_proto here to go with libc_hidden_def.
Also, this header really should not be in bits/.
That only makes sense for installed headers.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> @@ -0,0 +1,20 @@
> +#include "bits/libc-vdso.h"
Missing top comment and license header.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
> @@ -0,0 +1,10 @@
> +#include "bits/libc-vdso.h"
Here too.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-06-27 21:58 ` Roland McGrath
@ 2014-06-29 15:57 ` Adhemerval Zanella
2014-07-07 18:01 ` Adhemerval Zanella
2014-07-09 20:02 ` Roland McGrath
0 siblings, 2 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-06-29 15:57 UTC (permalink / raw)
To: Roland McGrath; +Cc: GNU C. Library, Stefani Seibold
Thanks for the review.
On 27-06-2014 18:58, Roland McGrath wrote:
>
>> * sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: add support
>> to vDSO.
> "support to use vDSO"?
Bad chose of words, I have change it to "set syscall fallback when vDSO is not presented."
>
>> --- a/sysdeps/unix/sysv/linux/i386/Makefile
>> +++ b/sysdeps/unix/sysv/linux/i386/Makefile
>> @@ -21,3 +21,7 @@ endif
>> ifeq ($(subdir),stdlib)
>> gen-as-const-headers += ucontext_i.sym
>> endif
>> +
>> +ifeq ($(subdir),elf)
>> +sysdep_routines += dl-vdso
>> +endif
> Instead just move that from x86_64/Makefile to x86/Makefile so it's shared.
Fixed
>
>> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
>> + __attribute__ ((nocommon));
>> +strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
> Use libc_hidden_data_def.
Fixed, I also changed x86_64 version.
>
>> +static inline void
>> +_libc_vdso_platform_setup (void)
> Don't use a _libc_ prefix like that on a static symbol.
> Just use a descriptive name.
Fixed, I also changed x86_64 version.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/i386/time.c
>> @@ -0,0 +1,33 @@
>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
> First line is a descriptive comment.
Fixed.
>
>> +# define TIME_FALLBACK (void*)__time_syscall
> # define TIME_FALLBACK ((void *) &__time_syscall)
Fixed, I also fixed the gettimeofday.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
> [...]
>> +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
> libc_hidden_proto here to go with libc_hidden_def.
>
> Also, this header really should not be in bits/.
> That only makes sense for installed headers.
Fixed and I moved it outside of bits.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
>> @@ -0,0 +1,20 @@
>> +#include "bits/libc-vdso.h"
> Missing top comment and license header.
Fixed
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
>> @@ -0,0 +1,10 @@
>> +#include "bits/libc-vdso.h"
> Here too.
>
I think I have addressed all the missing points, what about the following patch:
--
2014-06-29 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Stefani Seibold <stefani@seibold.net>
* sysdeps/unix/sysv/linux/x86_64/Makefile [sysdep_routing]: Move
dl-vdso rule to ...
* sysdeps/unix/sysv/linux/x86/Makefile [sysdep_routines]: ... here.
* sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: set syscall
fallback when vDSO is not presented.
* sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime):
Define with libc_hidden_proto/libc_hidden_data_def definitions.
(_libc_vdso_platform_setup): Rename to __vdso_platform_setup.
* sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
* sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
* sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
* sysdeps/unix/sysv/linux/x86/libc-vdso.h: ... here.
* sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
* sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
* sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
fallback configurable symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
* sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
be able to redefine fallback symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
* sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
---
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
new file mode 100644
index 0000000..f50aa76
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the syscall. */
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+# define GETTIMEOFAY_FALLBACK (void*) &__gettimeofday_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
new file mode 100644
index 0000000..dc3b1ba
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
@@ -0,0 +1,52 @@
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+ __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
+
+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)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ if (p == NULL)
+ p = clock_gettime_syscall;
+ PTR_MANGLE (p);
+ __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP __vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
new file mode 100644
index 0000000..8933e6b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -0,0 +1,34 @@
+/* time implementation call for Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the old vsyscall. */
+static time_t
+__time_syscall (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+# define TIME_FALLBACK (void*) &__time_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index 012125f..c827784 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -22,3 +22,7 @@ libpthread-sysdep_routines += init-arch
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
new file mode 100644
index 0000000..8635d5e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
@@ -0,0 +1,38 @@
+/* clock_gettime implementation call for Linux/x86.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define SYSCALL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ long int v_ret; \
+ PTR_DEMANGLE (f); \
+ v_ret = f (id, tp); \
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
+ v_ret = -1; \
+ } \
+ v_ret; })
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ f (id, tp); })
+#endif
+
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
new file mode 100644
index 0000000..587a7c4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+ ?: GETTIMEOFAY_FALLBACK);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
+ let us do it in C because it doesn't know we're defining __gettimeofday
+ here in this file. */
+asm (".globl __GI___gettimeofday\n"
+ "__GI___gettimeofday = __gettimeofday");
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+libc_hidden_def (__gettimeofday)
+
+#endif
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
new file mode 100644
index 0000000..f291924
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
@@ -0,0 +1,31 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005-2014 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/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
new file mode 100644
index 0000000..183754b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#ifdef SHARED
+
+#include <dl-vdso.h>
+
+void *time_ifunc (void) __asm__ ("time");
+
+void *
+time_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
+}
+asm (".type time, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (time)" but the compiler won't let us do
+ it in C because it doesn't know we're defining __gettimeofday here in
+ this file. */
+asm (".globl __GI_time\n"
+ "__GI_time = time");
+
+#else
+
+# include <sysdep.h>
+
+time_t
+time (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
new file mode 100644
index 0000000..ef9f655
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
@@ -0,0 +1,28 @@
+/* timespec_get implementation call for Linux/x86.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ f (id, tp); })
+#endif
+
+#include <./sysdeps/unix/sysv/linux/timespec_get.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index d6a9d36..9b82155 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -13,7 +13,3 @@ endif
ifeq ($(subdir),misc)
gen-as-const-headers += sigaltstack-offsets.sym
endif
-
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
deleted file mode 100644
index f291924..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Resolve function pointers to VDSO functions.
- Copyright (C) 2005-2014 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/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef SHARED
-
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
-
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
deleted file mode 100644
index f712110..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define SYSCALL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- long int v_ret; \
- PTR_DEMANGLE (f); \
- v_ret = f (id, tp); \
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
- v_ret = -1; \
- } \
- v_ret; })
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
index 440ca7f..defefbc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
@@ -18,42 +18,9 @@
#include <sys/time.h>
#ifdef SHARED
-
-# include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
-
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
- let us do it in C because it doesn't know we're defining __gettimeofday
- here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
+# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
index fb090df..827751a 100644
--- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
+++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
@@ -20,20 +20,20 @@
# include <time.h>
# include <sysdep.h>
# include <dl-vdso.h>
-# include <bits/libc-vdso.h>
+# include <libc-vdso.h>
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
__attribute__ ((nocommon));
-strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
-
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
static inline void
-_libc_vdso_platform_setup (void)
+__vdso_platform_setup (void)
{
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
@@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
if (p == NULL)
p = __syscall_clock_gettime;
PTR_MANGLE (p);
- __GI___vdso_clock_gettime = p;
+ __vdso_clock_gettime = p;
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
/* If the vDSO is not available we fall back on the old vsyscall. */
@@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
__vdso_getcpu = p;
}
-# define VDSO_SETUP _libc_vdso_platform_setup
+# define VDSO_SETUP __vdso_platform_setup
#endif
#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
index 79f1fab..ec1393b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
@@ -16,45 +16,9 @@
<http://www.gnu.org/licenses/>. */
#ifdef SHARED
-/* Redefine time so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef time
-#define time __redirect_time
-#include <time.h>
-
-#include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_time) __libc_time;
-void *time_ifunc (void) __asm__ ("__libc_time");
-
-void *
-time_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
-}
-__asm (".type __libc_time, %gnu_indirect_function");
-
-#undef time
-strong_alias (__libc_time, time)
-libc_hidden_ver (__libc_time, time)
-
-#else
-
-# include <time.h>
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
deleted file mode 100644
index cb26068..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../timespec_get.c"
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-06-29 15:57 ` Adhemerval Zanella
@ 2014-07-07 18:01 ` Adhemerval Zanella
2014-07-09 20:02 ` Roland McGrath
1 sibling, 0 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-07-07 18:01 UTC (permalink / raw)
To: libc-alpha
Ping, is this patch ok now with the comments addressed?
On 29-06-2014 12:57, Adhemerval Zanella wrote:
> Thanks for the review.
>
>
> On 27-06-2014 18:58, Roland McGrath wrote:
>>> * sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: add support
>>> to vDSO.
>> "support to use vDSO"?
> Bad chose of words, I have change it to "set syscall fallback when vDSO is not presented."
>
>>> --- a/sysdeps/unix/sysv/linux/i386/Makefile
>>> +++ b/sysdeps/unix/sysv/linux/i386/Makefile
>>> @@ -21,3 +21,7 @@ endif
>>> ifeq ($(subdir),stdlib)
>>> gen-as-const-headers += ucontext_i.sym
>>> endif
>>> +
>>> +ifeq ($(subdir),elf)
>>> +sysdep_routines += dl-vdso
>>> +endif
>> Instead just move that from x86_64/Makefile to x86/Makefile so it's shared.
> Fixed
>>> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
>>> + __attribute__ ((nocommon));
>>> +strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
>> Use libc_hidden_data_def.
> Fixed, I also changed x86_64 version.
>>> +static inline void
>>> +_libc_vdso_platform_setup (void)
>> Don't use a _libc_ prefix like that on a static symbol.
>> Just use a descriptive name.
> Fixed, I also changed x86_64 version.
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/i386/time.c
>>> @@ -0,0 +1,33 @@
>>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
>> First line is a descriptive comment.
> Fixed.
>>> +# define TIME_FALLBACK (void*)__time_syscall
>> # define TIME_FALLBACK ((void *) &__time_syscall)
> Fixed, I also fixed the gettimeofday.
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/bits/libc-vdso.h
>> [...]
>>> +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
>> libc_hidden_proto here to go with libc_hidden_def.
>>
>> Also, this header really should not be in bits/.
>> That only makes sense for installed headers.
> Fixed and I moved it outside of bits.
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
>>> @@ -0,0 +1,20 @@
>>> +#include "bits/libc-vdso.h"
>> Missing top comment and license header.
> Fixed
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
>>> @@ -0,0 +1,10 @@
>>> +#include "bits/libc-vdso.h"
>> Here too.
>>
> I think I have addressed all the missing points, what about the following patch:
>
> --
>
> 2014-06-29 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
> Stefani Seibold <stefani@seibold.net>
>
> * sysdeps/unix/sysv/linux/x86_64/Makefile [sysdep_routing]: Move
> dl-vdso rule to ...
> * sysdeps/unix/sysv/linux/x86/Makefile [sysdep_routines]: ... here.
> * sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: set syscall
> fallback when vDSO is not presented.
> * sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime):
> Define with libc_hidden_proto/libc_hidden_data_def definitions.
> (_libc_vdso_platform_setup): Rename to __vdso_platform_setup.
> * sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
> * sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
> * sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
> * sysdeps/unix/sysv/linux/x86/libc-vdso.h: ... here.
> * sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
> * sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
> fallback configurable symbol when vDSO is not available.
> * sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
> be able to redefine fallback symbol when vDSO is not available.
> * sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
> ---
>
> diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> new file mode 100644
> index 0000000..f50aa76
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> @@ -0,0 +1,34 @@
> +/* Copyright (C) 2014 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 <sys/time.h>
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +# include <errno.h>
> +
> +/* If the vDSO is not available we fall back on the syscall. */
> +static int
> +__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
> +{
> + return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +}
> +# define GETTIMEOFAY_FALLBACK (void*) &__gettimeofday_syscall
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
> new file mode 100644
> index 0000000..dc3b1ba
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/init-first.c
> @@ -0,0 +1,52 @@
> +/* Initialization code run first thing by the ELF startup code. Linux/i386.
> + Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifdef SHARED
> +# include <time.h>
> +# include <sysdep.h>
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
> +
> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> + __attribute__ ((nocommon));
> +libc_hidden_proto (__vdso_clock_gettime)
> +libc_hidden_data_def (__vdso_clock_gettime)
> +
> +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)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> +
> + void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
> + if (p == NULL)
> + p = clock_gettime_syscall;
> + PTR_MANGLE (p);
> + __vdso_clock_gettime = p;
> +}
> +
> +# define VDSO_SETUP __vdso_platform_setup
> +#endif
> +
> +#include <csu/init-first.c>
> diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
> new file mode 100644
> index 0000000..8933e6b
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/time.c
> @@ -0,0 +1,34 @@
> +/* time implementation call for Linux/i386.
> + Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +# include <errno.h>
> +
> +/* If the vDSO is not available we fall back on the old vsyscall. */
> +static time_t
> +__time_syscall (time_t *t)
> +{
> + INTERNAL_SYSCALL_DECL (err);
> + return INTERNAL_SYSCALL (time, err, 1, t);
> +}
> +# define TIME_FALLBACK (void*) &__time_syscall
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/x86/time.c>
> diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
> index 012125f..c827784 100644
> --- a/sysdeps/unix/sysv/linux/x86/Makefile
> +++ b/sysdeps/unix/sysv/linux/x86/Makefile
> @@ -22,3 +22,7 @@ libpthread-sysdep_routines += init-arch
> libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
> elision-trylock
> endif
> +
> +ifeq ($(subdir),elf)
> +sysdep_routines += dl-vdso
> +endif
> diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> new file mode 100644
> index 0000000..8635d5e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> @@ -0,0 +1,38 @@
> +/* clock_gettime implementation call for Linux/x86.
> + Copyright (C) 2014 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 <libc-vdso.h>
> +
> +#ifdef SHARED
> +# define SYSCALL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + long int v_ret; \
> + PTR_DEMANGLE (f); \
> + v_ret = f (id, tp); \
> + if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
> + __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
> + v_ret = -1; \
> + } \
> + v_ret; })
> +# define INTERNAL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + PTR_DEMANGLE (f); \
> + f (id, tp); })
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/clock_gettime.c>
> diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> new file mode 100644
> index 0000000..587a7c4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> @@ -0,0 +1,57 @@
> +/* Copyright (C) 2014 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 <sys/time.h>
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +
> +void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> +
> +void *
> +gettimeofday_ifunc (void)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> +
> + /* If the vDSO is not available we fall back on the old vsyscall. */
> + return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
> + ?: GETTIMEOFAY_FALLBACK);
> +}
> +asm (".type __gettimeofday, %gnu_indirect_function");
> +
> +/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
> + let us do it in C because it doesn't know we're defining __gettimeofday
> + here in this file. */
> +asm (".globl __GI___gettimeofday\n"
> + "__GI___gettimeofday = __gettimeofday");
> +
> +#else
> +
> +# include <sysdep.h>
> +# include <errno.h>
> +
> +int
> +__gettimeofday (struct timeval *tv, struct timezone *tz)
> +{
> + return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +}
> +libc_hidden_def (__gettimeofday)
> +
> +#endif
> +weak_alias (__gettimeofday, gettimeofday)
> +libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
> new file mode 100644
> index 0000000..f291924
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
> @@ -0,0 +1,31 @@
> +/* Resolve function pointers to VDSO functions.
> + Copyright (C) 2005-2014 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/>. */
> +
> +#ifndef _LIBC_VDSO_H
> +#define _LIBC_VDSO_H
> +
> +#include <time.h>
> +#include <sys/time.h>
> +
> +#ifdef SHARED
> +
> +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
> +
> +#endif
> +
> +#endif /* _LIBC_VDSO_H */
> diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
> new file mode 100644
> index 0000000..183754b
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/time.c
> @@ -0,0 +1,52 @@
> +/* Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <time.h>
> +
> +#ifdef SHARED
> +
> +#include <dl-vdso.h>
> +
> +void *time_ifunc (void) __asm__ ("time");
> +
> +void *
> +time_ifunc (void)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> +
> + return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
> +}
> +asm (".type time, %gnu_indirect_function");
> +
> +/* This is doing "libc_hidden_def (time)" but the compiler won't let us do
> + it in C because it doesn't know we're defining __gettimeofday here in
> + this file. */
> +asm (".globl __GI_time\n"
> + "__GI_time = time");
> +
> +#else
> +
> +# include <sysdep.h>
> +
> +time_t
> +time (time_t *t)
> +{
> + INTERNAL_SYSCALL_DECL (err);
> + return INTERNAL_SYSCALL (time, err, 1, t);
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
> new file mode 100644
> index 0000000..ef9f655
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
> @@ -0,0 +1,28 @@
> +/* timespec_get implementation call for Linux/x86.
> + Copyright (C) 2014 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 <libc-vdso.h>
> +
> +#ifdef SHARED
> +# define INTERNAL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + PTR_DEMANGLE (f); \
> + f (id, tp); })
> +#endif
> +
> +#include <./sysdeps/unix/sysv/linux/timespec_get.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
> index d6a9d36..9b82155 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/Makefile
> +++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
> @@ -13,7 +13,3 @@ endif
> ifeq ($(subdir),misc)
> gen-as-const-headers += sigaltstack-offsets.sym
> endif
> -
> -ifeq ($(subdir),elf)
> -sysdep_routines += dl-vdso
> -endif
> diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
> deleted file mode 100644
> index f291924..0000000
> --- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Resolve function pointers to VDSO functions.
> - Copyright (C) 2005-2014 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/>. */
> -
> -#ifndef _LIBC_VDSO_H
> -#define _LIBC_VDSO_H
> -
> -#include <time.h>
> -#include <sys/time.h>
> -
> -#ifdef SHARED
> -
> -extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
> -
> -#endif
> -
> -#endif /* _LIBC_VDSO_H */
> diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
> deleted file mode 100644
> index f712110..0000000
> --- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -#include "bits/libc-vdso.h"
> -
> -#ifdef SHARED
> -# define SYSCALL_GETTIME(id, tp) \
> - ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> - long int v_ret; \
> - PTR_DEMANGLE (f); \
> - v_ret = f (id, tp); \
> - if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
> - __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
> - v_ret = -1; \
> - } \
> - v_ret; })
> -# define INTERNAL_GETTIME(id, tp) \
> - ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> - PTR_DEMANGLE (f); \
> - f (id, tp); })
> -#endif
> -
> -#include "../clock_gettime.c"
> diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
> index 440ca7f..defefbc 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
> @@ -18,42 +18,9 @@
> #include <sys/time.h>
>
> #ifdef SHARED
> -
> -# include <dl-vdso.h>
> -
> +/* If the vDSO is not available we fall back on the old vsyscall. */
> # define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
> -
> -void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> -
> -void *
> -gettimeofday_ifunc (void)
> -{
> - PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> -
> - /* If the vDSO is not available we fall back on the old vsyscall. */
> - return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
> - ?: (void *) VSYSCALL_ADDR_vgettimeofday);
> -}
> -asm (".type __gettimeofday, %gnu_indirect_function");
> -
> -/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
> - let us do it in C because it doesn't know we're defining __gettimeofday
> - here in this file. */
> -asm (".globl __GI___gettimeofday\n"
> - "__GI___gettimeofday = __gettimeofday");
> -
> -#else
> -
> -# include <sysdep.h>
> -# include <errno.h>
> -
> -int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> -{
> - return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> -}
> -libc_hidden_def (__gettimeofday)
> -
> +# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
> #endif
> -weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> +
> +#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
> index fb090df..827751a 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
> @@ -20,20 +20,20 @@
> # include <time.h>
> # include <sysdep.h>
> # include <dl-vdso.h>
> -# include <bits/libc-vdso.h>
> +# include <libc-vdso.h>
>
> long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> __attribute__ ((nocommon));
> -strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
> +libc_hidden_proto (__vdso_clock_gettime)
> +libc_hidden_data_def (__vdso_clock_gettime)
>
> long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
>
> -
> extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
>
>
> static inline void
> -_libc_vdso_platform_setup (void)
> +__vdso_platform_setup (void)
> {
> PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
>
> @@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
> if (p == NULL)
> p = __syscall_clock_gettime;
> PTR_MANGLE (p);
> - __GI___vdso_clock_gettime = p;
> + __vdso_clock_gettime = p;
>
> p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
> /* If the vDSO is not available we fall back on the old vsyscall. */
> @@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
> __vdso_getcpu = p;
> }
>
> -# define VDSO_SETUP _libc_vdso_platform_setup
> +# define VDSO_SETUP __vdso_platform_setup
> #endif
>
> #include <csu/init-first.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
> index 79f1fab..ec1393b 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/time.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/time.c
> @@ -16,45 +16,9 @@
> <http://www.gnu.org/licenses/>. */
>
> #ifdef SHARED
> -/* Redefine time so that the compiler won't complain about the type
> - mismatch with the IFUNC selector in strong_alias, below. */
> -#undef time
> -#define time __redirect_time
> -#include <time.h>
> -
> -#include <dl-vdso.h>
> -
> +/* If the vDSO is not available we fall back on the old vsyscall. */
> #define VSYSCALL_ADDR_vtime 0xffffffffff600400
> -
> -/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
> - ifunc symbol properly. */
> -extern __typeof (__redirect_time) __libc_time;
> -void *time_ifunc (void) __asm__ ("__libc_time");
> -
> -void *
> -time_ifunc (void)
> -{
> - PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> -
> - /* If the vDSO is not available we fall back on the old vsyscall. */
> - return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
> -}
> -__asm (".type __libc_time, %gnu_indirect_function");
> -
> -#undef time
> -strong_alias (__libc_time, time)
> -libc_hidden_ver (__libc_time, time)
> -
> -#else
> -
> -# include <time.h>
> -# include <sysdep.h>
> -
> -time_t
> -time (time_t *t)
> -{
> - INTERNAL_SYSCALL_DECL (err);
> - return INTERNAL_SYSCALL (time, err, 1, t);
> -}
> -
> +#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
> #endif
> +
> +#include <sysdeps/unix/sysv/linux/x86/time.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
> deleted file mode 100644
> index cb26068..0000000
> --- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -#include "bits/libc-vdso.h"
> -
> -#ifdef SHARED
> -# define INTERNAL_GETTIME(id, tp) \
> - ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> - PTR_DEMANGLE (f); \
> - f (id, tp); })
> -#endif
> -
> -#include "../timespec_get.c"
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-06-29 15:57 ` Adhemerval Zanella
2014-07-07 18:01 ` Adhemerval Zanella
@ 2014-07-09 20:02 ` Roland McGrath
2014-07-10 14:33 ` Adhemerval Zanella
1 sibling, 1 reply; 27+ messages in thread
From: Roland McGrath @ 2014-07-09 20:02 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: GNU C. Library, Stefani Seibold
> * sysdeps/unix/sysv/linux/x86_64/Makefile [sysdep_routing]: Move
> dl-vdso rule to ...
> * sysdeps/unix/sysv/linux/x86/Makefile [sysdep_routines]: ... here.
Typo: s/routing/routines/. Also, [] is for identifying conditional
sections (if* in makefiles, #if* in C). Use () for identifying the entity
being changed. Also, there is no rule here. It's just appending it to the
list (or not). I would have written:
* sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
(sysdep_routines): Add dl-vdso here, ...
* sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
(sysdep_routines): ... not here.
> * sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
Two spaces between sentences.
> * sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
And here.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> @@ -0,0 +1,34 @@
> +/* Copyright (C) 2014 Free Software Foundation, Inc.
Still needs a top-line descriptive comment.
> +# define GETTIMEOFAY_FALLBACK (void*) &__gettimeofday_syscall
Put parens around the rhs so it's a single syntactic unit.
> +++ b/sysdeps/unix/sysv/linux/i386/time.c
> @@ -0,0 +1,34 @@
> +/* time implementation call for Linux/i386.
/* time -- Get number of seconds since Epoch. Linux/i386 version.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> @@ -0,0 +1,38 @@
> +/* clock_gettime implementation call for Linux/x86.
/* Get the current value of a clock. Linux/x86 version.
(Here I copied the description from the stub file rt/clock_gettime.c.)
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> @@ -0,0 +1,57 @@
> +/* Copyright (C) 2014 Free Software Foundation, Inc.
Still needs a top-line descriptive comment.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/time.c
> @@ -0,0 +1,52 @@
> +/* Copyright (C) 2014 Free Software Foundation, Inc.
Still needs a top-line descriptive comment.
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
> @@ -0,0 +1,28 @@
> +/* timespec_get implementation call for Linux/x86.
This is not a sensical English sentence fragment.
I think you meant "timespec_get call implementation".
But that's not actually descriptive.
> +#ifdef SHARED
> +# define INTERNAL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + PTR_DEMANGLE (f); \
> + f (id, tp); })
Why isn't this just an inline function? If it had to be a macro, it should
have line breaks around ({ and }) to be more readable. Either way, it
should use (*f) (...) to call via the function pointer.
You didn't mention what testing you did. For this sort of change, it is
important to test (and report about it) for more than one kernel version,
including at least one and one without the vDSO support that this code
should use but not rely on.
I tend to think this is getting a bit close to freeze time for a
substantial semantic change like this one. But I'll defer that paranoia to
others, and if the folks here who are distro package maintainers are not
worried about it then I won't object.
Thanks,
Roland
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-09 20:02 ` Roland McGrath
@ 2014-07-10 14:33 ` Adhemerval Zanella
2014-07-22 17:32 ` Adhemerval Zanella
2014-08-02 16:48 ` Mike Frysinger
0 siblings, 2 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-07-10 14:33 UTC (permalink / raw)
To: Roland McGrath; +Cc: GNU C. Library, Stefani Seibold
Hi Roland,
Thanks again for reviewing it.
On 09-07-2014 17:02, Roland McGrath wrote:
>> * sysdeps/unix/sysv/linux/x86_64/Makefile [sysdep_routing]: Move
>> dl-vdso rule to ...
>> * sysdeps/unix/sysv/linux/x86/Makefile [sysdep_routines]: ... here.
> Typo: s/routing/routines/. Also, [] is for identifying conditional
> sections (if* in makefiles, #if* in C). Use () for identifying the entity
> being changed. Also, there is no rule here. It's just appending it to the
> list (or not). I would have written:
>
> * sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
> (sysdep_routines): Add dl-vdso here, ...
> * sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
> (sysdep_routines): ... not here.
Thanks, I used your wording.
>> * sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
> Two spaces between sentences.
>
>> * sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
> And here.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
>> @@ -0,0 +1,34 @@
>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
> Still needs a top-line descriptive comment.
>
>> +# define GETTIMEOFAY_FALLBACK (void*) &__gettimeofday_syscall
> Put parens around the rhs so it's a single syntactic unit.
>
>> +++ b/sysdeps/unix/sysv/linux/i386/time.c
>> @@ -0,0 +1,34 @@
>> +/* time implementation call for Linux/i386.
> /* time -- Get number of seconds since Epoch. Linux/i386 version.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
>> @@ -0,0 +1,38 @@
>> +/* clock_gettime implementation call for Linux/x86.
> /* Get the current value of a clock. Linux/x86 version.
>
> (Here I copied the description from the stub file rt/clock_gettime.c.)
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
>> @@ -0,0 +1,57 @@
>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
> Still needs a top-line descriptive comment.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/time.c
>> @@ -0,0 +1,52 @@
>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
> Still needs a top-line descriptive comment.
>
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
>> @@ -0,0 +1,28 @@
>> +/* timespec_get implementation call for Linux/x86.
> This is not a sensical English sentence fragment.
> I think you meant "timespec_get call implementation".
> But that's not actually descriptive.
I have addressed all the aforementioned issues.
>> +#ifdef SHARED
>> +# define INTERNAL_GETTIME(id, tp) \
>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>> + PTR_DEMANGLE (f); \
>> + f (id, tp); })
> Why isn't this just an inline function? If it had to be a macro, it should
> have line breaks around ({ and }) to be more readable. Either way, it
> should use (*f) (...) to call via the function pointer.
My first approach was to just existent code, that's why I haven't changed it to
an inline function. And if you double check there is already line breaks around it.
I have changed the function call to use (*f).
>
>
> You didn't mention what testing you did. For this sort of change, it is
> important to test (and report about it) for more than one kernel version,
> including at least one and one without the vDSO support that this code
> should use but not rely on.
I have indicated on my first message (x86 and x86_64 with a 3.16-rc2 kernel) and I also
checked x86 and x86_64 on a 3.5.0 kernel.
>
> I tend to think this is getting a bit close to freeze time for a
> substantial semantic change like this one. But I'll defer that paranoia to
> others, and if the folks here who are distro package maintainers are not
> worried about it then I won't object.
Indeed, although this is more like a cleanup. Anyway, I will defer this work for
another release if other raise concerns about it.
What about now, is everything ok?
--
2014-07-10 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Stefani Seibold <stefani@seibold.net>
* sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
(sysdep_routines): Add dl-vdso here, ...
* sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
(sysdep_routines): ... not here.
* sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: set syscall
fallback when vDSO is not presented.
* sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime):
Define with libc_hidden_proto/libc_hidden_data_def definitions.
(_libc_vdso_platform_setup): Rename to __vdso_platform_setup.
* sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
* sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
* sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
* sysdeps/unix/sysv/linux/x86/libc-vdso.h: ... here.
* sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
* sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
* sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
fallback configurable symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
* sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
be able to redefine fallback symbol when vDSO is not available.
* sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
* sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
---
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
new file mode 100644
index 0000000..d02fdd3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -0,0 +1,35 @@
+/* gettimeofday - get the time. Linux/i386 version.
+ Copyright (C) 2014 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the syscall. */
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+# define GETTIMEOFAY_FALLBACK (void*) (&__gettimeofday_syscall)
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
new file mode 100644
index 0000000..dc3b1ba
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
@@ -0,0 +1,52 @@
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+ __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
+
+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)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ if (p == NULL)
+ p = clock_gettime_syscall;
+ PTR_MANGLE (p);
+ __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP __vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
new file mode 100644
index 0000000..ba4401f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -0,0 +1,34 @@
+/* time -- Get number of seconds since Epoch. Linux/i386 version.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <errno.h>
+
+/* If the vDSO is not available we fall back on the old vsyscall. */
+static time_t
+__time_syscall (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+# define TIME_FALLBACK (void*) &__time_syscall
+#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index 012125f..c827784 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -22,3 +22,7 @@ libpthread-sysdep_routines += init-arch
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
new file mode 100644
index 0000000..2547a8c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
@@ -0,0 +1,38 @@
+/* Get the current value of a clock. Linux/x86 version.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define SYSCALL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ long int v_ret; \
+ PTR_DEMANGLE (f); \
+ v_ret = (*f) (id, tp); \
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
+ v_ret = -1; \
+ } \
+ v_ret; })
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ (*f) (id, tp); })
+#endif
+
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
new file mode 100644
index 0000000..c8286e3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -0,0 +1,57 @@
+/* gettimeofday - get the time. Linux/x86 version.
+ 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 <sys/time.h>
+
+#ifdef SHARED
+
+# include <dl-vdso.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+ ?: GETTIMEOFAY_FALLBACK);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
+ let us do it in C because it doesn't know we're defining __gettimeofday
+ here in this file. */
+asm (".globl __GI___gettimeofday\n"
+ "__GI___gettimeofday = __gettimeofday");
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+libc_hidden_def (__gettimeofday)
+
+#endif
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
new file mode 100644
index 0000000..f291924
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
@@ -0,0 +1,31 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005-2014 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/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
new file mode 100644
index 0000000..efd1edf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -0,0 +1,53 @@
+/* time -- Get number of seconds since Epoch. Linux/x86 version.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+#ifdef SHARED
+
+#include <dl-vdso.h>
+
+void *time_ifunc (void) __asm__ ("time");
+
+void *
+time_ifunc (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
+}
+asm (".type time, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (time)" but the compiler won't let us do
+ it in C because it doesn't know we're defining __gettimeofday here in
+ this file. */
+asm (".globl __GI_time\n"
+ "__GI_time = time");
+
+#else
+
+# include <sysdep.h>
+
+time_t
+time (time_t *t)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ return INTERNAL_SYSCALL (time, err, 1, t);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
new file mode 100644
index 0000000..4b6d721
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
@@ -0,0 +1,29 @@
+/* timespec_get -- returns the calendar time based on a given time base.
+ Linux/x86 version.
+ Copyright (C) 2014 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 <libc-vdso.h>
+
+#ifdef SHARED
+# define INTERNAL_GETTIME(id, tp) \
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+ PTR_DEMANGLE (f); \
+ (*f) (id, tp); })
+#endif
+
+#include <sysdeps/unix/sysv/linux/timespec_get.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index d6a9d36..9b82155 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -13,7 +13,3 @@ endif
ifeq ($(subdir),misc)
gen-as-const-headers += sigaltstack-offsets.sym
endif
-
-ifeq ($(subdir),elf)
-sysdep_routines += dl-vdso
-endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
deleted file mode 100644
index f291924..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Resolve function pointers to VDSO functions.
- Copyright (C) 2005-2014 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/>. */
-
-#ifndef _LIBC_VDSO_H
-#define _LIBC_VDSO_H
-
-#include <time.h>
-#include <sys/time.h>
-
-#ifdef SHARED
-
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
-
-#endif
-
-#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
deleted file mode 100644
index f712110..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define SYSCALL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- long int v_ret; \
- PTR_DEMANGLE (f); \
- v_ret = f (id, tp); \
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
- v_ret = -1; \
- } \
- v_ret; })
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../clock_gettime.c"
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
index 440ca7f..defefbc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
@@ -18,42 +18,9 @@
#include <sys/time.h>
#ifdef SHARED
-
-# include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
-
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
- let us do it in C because it doesn't know we're defining __gettimeofday
- here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
+# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
+
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
index fb090df..827751a 100644
--- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
+++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
@@ -20,20 +20,20 @@
# include <time.h>
# include <sysdep.h>
# include <dl-vdso.h>
-# include <bits/libc-vdso.h>
+# include <libc-vdso.h>
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
__attribute__ ((nocommon));
-strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
-
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
static inline void
-_libc_vdso_platform_setup (void)
+__vdso_platform_setup (void)
{
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
@@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
if (p == NULL)
p = __syscall_clock_gettime;
PTR_MANGLE (p);
- __GI___vdso_clock_gettime = p;
+ __vdso_clock_gettime = p;
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
/* If the vDSO is not available we fall back on the old vsyscall. */
@@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
__vdso_getcpu = p;
}
-# define VDSO_SETUP _libc_vdso_platform_setup
+# define VDSO_SETUP __vdso_platform_setup
#endif
#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
index 79f1fab..ec1393b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
@@ -16,45 +16,9 @@
<http://www.gnu.org/licenses/>. */
#ifdef SHARED
-/* Redefine time so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef time
-#define time __redirect_time
-#include <time.h>
-
-#include <dl-vdso.h>
-
+/* If the vDSO is not available we fall back on the old vsyscall. */
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_time) __libc_time;
-void *time_ifunc (void) __asm__ ("__libc_time");
-
-void *
-time_ifunc (void)
-{
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
-
- /* If the vDSO is not available we fall back on the old vsyscall. */
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
-}
-__asm (".type __libc_time, %gnu_indirect_function");
-
-#undef time
-strong_alias (__libc_time, time)
-libc_hidden_ver (__libc_time, time)
-
-#else
-
-# include <time.h>
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
- INTERNAL_SYSCALL_DECL (err);
- return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
#endif
+
+#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
deleted file mode 100644
index cb26068..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "bits/libc-vdso.h"
-
-#ifdef SHARED
-# define INTERNAL_GETTIME(id, tp) \
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
- PTR_DEMANGLE (f); \
- f (id, tp); })
-#endif
-
-#include "../timespec_get.c"
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-10 14:33 ` Adhemerval Zanella
@ 2014-07-22 17:32 ` Adhemerval Zanella
2014-07-23 0:40 ` Allan McRae
2014-08-02 16:48 ` Mike Frysinger
1 sibling, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-07-22 17:32 UTC (permalink / raw)
To: Allan McRae; +Cc: Roland McGrath, GNU C. Library, Stefani Seibold
Allan,
Do you think is it good to add for 2.20?
On 10-07-2014 11:33, Adhemerval Zanella wrote:
> Hi Roland,
>
> Thanks again for reviewing it.
>
>
> On 09-07-2014 17:02, Roland McGrath wrote:
>>> * sysdeps/unix/sysv/linux/x86_64/Makefile [sysdep_routing]: Move
>>> dl-vdso rule to ...
>>> * sysdeps/unix/sysv/linux/x86/Makefile [sysdep_routines]: ... here.
>> Typo: s/routing/routines/. Also, [] is for identifying conditional
>> sections (if* in makefiles, #if* in C). Use () for identifying the entity
>> being changed. Also, there is no rule here. It's just appending it to the
>> list (or not). I would have written:
>>
>> * sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
>> (sysdep_routines): Add dl-vdso here, ...
>> * sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
>> (sysdep_routines): ... not here.
> Thanks, I used your wording.
>
>>> * sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
>> Two spaces between sentences.
>>
>>> * sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
>> And here.
>>
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
>>> @@ -0,0 +1,34 @@
>>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
>> Still needs a top-line descriptive comment.
>>
>>> +# define GETTIMEOFAY_FALLBACK (void*) &__gettimeofday_syscall
>> Put parens around the rhs so it's a single syntactic unit.
>>
>>> +++ b/sysdeps/unix/sysv/linux/i386/time.c
>>> @@ -0,0 +1,34 @@
>>> +/* time implementation call for Linux/i386.
>> /* time -- Get number of seconds since Epoch. Linux/i386 version.
>>
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
>>> @@ -0,0 +1,38 @@
>>> +/* clock_gettime implementation call for Linux/x86.
>> /* Get the current value of a clock. Linux/x86 version.
>>
>> (Here I copied the description from the stub file rt/clock_gettime.c.)
>>
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
>>> @@ -0,0 +1,57 @@
>>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
>> Still needs a top-line descriptive comment.
>>
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/time.c
>>> @@ -0,0 +1,52 @@
>>> +/* Copyright (C) 2014 Free Software Foundation, Inc.
>> Still needs a top-line descriptive comment.
>>
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
>>> @@ -0,0 +1,28 @@
>>> +/* timespec_get implementation call for Linux/x86.
>> This is not a sensical English sentence fragment.
>> I think you meant "timespec_get call implementation".
>> But that's not actually descriptive.
> I have addressed all the aforementioned issues.
>
>>> +#ifdef SHARED
>>> +# define INTERNAL_GETTIME(id, tp) \
>>> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
>>> + PTR_DEMANGLE (f); \
>>> + f (id, tp); })
>> Why isn't this just an inline function? If it had to be a macro, it should
>> have line breaks around ({ and }) to be more readable. Either way, it
>> should use (*f) (...) to call via the function pointer.
> My first approach was to just existent code, that's why I haven't changed it to
> an inline function. And if you double check there is already line breaks around it.
> I have changed the function call to use (*f).
>
>>
>> You didn't mention what testing you did. For this sort of change, it is
>> important to test (and report about it) for more than one kernel version,
>> including at least one and one without the vDSO support that this code
>> should use but not rely on.
> I have indicated on my first message (x86 and x86_64 with a 3.16-rc2 kernel) and I also
> checked x86 and x86_64 on a 3.5.0 kernel.
>
>> I tend to think this is getting a bit close to freeze time for a
>> substantial semantic change like this one. But I'll defer that paranoia to
>> others, and if the folks here who are distro package maintainers are not
>> worried about it then I won't object.
> Indeed, although this is more like a cleanup. Anyway, I will defer this work for
> another release if other raise concerns about it.
>
> What about now, is everything ok?
>
> --
>
> 2014-07-10 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
> Stefani Seibold <stefani@seibold.net>
>
> * sysdeps/unix/sysv/linux/x86_64/Makefile [$(subdir) = elf]
> (sysdep_routines): Add dl-vdso here, ...
> * sysdeps/unix/sysv/linux/x86/Makefile [$(subdir) = elf]
> (sysdep_routines): ... not here.
> * sysdeps/unix/sysv/linux/i386/gettimeofday.c: New file: set syscall
> fallback when vDSO is not presented.
> * sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime):
> Define with libc_hidden_proto/libc_hidden_data_def definitions.
> (_libc_vdso_platform_setup): Rename to __vdso_platform_setup.
> * sysdeps/unix/sysv/linux/i386/init-first.c: New file: likewise.
> * sysdeps/unix/sysv/linux/i386/time.c: New file: likewise.
> * sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: Moved to ...
> * sysdeps/unix/sysv/linux/x86/libc-vdso.h: ... here.
> * sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/clock_gettime.c: ... here.
> * sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/gettimeofday.c: ... here. Also added
> fallback configurable symbol when vDSO is not available.
> * sysdeps/unix/sysv/linux/x86_64/time.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/time.c: ... here. Also refactored to
> be able to redefine fallback symbol when vDSO is not available.
> * sysdeps/unix/sysv/linux/x86_64/timespec_get.c: Move to ...
> * sysdeps/unix/sysv/linux/x86/timespec_get.c: ... here.
>
> ---
>
> diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> new file mode 100644
> index 0000000..d02fdd3
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> @@ -0,0 +1,35 @@
> +/* gettimeofday - get the time. Linux/i386 version.
> + Copyright (C) 2014 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 <sys/time.h>
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +# include <errno.h>
> +
> +/* If the vDSO is not available we fall back on the syscall. */
> +static int
> +__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
> +{
> + return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +}
> +# define GETTIMEOFAY_FALLBACK (void*) (&__gettimeofday_syscall)
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
> new file mode 100644
> index 0000000..dc3b1ba
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/init-first.c
> @@ -0,0 +1,52 @@
> +/* Initialization code run first thing by the ELF startup code. Linux/i386.
> + Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifdef SHARED
> +# include <time.h>
> +# include <sysdep.h>
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
> +
> +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> + __attribute__ ((nocommon));
> +libc_hidden_proto (__vdso_clock_gettime)
> +libc_hidden_data_def (__vdso_clock_gettime)
> +
> +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)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> +
> + void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
> + if (p == NULL)
> + p = clock_gettime_syscall;
> + PTR_MANGLE (p);
> + __vdso_clock_gettime = p;
> +}
> +
> +# define VDSO_SETUP __vdso_platform_setup
> +#endif
> +
> +#include <csu/init-first.c>
> diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
> new file mode 100644
> index 0000000..ba4401f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/time.c
> @@ -0,0 +1,34 @@
> +/* time -- Get number of seconds since Epoch. Linux/i386 version.
> + Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +# include <errno.h>
> +
> +/* If the vDSO is not available we fall back on the old vsyscall. */
> +static time_t
> +__time_syscall (time_t *t)
> +{
> + INTERNAL_SYSCALL_DECL (err);
> + return INTERNAL_SYSCALL (time, err, 1, t);
> +}
> +# define TIME_FALLBACK (void*) &__time_syscall
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/x86/time.c>
> diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
> index 012125f..c827784 100644
> --- a/sysdeps/unix/sysv/linux/x86/Makefile
> +++ b/sysdeps/unix/sysv/linux/x86/Makefile
> @@ -22,3 +22,7 @@ libpthread-sysdep_routines += init-arch
> libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
> elision-trylock
> endif
> +
> +ifeq ($(subdir),elf)
> +sysdep_routines += dl-vdso
> +endif
> diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> new file mode 100644
> index 0000000..2547a8c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
> @@ -0,0 +1,38 @@
> +/* Get the current value of a clock. Linux/x86 version.
> + Copyright (C) 2014 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 <libc-vdso.h>
> +
> +#ifdef SHARED
> +# define SYSCALL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + long int v_ret; \
> + PTR_DEMANGLE (f); \
> + v_ret = (*f) (id, tp); \
> + if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
> + __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
> + v_ret = -1; \
> + } \
> + v_ret; })
> +# define INTERNAL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + PTR_DEMANGLE (f); \
> + (*f) (id, tp); })
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/clock_gettime.c>
> diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> new file mode 100644
> index 0000000..c8286e3
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> @@ -0,0 +1,57 @@
> +/* gettimeofday - get the time. Linux/x86 version.
> + 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 <sys/time.h>
> +
> +#ifdef SHARED
> +
> +# include <dl-vdso.h>
> +
> +void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> +
> +void *
> +gettimeofday_ifunc (void)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> +
> + /* If the vDSO is not available we fall back on the old vsyscall. */
> + return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
> + ?: GETTIMEOFAY_FALLBACK);
> +}
> +asm (".type __gettimeofday, %gnu_indirect_function");
> +
> +/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
> + let us do it in C because it doesn't know we're defining __gettimeofday
> + here in this file. */
> +asm (".globl __GI___gettimeofday\n"
> + "__GI___gettimeofday = __gettimeofday");
> +
> +#else
> +
> +# include <sysdep.h>
> +# include <errno.h>
> +
> +int
> +__gettimeofday (struct timeval *tv, struct timezone *tz)
> +{
> + return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +}
> +libc_hidden_def (__gettimeofday)
> +
> +#endif
> +weak_alias (__gettimeofday, gettimeofday)
> +libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
> new file mode 100644
> index 0000000..f291924
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
> @@ -0,0 +1,31 @@
> +/* Resolve function pointers to VDSO functions.
> + Copyright (C) 2005-2014 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/>. */
> +
> +#ifndef _LIBC_VDSO_H
> +#define _LIBC_VDSO_H
> +
> +#include <time.h>
> +#include <sys/time.h>
> +
> +#ifdef SHARED
> +
> +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
> +
> +#endif
> +
> +#endif /* _LIBC_VDSO_H */
> diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
> new file mode 100644
> index 0000000..efd1edf
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/time.c
> @@ -0,0 +1,53 @@
> +/* time -- Get number of seconds since Epoch. Linux/x86 version.
> + Copyright (C) 2014 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <time.h>
> +
> +#ifdef SHARED
> +
> +#include <dl-vdso.h>
> +
> +void *time_ifunc (void) __asm__ ("time");
> +
> +void *
> +time_ifunc (void)
> +{
> + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> +
> + return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
> +}
> +asm (".type time, %gnu_indirect_function");
> +
> +/* This is doing "libc_hidden_def (time)" but the compiler won't let us do
> + it in C because it doesn't know we're defining __gettimeofday here in
> + this file. */
> +asm (".globl __GI_time\n"
> + "__GI_time = time");
> +
> +#else
> +
> +# include <sysdep.h>
> +
> +time_t
> +time (time_t *t)
> +{
> + INTERNAL_SYSCALL_DECL (err);
> + return INTERNAL_SYSCALL (time, err, 1, t);
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
> new file mode 100644
> index 0000000..4b6d721
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
> @@ -0,0 +1,29 @@
> +/* timespec_get -- returns the calendar time based on a given time base.
> + Linux/x86 version.
> + Copyright (C) 2014 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 <libc-vdso.h>
> +
> +#ifdef SHARED
> +# define INTERNAL_GETTIME(id, tp) \
> + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> + PTR_DEMANGLE (f); \
> + (*f) (id, tp); })
> +#endif
> +
> +#include <sysdeps/unix/sysv/linux/timespec_get.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
> index d6a9d36..9b82155 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/Makefile
> +++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
> @@ -13,7 +13,3 @@ endif
> ifeq ($(subdir),misc)
> gen-as-const-headers += sigaltstack-offsets.sym
> endif
> -
> -ifeq ($(subdir),elf)
> -sysdep_routines += dl-vdso
> -endif
> diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
> deleted file mode 100644
> index f291924..0000000
> --- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Resolve function pointers to VDSO functions.
> - Copyright (C) 2005-2014 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/>. */
> -
> -#ifndef _LIBC_VDSO_H
> -#define _LIBC_VDSO_H
> -
> -#include <time.h>
> -#include <sys/time.h>
> -
> -#ifdef SHARED
> -
> -extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
> -
> -#endif
> -
> -#endif /* _LIBC_VDSO_H */
> diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
> deleted file mode 100644
> index f712110..0000000
> --- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -#include "bits/libc-vdso.h"
> -
> -#ifdef SHARED
> -# define SYSCALL_GETTIME(id, tp) \
> - ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> - long int v_ret; \
> - PTR_DEMANGLE (f); \
> - v_ret = f (id, tp); \
> - if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
> - __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
> - v_ret = -1; \
> - } \
> - v_ret; })
> -# define INTERNAL_GETTIME(id, tp) \
> - ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> - PTR_DEMANGLE (f); \
> - f (id, tp); })
> -#endif
> -
> -#include "../clock_gettime.c"
> diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
> index 440ca7f..defefbc 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
> @@ -18,42 +18,9 @@
> #include <sys/time.h>
>
> #ifdef SHARED
> -
> -# include <dl-vdso.h>
> -
> +/* If the vDSO is not available we fall back on the old vsyscall. */
> # define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
> -
> -void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> -
> -void *
> -gettimeofday_ifunc (void)
> -{
> - PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> -
> - /* If the vDSO is not available we fall back on the old vsyscall. */
> - return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
> - ?: (void *) VSYSCALL_ADDR_vgettimeofday);
> -}
> -asm (".type __gettimeofday, %gnu_indirect_function");
> -
> -/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
> - let us do it in C because it doesn't know we're defining __gettimeofday
> - here in this file. */
> -asm (".globl __GI___gettimeofday\n"
> - "__GI___gettimeofday = __gettimeofday");
> -
> -#else
> -
> -# include <sysdep.h>
> -# include <errno.h>
> -
> -int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> -{
> - return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> -}
> -libc_hidden_def (__gettimeofday)
> -
> +# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
> #endif
> -weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> +
> +#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
> index fb090df..827751a 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
> @@ -20,20 +20,20 @@
> # include <time.h>
> # include <sysdep.h>
> # include <dl-vdso.h>
> -# include <bits/libc-vdso.h>
> +# include <libc-vdso.h>
>
> long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
> __attribute__ ((nocommon));
> -strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
> +libc_hidden_proto (__vdso_clock_gettime)
> +libc_hidden_data_def (__vdso_clock_gettime)
>
> long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
>
> -
> extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
>
>
> static inline void
> -_libc_vdso_platform_setup (void)
> +__vdso_platform_setup (void)
> {
> PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
>
> @@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
> if (p == NULL)
> p = __syscall_clock_gettime;
> PTR_MANGLE (p);
> - __GI___vdso_clock_gettime = p;
> + __vdso_clock_gettime = p;
>
> p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
> /* If the vDSO is not available we fall back on the old vsyscall. */
> @@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
> __vdso_getcpu = p;
> }
>
> -# define VDSO_SETUP _libc_vdso_platform_setup
> +# define VDSO_SETUP __vdso_platform_setup
> #endif
>
> #include <csu/init-first.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
> index 79f1fab..ec1393b 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/time.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/time.c
> @@ -16,45 +16,9 @@
> <http://www.gnu.org/licenses/>. */
>
> #ifdef SHARED
> -/* Redefine time so that the compiler won't complain about the type
> - mismatch with the IFUNC selector in strong_alias, below. */
> -#undef time
> -#define time __redirect_time
> -#include <time.h>
> -
> -#include <dl-vdso.h>
> -
> +/* If the vDSO is not available we fall back on the old vsyscall. */
> #define VSYSCALL_ADDR_vtime 0xffffffffff600400
> -
> -/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
> - ifunc symbol properly. */
> -extern __typeof (__redirect_time) __libc_time;
> -void *time_ifunc (void) __asm__ ("__libc_time");
> -
> -void *
> -time_ifunc (void)
> -{
> - PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
> -
> - /* If the vDSO is not available we fall back on the old vsyscall. */
> - return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
> -}
> -__asm (".type __libc_time, %gnu_indirect_function");
> -
> -#undef time
> -strong_alias (__libc_time, time)
> -libc_hidden_ver (__libc_time, time)
> -
> -#else
> -
> -# include <time.h>
> -# include <sysdep.h>
> -
> -time_t
> -time (time_t *t)
> -{
> - INTERNAL_SYSCALL_DECL (err);
> - return INTERNAL_SYSCALL (time, err, 1, t);
> -}
> -
> +#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
> #endif
> +
> +#include <sysdeps/unix/sysv/linux/x86/time.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
> deleted file mode 100644
> index cb26068..0000000
> --- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -#include "bits/libc-vdso.h"
> -
> -#ifdef SHARED
> -# define INTERNAL_GETTIME(id, tp) \
> - ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
> - PTR_DEMANGLE (f); \
> - f (id, tp); })
> -#endif
> -
> -#include "../timespec_get.c"
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-22 17:32 ` Adhemerval Zanella
@ 2014-07-23 0:40 ` Allan McRae
2014-07-23 13:56 ` Adhemerval Zanella
2014-10-07 6:57 ` Stefani Seibold
0 siblings, 2 replies; 27+ messages in thread
From: Allan McRae @ 2014-07-23 0:40 UTC (permalink / raw)
To: Adhemerval Zanella; +Cc: Roland McGrath, GNU C. Library, Stefani Seibold
On 23/07/14 03:31, Adhemerval Zanella wrote:
> Allan,
>
> Do you think is it good to add for 2.20?
>
I'm going to say too late for this one. I looked at the patch a thought
it was a big intrusive for this stage and then noted Roland comment
suggesting it was too close to 2.20 to be included. So I am taking the
cautious approach here.
Allan
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-23 0:40 ` Allan McRae
@ 2014-07-23 13:56 ` Adhemerval Zanella
2014-09-10 14:20 ` Adhemerval Zanella
2014-10-07 6:57 ` Stefani Seibold
1 sibling, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-07-23 13:56 UTC (permalink / raw)
To: libc-alpha
On 22-07-2014 21:40, Allan McRae wrote:
> On 23/07/14 03:31, Adhemerval Zanella wrote:
>> Allan,
>>
>> Do you think is it good to add for 2.20?
>>
> I'm going to say too late for this one. I looked at the patch a thought
> it was a big intrusive for this stage and then noted Roland comment
> suggesting it was too close to 2.20 to be included. So I am taking the
> cautious approach here.
>
> Allan
>
Fair enough, I will push it when 2.21 opens.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-23 13:56 ` Adhemerval Zanella
@ 2014-09-10 14:20 ` Adhemerval Zanella
2014-09-22 15:01 ` Adhemerval Zanella
0 siblings, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2014-09-10 14:20 UTC (permalink / raw)
To: libc-alpha
On 23-07-2014 10:56, Adhemerval Zanella wrote:
> On 22-07-2014 21:40, Allan McRae wrote:
>> On 23/07/14 03:31, Adhemerval Zanella wrote:
>>> Allan,
>>>
>>> Do you think is it good to add for 2.20?
>>>
>> I'm going to say too late for this one. I looked at the patch a thought
>> it was a big intrusive for this stage and then noted Roland comment
>> suggesting it was too close to 2.20 to be included. So I am taking the
>> cautious approach here.
>>
>> Allan
>>
> Fair enough, I will push it when 2.21 opens.
>
Ping.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-09-10 14:20 ` Adhemerval Zanella
@ 2014-09-22 15:01 ` Adhemerval Zanella
0 siblings, 0 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2014-09-22 15:01 UTC (permalink / raw)
To: libc-alpha
On 10-09-2014 11:19, Adhemerval Zanella wrote:
> On 23-07-2014 10:56, Adhemerval Zanella wrote:
>> On 22-07-2014 21:40, Allan McRae wrote:
>>> On 23/07/14 03:31, Adhemerval Zanella wrote:
>>>> Allan,
>>>>
>>>> Do you think is it good to add for 2.20?
>>>>
>>> I'm going to say too late for this one. I looked at the patch a thought
>>> it was a big intrusive for this stage and then noted Roland comment
>>> suggesting it was too close to 2.20 to be included. So I am taking the
>>> cautious approach here.
>>>
>>> Allan
>>>
>> Fair enough, I will push it when 2.21 opens.
>>
> Ping.
>
Ping.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-23 0:40 ` Allan McRae
2014-07-23 13:56 ` Adhemerval Zanella
@ 2014-10-07 6:57 ` Stefani Seibold
2014-10-08 21:56 ` Roland McGrath
1 sibling, 1 reply; 27+ messages in thread
From: Stefani Seibold @ 2014-10-07 6:57 UTC (permalink / raw)
To: Allan McRae; +Cc: Adhemerval Zanella, Roland McGrath, GNU C. Library
Hi,
i still wait that this patch will be applied to improve the performance
of i386 applications. Anything wrong with this patch?
Stefani
Am Mittwoch, den 23.07.2014, 10:40 +1000 schrieb Allan McRae:
> On 23/07/14 03:31, Adhemerval Zanella wrote:
> > Allan,
> >
> > Do you think is it good to add for 2.20?
> >
>
> I'm going to say too late for this one. I looked at the patch a thought
> it was a big intrusive for this stage and then noted Roland comment
> suggesting it was too close to 2.20 to be included. So I am taking the
> cautious approach here.
>
> Allan
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v2] Add x86 32 bit vDSO time function support
2014-07-10 14:33 ` Adhemerval Zanella
2014-07-22 17:32 ` Adhemerval Zanella
@ 2014-08-02 16:48 ` Mike Frysinger
1 sibling, 0 replies; 27+ messages in thread
From: Mike Frysinger @ 2014-08-02 16:48 UTC (permalink / raw)
To: libc-alpha; +Cc: Adhemerval Zanella
[-- Attachment #1: Type: text/plain, Size: 140 bytes --]
fyi: if you use the -C/-M flags, the diff output will indicate moved files and
make it easier to see what you changed vs just moved
-mike
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2014-11-27 17:38 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-09 18:31 [PATCH v2] Add x86 32 bit vDSO time function support Adhemerval Zanella
2014-10-09 20:50 ` Nathan Lynch
2014-11-03 20:30 ` Adhemerval Zanella
2014-11-03 21:42 ` Adhemerval Zanella
2014-11-03 23:51 ` Nathan Lynch
2014-11-05 12:51 ` Adhemerval Zanella
2014-11-05 16:22 ` Nathan Lynch
2014-11-14 19:19 ` Adhemerval Zanella
2014-11-27 17:38 ` Adhemerval Zanella
-- strict thread matches above, loose matches on Subject: below --
2014-11-19 7:53 Stefani Seibold
2014-06-27 21:21 Adhemerval Zanella
2014-06-27 21:58 ` Roland McGrath
2014-06-29 15:57 ` Adhemerval Zanella
2014-07-07 18:01 ` Adhemerval Zanella
2014-07-09 20:02 ` Roland McGrath
2014-07-10 14:33 ` Adhemerval Zanella
2014-07-22 17:32 ` Adhemerval Zanella
2014-07-23 0:40 ` Allan McRae
2014-07-23 13:56 ` Adhemerval Zanella
2014-09-10 14:20 ` Adhemerval Zanella
2014-09-22 15:01 ` Adhemerval Zanella
2014-10-07 6:57 ` Stefani Seibold
2014-10-08 21:56 ` Roland McGrath
2014-10-08 22:02 ` Adhemerval Zanella
2014-10-08 22:15 ` Roland McGrath
2014-10-08 22:31 ` Adhemerval Zanella
2014-08-02 16:48 ` Mike Frysinger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).