From 0480c901736591179cdf675697df7ea476720b90 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 8 Jan 2009 00:28:23 +0000 Subject: [PATCH] * sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h: New file. * sysdeps/unix/sysv/linux/s390/gettimeofday.c: New file. * sysdeps/unix/sysv/linux/s390/init-first.c: New file. * sysdeps/unix/sysv/linux/s390/Makefile (sysdep_routines): Add dl-vdso for elf subdir. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h (INLINE_VSYSCALL, INTERNAL_VSYSCALL, INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK, INTERNAL_SYSCALL_NCS, HAVE_CLOCK_GETRES_VSYSCALL and HAVE_CLOCK_GETTIME_VSYSCALL: Define. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/s390/Versions: New file. --- ChangeLog | 14 ++++ sysdeps/unix/sysv/linux/s390/Makefile | 4 + sysdeps/unix/sysv/linux/s390/Versions | 6 ++ sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h | 35 +++++++++ sysdeps/unix/sysv/linux/s390/gettimeofday.c | 42 +++++++++++ sysdeps/unix/sysv/linux/s390/init-first.c | 50 +++++++++++++ sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h | 101 ++++++++++++++++++++++++- sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h | 102 +++++++++++++++++++++++++- 8 files changed, 352 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/s390/Versions create mode 100644 sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h create mode 100644 sysdeps/unix/sysv/linux/s390/gettimeofday.c create mode 100644 sysdeps/unix/sysv/linux/s390/init-first.c diff --git a/ChangeLog b/ChangeLog index 03d50cf..182bd26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-01-05 Martin Schwidefsky + + * sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h: New file. + * sysdeps/unix/sysv/linux/s390/gettimeofday.c: New file. + * sysdeps/unix/sysv/linux/s390/init-first.c: New file. + * sysdeps/unix/sysv/linux/s390/Makefile (sysdep_routines): Add dl-vdso + for elf subdir. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h (INLINE_VSYSCALL, + INTERNAL_VSYSCALL, INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK, + INTERNAL_SYSCALL_NCS, HAVE_CLOCK_GETRES_VSYSCALL and + HAVE_CLOCK_GETTIME_VSYSCALL: Define. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/Versions: New file. + 2008-12-31 Paolo Bonzini * posix/regcomp.c (re_compile_fastmap_iter): Use __mbrtowc. diff --git a/sysdeps/unix/sysv/linux/s390/Makefile b/sysdeps/unix/sysv/linux/s390/Makefile index 5c53818..72eae68 100644 --- a/sysdeps/unix/sysv/linux/s390/Makefile +++ b/sysdeps/unix/sysv/linux/s390/Makefile @@ -6,3 +6,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/s390/Versions b/sysdeps/unix/sysv/linux/s390/Versions new file mode 100644 index 0000000..627ff53 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/Versions @@ -0,0 +1,6 @@ +libc { + GLIBC_PRIVATE { + __vdso_clock_gettime; + __vdso_clock_getres; + } +} diff --git a/sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h new file mode 100644 index 0000000..f289f9a --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/bits/libc-vdso.h @@ -0,0 +1,35 @@ +/* Resolve function pointers to VDSO functions. + Copyright (C) 2008 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +#ifndef _LIBC_VDSO_H +#define _LIBC_VDSO_H + +#ifdef SHARED + +extern long int (*__vdso_gettimeofday) (struct timeval *, void *) + attribute_hidden; + +extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *); + +extern long int (*__vdso_clock_getres) (clockid_t, struct timespec *); + +#endif + +#endif /* _LIBC_VDSO_H */ diff --git a/sysdeps/unix/sysv/linux/s390/gettimeofday.c b/sysdeps/unix/sysv/linux/s390/gettimeofday.c new file mode 100644 index 0000000..1914c3b --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/gettimeofday.c @@ -0,0 +1,42 @@ +/* Copyright (C) 2008 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include + +#undef __gettimeofday +#include + +/* Get the current time of day and timezone information, + putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. + Returns 0 on success, -1 on errors. */ + +int +__gettimeofday (tv, tz) + struct timeval *tv; + struct timezone *tz; +{ + return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz)); +} + +INTDEF (__gettimeofday) +weak_alias (__gettimeofday, gettimeofday) diff --git a/sysdeps/unix/sysv/linux/s390/init-first.c b/sysdeps/unix/sysv/linux/s390/init-first.c new file mode 100644 index 0000000..7091aac --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/init-first.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2008 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifdef SHARED +# include +# undef __gettimeofday +# undef __clock_gettime +# undef __clock_getres +# include + +long int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden; + +long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) + __attribute__ ((nocommon)); +strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden) + +long int (*__vdso_clock_getres) (clockid_t, struct timespec *) + __attribute__ ((nocommon)); +strong_alias (__vdso_clock_getres, __GI___vdso_clock_getres attribute_hidden) + + +static inline void +_libc_vdso_platform_setup (void) +{ + PREPARE_VERSION (linux2629, "LINUX_2.6.29", 123718585); + + __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2629); + __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2629); + __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2629); +} + +# define VDSO_SETUP _libc_vdso_platform_setup +#endif + +#include "../init-first.c" diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h index b86072b..5bfdc44 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -26,6 +26,11 @@ #include /* For RTLD_PRIVATE_ERRNO. */ #include +/* Define __set_errno() for INLINE_SYSCALL macro below. */ +#ifndef __ASSEMBLER__ +#include +#endif + /* For Linux we can use the system call table in the header file /usr/include/asm/unistd.h of the kernel. But these symbols do not follow the SYS_* syntax @@ -276,6 +281,100 @@ #define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6) #define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7) +#define CLOBBER_0 , "3", "4", "5" +#define CLOBBER_1 , "3", "4", "5" +#define CLOBBER_2 , "4", "5" +#define CLOBBER_3 , "5" +#define CLOBBER_4 +#define CLOBBER_5 +#define CLOBBER_6 + +/* List of system calls which are supported as vsyscalls. */ +#define HAVE_CLOCK_GETRES_VSYSCALL 1 +#define HAVE_CLOCK_GETTIME_VSYSCALL 1 + +/* This version is for kernels that implement system calls that + behave like function calls as far as register saving. + It falls back to the syscall in the case that the vDSO doesn't + exist or fails for ENOSYS */ +#ifdef SHARED +# define INLINE_VSYSCALL(name, nr, args...) \ + ({ \ + __label__ out; \ + __label__ iserr; \ + long int _ret; \ + \ + if (__vdso_##name != NULL) \ + { \ + _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, , nr, ##args); \ + if (!INTERNAL_SYSCALL_ERROR_P (_ret, )) \ + goto out; \ + if (INTERNAL_SYSCALL_ERRNO (_ret, ) != ENOSYS) \ + goto iserr; \ + } \ + \ + _ret = INTERNAL_SYSCALL (name, , nr, ##args); \ + if (INTERNAL_SYSCALL_ERROR_P (_ret, )) \ + { \ + iserr: \ + __set_errno (INTERNAL_SYSCALL_ERRNO (_ret, )); \ + _ret = -1L; \ + } \ + out: \ + (int) _ret; \ + }) +#else +# define INLINE_VSYSCALL(name, nr, args...) \ + INLINE_SYSCALL (name, nr, ##args) +#endif + +#ifdef SHARED +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + ({ \ + __label__ out; \ + long int _ret; \ + \ + if (__vdso_##name != NULL) \ + { \ + _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ + if (!INTERNAL_SYSCALL_ERROR_P (_ret, err) \ + || INTERNAL_SYSCALL_ERRNO (_ret, err) != ENOSYS) \ + goto out; \ + } \ + _ret = INTERNAL_SYSCALL (name, err, nr, ##args); \ + out: \ + _ret; \ + }) +#else +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL (name, err, nr, ##args) +#endif + +/* This version is for internal uses when there is no desire + to set errno */ +#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \ + ({ \ + long int _ret = ENOSYS; \ + \ + if (__vdso_##name != NULL) \ + _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ + else \ + err = 1 << 28; \ + _ret; \ + }) + +#define INTERNAL_VSYSCALL_NCS(fn, err, nr, args...) \ + ({ \ + DECLARGS_##nr(args) \ + register long _ret asm("2"); \ + asm volatile ( \ + "lr 11,14\n\t" \ + "basr 14,%1\n\t" \ + "lr 14,11\n\t" \ + : "=d" (_ret) \ + : "d" (fn) ASMFMT_##nr \ + : "cc", "memory", "0", "1", "11" CLOBBER_##nr); \ + _ret; }) /* Pointer mangling support. */ #if defined NOT_IN_libc && defined IS_IN_rtld diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h index 9ddec8e..6491a3b 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h @@ -1,5 +1,5 @@ /* Assembler macros for 64 bit S/390. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -27,6 +27,11 @@ #include /* For RTLD_PRIVATE_ERRNO. */ #include +/* Define __set_errno() for INLINE_SYSCALL macro below. */ +#ifndef __ASSEMBLER__ +#include +#endif + /* For Linux we can use the system call table in the header file /usr/include/asm/unistd.h of the kernel. But these symbols do not follow the SYS_* syntax @@ -278,6 +283,101 @@ #define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6) #define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7) +#define CLOBBER_0 , "3", "4", "5" +#define CLOBBER_1 , "3", "4", "5" +#define CLOBBER_2 , "4", "5" +#define CLOBBER_3 , "5" +#define CLOBBER_4 +#define CLOBBER_5 +#define CLOBBER_6 + +/* List of system calls which are supported as vsyscalls. */ +#define HAVE_CLOCK_GETRES_VSYSCALL 1 +#define HAVE_CLOCK_GETTIME_VSYSCALL 1 + +/* This version is for kernels that implement system calls that + behave like function calls as far as register saving. + It falls back to the syscall in the case that the vDSO doesn't + exist or fails for ENOSYS */ +#ifdef SHARED +# define INLINE_VSYSCALL(name, nr, args...) \ + ({ \ + __label__ out; \ + __label__ iserr; \ + long int _ret; \ + \ + if (__vdso_##name != NULL) \ + { \ + _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, , nr, ##args); \ + if (!INTERNAL_SYSCALL_ERROR_P (_ret, )) \ + goto out; \ + if (INTERNAL_SYSCALL_ERRNO (_ret, ) != ENOSYS) \ + goto iserr; \ + } \ + \ + _ret = INTERNAL_SYSCALL (name, , nr, ##args); \ + if (INTERNAL_SYSCALL_ERROR_P (_ret, )) \ + { \ + iserr: \ + __set_errno (INTERNAL_SYSCALL_ERRNO (_ret, )); \ + _ret = -1L; \ + } \ + out: \ + (int) _ret; \ + }) +#else +# define INLINE_VSYSCALL(name, nr, args...) \ + INLINE_SYSCALL (name, nr, ##args) +#endif + +#ifdef SHARED +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + ({ \ + __label__ out; \ + long int _ret; \ + \ + if (__vdso_##name != NULL) \ + { \ + _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ + if (!INTERNAL_SYSCALL_ERROR_P (_ret, err) \ + || INTERNAL_SYSCALL_ERRNO (_ret, err) != ENOSYS) \ + goto out; \ + } \ + _ret = INTERNAL_SYSCALL (name, err, nr, ##args); \ + out: \ + _ret; \ + }) +#else +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL (name, err, nr, ##args) +#endif + +/* This version is for internal uses when there is no desire + to set errno */ +#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \ + ({ \ + long int _ret = ENOSYS; \ + \ + if (__vdso_##name != NULL) \ + _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ + else \ + err = 1 << 28; \ + _ret; \ + }) + +#define INTERNAL_VSYSCALL_NCS(fn, err, nr, args...) \ + ({ \ + DECLARGS_##nr(args) \ + register long _ret asm("2"); \ + asm volatile ( \ + "lgr 11,14\n\t" \ + "basr 14,%1\n\t" \ + "lgr 14,11\n\t" \ + : "=d" (_ret) \ + : "a" (fn) ASMFMT_##nr \ + : "cc", "memory", "0", "1", "11" CLOBBER_##nr); \ + _ret; }) + /* Pointer mangling support. */ #if defined NOT_IN_libc && defined IS_IN_rtld /* We cannot use the thread descriptor because in ld.so we use setjmp -- 2.7.4