[resend] Add x86 32 bit vDSO time function support

Message ID 54871622.807@linux.vnet.ibm.com
State Committed
Delegated to: Adhemerval Zanella Netto
Headers

Commit Message

Adhemerval Zanella Netto Dec. 9, 2014, 3:32 p.m. UTC
  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 avaiable.

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.

Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.

--

2014-12-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.

--
  

Comments

Adhemerval Zanella Netto Jan. 6, 2015, 2:35 p.m. UTC | #1
Ping.

On 09-12-2014 13:32, Adhemerval Zanella wrote:
> 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 avaiable.
>
> 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.
>
> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>
> --
>
> 2014-12-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..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"
>
  
H.J. Lu Jan. 12, 2015, 12:38 p.m. UTC | #2
On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
<azanella@linux.vnet.ibm.com> wrote:
> Ping.
>
> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>> 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 avaiable.
>>
>> 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.
>>
>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>
>> --
>>
>> 2014-12-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.
>>
>

1.  Please update copyright year to 2015.
2.  Please update sysdeps/unix/sysv/linux/x86_64/x32/init-first.c:

#ifdef SHARED
# include <dl-vdso.h>
# include <bits/libc-vdso.h>
                ^^^^^^^^^^^^^^^^^^

Your patch moves this file.
  
H.J. Lu Jan. 12, 2015, 1:51 p.m. UTC | #3
On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
<azanella@linux.vnet.ibm.com> wrote:
> Ping.
>
> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>> 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 avaiable.
>>
>> 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.
>>
>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>
>> --
>>
>> 2014-12-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.
>>
>> --
>>

>> +# 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)

Why do you define __GI___gettimeofday to __gettimeofday_syscall
instead of the ifunc version? The x86-64 ifunc  works fine.
  
H.J. Lu Jan. 12, 2015, 2:28 p.m. UTC | #4
On Mon, Jan 12, 2015 at 5:51 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
> <azanella@linux.vnet.ibm.com> wrote:
>> Ping.
>>
>> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>>> 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 avaiable.
>>>
>>> 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.
>>>
>>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>>
>>> --
>>>
>>> 2014-12-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.
>>>
>>> --
>>>
>
>>> +# 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)
>
> Why do you define __GI___gettimeofday to __gettimeofday_syscall
> instead of the ifunc version? The x86-64 ifunc  works fine.
>
> --
> H.J.

Why isn't __GI_time IFUNC

5822: 000a3360    21 FUNC    LOCAL  DEFAULT   13 __GI_time
  
H.J. Lu Jan. 12, 2015, 2:49 p.m. UTC | #5
On Mon, Jan 12, 2015 at 6:28 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Jan 12, 2015 at 5:51 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
>> <azanella@linux.vnet.ibm.com> wrote:
>>> Ping.
>>>
>>> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>>>> 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 avaiable.
>>>>
>>>> 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.
>>>>
>>>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>>>
>>>> --
>>>>
>>>> 2014-12-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.
>>>>
>>>> --
>>>>
>>
>>>> +# 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)
>>
>> Why do you define __GI___gettimeofday to __gettimeofday_syscall
>> instead of the ifunc version? The x86-64 ifunc  works fine.
>>
>> --
>> H.J.
>
> Why isn't __GI_time IFUNC
>
> 5822: 000a3360    21 FUNC    LOCAL  DEFAULT   13 __GI_time
>

The key to call local IFUNC function is that we HAVE to tell GCC
it is a global function, not local so that it will go through PLT.
Otherwise GCC will perform optimization which will break local
IFUNC.  I will see what I can do.
  
H.J. Lu Jan. 12, 2015, 3:59 p.m. UTC | #6
On Mon, Jan 12, 2015 at 6:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Jan 12, 2015 at 6:28 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Mon, Jan 12, 2015 at 5:51 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
>>> <azanella@linux.vnet.ibm.com> wrote:
>>>> Ping.
>>>>
>>>> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>>>>> 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 avaiable.
>>>>>
>>>>> 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.
>>>>>
>>>>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>>>>
>>>>> --
>>>>>
>>>>> 2014-12-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.
>>>>>
>>>>> --
>>>>>
>>>
>>>>> +# 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)
>>>
>>> Why do you define __GI___gettimeofday to __gettimeofday_syscall
>>> instead of the ifunc version? The x86-64 ifunc  works fine.
>>>
>>> --
>>> H.J.
>>
>> Why isn't __GI_time IFUNC
>>
>> 5822: 000a3360    21 FUNC    LOCAL  DEFAULT   13 __GI_time
>>
>
> The key to call local IFUNC function is that we HAVE to tell GCC
> it is a global function, not local so that it will go through PLT.
> Otherwise GCC will perform optimization which will break local
> IFUNC.  I will see what I can do.
>

This requires too many changes with unknown benefits at this stage.  OK with
copyright year update and sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
fix.

Thanks.
  
Adhemerval Zanella Netto Jan. 12, 2015, 5:35 p.m. UTC | #7
On 12-01-2015 13:59, H.J. Lu wrote:
> On Mon, Jan 12, 2015 at 6:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Mon, Jan 12, 2015 at 6:28 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Mon, Jan 12, 2015 at 5:51 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
>>>> <azanella@linux.vnet.ibm.com> wrote:
>>>>> Ping.
>>>>>
>>>>> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>>>>>> 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 avaiable.
>>>>>>
>>>>>> 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.
>>>>>>
>>>>>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>>>>>
>>>>>> --
>>>>>>
>>>>>> 2014-12-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.
>>>>>>
>>>>>> --
>>>>>>
>>>>>> +# 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)
>>>> Why do you define __GI___gettimeofday to __gettimeofday_syscall
>>>> instead of the ifunc version? The x86-64 ifunc  works fine.
>>>>
>>>> --
>>>> H.J.
>>> Why isn't __GI_time IFUNC
>>>
>>> 5822: 000a3360    21 FUNC    LOCAL  DEFAULT   13 __GI_time
>>>
>> The key to call local IFUNC function is that we HAVE to tell GCC
>> it is a global function, not local so that it will go through PLT.
>> Otherwise GCC will perform optimization which will break local
>> IFUNC.  I will see what I can do.
>>
> This requires too many changes with unknown benefits at this stage.  OK with
> copyright year update and sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
> fix.
>
> Thanks.
>
The idea of this patch is to just provide IFUNC calls externally to GLIBC, internal
calls are still by the syscall.  I didn't really dig into the issues, but what I
could tell i386 suffers from the same issue as powerpc32: __gettimeofday is resolved
as a local call and thus no PLT is created, although the IFUNC is still called.

I will change the copyright and the x32 and push, thanks for the review.
  
H.J. Lu Jan. 12, 2015, 7 p.m. UTC | #8
On Mon, Jan 12, 2015 at 9:35 AM, Adhemerval Zanella
<azanella@linux.vnet.ibm.com> wrote:
> On 12-01-2015 13:59, H.J. Lu wrote:
>> On Mon, Jan 12, 2015 at 6:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Mon, Jan 12, 2015 at 6:28 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> On Mon, Jan 12, 2015 at 5:51 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>> On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
>>>>> <azanella@linux.vnet.ibm.com> wrote:
>>>>>> Ping.
>>>>>>
>>>>>> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>>>>>>> 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 avaiable.
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> 2014-12-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.
>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> +# 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)
>>>>> Why do you define __GI___gettimeofday to __gettimeofday_syscall
>>>>> instead of the ifunc version? The x86-64 ifunc  works fine.
>>>>>
>>>>> --
>>>>> H.J.
>>>> Why isn't __GI_time IFUNC
>>>>
>>>> 5822: 000a3360    21 FUNC    LOCAL  DEFAULT   13 __GI_time
>>>>
>>> The key to call local IFUNC function is that we HAVE to tell GCC
>>> it is a global function, not local so that it will go through PLT.
>>> Otherwise GCC will perform optimization which will break local
>>> IFUNC.  I will see what I can do.
>>>
>> This requires too many changes with unknown benefits at this stage.  OK with
>> copyright year update and sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
>> fix.
>>
>> Thanks.
>>
> The idea of this patch is to just provide IFUNC calls externally to GLIBC, internal
> calls are still by the syscall.  I didn't really dig into the issues, but what I
> could tell i386 suffers from the same issue as powerpc32: __gettimeofday is resolved
> as a local call and thus no PLT is created, although the IFUNC is still called.

The problem on i386 is EBX wasn't set up for calling IFUNC via PLT since
it is local.

> I will change the copyright and the x32 and push, thanks for the review.
>
  
Adhemerval Zanella Netto Jan. 12, 2015, 7:09 p.m. UTC | #9
On 12-01-2015 17:00, H.J. Lu wrote:
> On Mon, Jan 12, 2015 at 9:35 AM, Adhemerval Zanella
> <azanella@linux.vnet.ibm.com> wrote:
>> On 12-01-2015 13:59, H.J. Lu wrote:
>>> On Mon, Jan 12, 2015 at 6:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> On Mon, Jan 12, 2015 at 6:28 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>> On Mon, Jan 12, 2015 at 5:51 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>>> On Tue, Jan 6, 2015 at 6:35 AM, Adhemerval Zanella
>>>>>> <azanella@linux.vnet.ibm.com> wrote:
>>>>>>> Ping.
>>>>>>>
>>>>>>> On 09-12-2014 13:32, Adhemerval Zanella wrote:
>>>>>>>> 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 avaiable.
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> Tested on x86 and x86_64 with a 3.5.0 and a 3.16 kernel.
>>>>>>>>
>>>>>>>> --
>>>>>>>>
>>>>>>>> 2014-12-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.
>>>>>>>>
>>>>>>>> --
>>>>>>>>
>>>>>>>> +# 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)
>>>>>> Why do you define __GI___gettimeofday to __gettimeofday_syscall
>>>>>> instead of the ifunc version? The x86-64 ifunc  works fine.
>>>>>>
>>>>>> --
>>>>>> H.J.
>>>>> Why isn't __GI_time IFUNC
>>>>>
>>>>> 5822: 000a3360    21 FUNC    LOCAL  DEFAULT   13 __GI_time
>>>>>
>>>> The key to call local IFUNC function is that we HAVE to tell GCC
>>>> it is a global function, not local so that it will go through PLT.
>>>> Otherwise GCC will perform optimization which will break local
>>>> IFUNC.  I will see what I can do.
>>>>
>>> This requires too many changes with unknown benefits at this stage.  OK with
>>> copyright year update and sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
>>> fix.
>>>
>>> Thanks.
>>>
>> The idea of this patch is to just provide IFUNC calls externally to GLIBC, internal
>> calls are still by the syscall.  I didn't really dig into the issues, but what I
>> could tell i386 suffers from the same issue as powerpc32: __gettimeofday is resolved
>> as a local call and thus no PLT is created, although the IFUNC is still called.
> The problem on i386 is EBX wasn't set up for calling IFUNC via PLT since
> it is local.
>
>> I will change the copyright and the x32 and push, thanks for the review.
>>
Pushed as ca677d3c3cd0eba7d1f03092517aea553a0e8569.
  

Patch

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"