From patchwork Fri Jun 14 15:29:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 166838 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp2202740ilk; Fri, 14 Jun 2019 08:31:13 -0700 (PDT) X-Google-Smtp-Source: APXvYqw8qtlX7HBeuQNdRZzwOvFqxYfN0pZRUzRxDI5wVraJc407S2xjt1zSTByBxfoxCK49wkGP X-Received: by 2002:a17:90a:aa0a:: with SMTP id k10mr12048012pjq.43.1560526272985; Fri, 14 Jun 2019 08:31:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560526272; cv=none; d=google.com; s=arc-20160816; b=sp5fBBvVxYevURXiw9Q7OyDAq7KLooVAT8ucZsuIHYIxNSZ6rGqJKSKSHQKx84MRZK Y8XoYEmP3vRElosRba8PJ4QdYoS44dM6jSPh4gEBWXd+pEm8jP9RR5vdu9eB+tHK0pm2 soiizdBalnaLo4jzWAQHGoUFE0eTSs7J7LJ7fNSfP4CzULi/OtjN8m9d6oXkbTdR5jRy qitsF+zk0C8jHOruIT9j7UAceTt/9qVXeN8ch4+xpaSAt71QxntIZUuMq5PrUiMZfS3t GqRT1n6QknqO2bkKhJXh1uaiGpY8pdUuxXquaHLTZIM8ShoYBwpNg0nKGBU+XFx82Kar Tp2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=9mx2Zq7+E5rqyKV5yIwk6jVCstmUNz+A750UrBVIDAw=; b=IdH8pox/P+DZ9J/r6bC9UayeD+8f5l+/sDuN63sodRPNiChqtVmQia3FCF3y679euK DrBtyI1eA7YcMFk6nLTVJxmKAHKwH8xF6MlD4VGgI7GJrFCU1RzLDurq4kJJCCFVm2S/ x+pHiui02TOpsyQCwoq+sgh9IARN14ubd7bhk8DF7MEEm/2NVsU7U08fXb6e7OAlaaVx ynxBsiDCrx9md7/rp3i2CRgaKlBJKRVXK0WFvR2Dw62/pxHeFWSo7AwvQGIVxUROKWz/ /cl+aJE2t/FYs/w8mcRSrTxhUHF3o6zFWPAsCWVGDKcxK+wDaup/igkGWHOUFJWOiS8u oUhg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=JlfpyqMK; dkim=pass header.i=@linaro.org header.s=google header.b=TDxbgDen; spf=pass (google.com: domain of libc-alpha-return-102744-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-102744-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id n34si2113398pld.202.2019.06.14.08.31.12 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Jun 2019 08:31:12 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-102744-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=JlfpyqMK; dkim=pass header.i=@linaro.org header.s=google header.b=TDxbgDen; spf=pass (google.com: domain of libc-alpha-return-102744-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-102744-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=oOAEbTkKNpoXiVVLL2udhGYRR+dAIHx PGumhRImDpo8/PHJeTIMS8tTl5pJJQRpAupAZQg77NwhzNLebAHmDvhOl+UJ9Ucw WHYIh5FfRlyWULcQYZsEvEjmzovOfdCniiwB92OA4uG0JFhZDD3P9imG7fJ3ib3o YEaAPJbjaFRw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=51zOexYZVnTWD9xvMcC/iG9UeAI=; b=Jlfpy qMKO9rcKmLdrUbmzUmW+EVFQsWJV7Fpe9DGcgqEW+SbvkhfqBNyN/EsVOH2CypcK BZFi1EWIHd7aUoIx3PmOrHwjJy2klEq26pZ4A/Tzn6UMebXlJsZJO2JrFg5Vw6tu UWFmLjJLqioq6VE7GKV9CzvB+ncitrQYrhhip8= Received: (qmail 118531 invoked by alias); 14 Jun 2019 15:29:32 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 118370 invoked by uid 89); 14 Jun 2019 15:29:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_JMF_BR, SPF_PASS, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 spammy=HX-Received:ea04, 1527 X-HELO: mail-vs1-f66.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=9mx2Zq7+E5rqyKV5yIwk6jVCstmUNz+A750UrBVIDAw=; b=TDxbgDen3lp8BYQOjEFZySBw0WLdQShjtv2bNgD0rAX314MG1slukZb6/FLN2FU0zF +UtpJWvYZNi7RPWjfljhoOEsikQz4x+8QptucTGqr6j2Ma2hvNgf/QMAH/zvh8i5ELxA ky1lxxjp3vDkaXkv48kLMO1IirXYiT9K1N5t5ImHuE6M69wnjOc+txuPjtzwhwN5bQSO LFh7YMDMiTI9gDSj4+goTzt9yUXUwzYmKews5+U73WH20oM2ZSHFr38ph5jT5fILSxt/ f53ekWOYC/KbBT3Qw9fxcL4vfBBh8vLhOGnnYHicLnJEcGj7e5MGzTHI07km5cLtJWVH 8d7A== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 11/12] linux: Consolidate time implementation Date: Fri, 14 Jun 2019 12:29:07 -0300 Message-Id: <20190614152908.8101-11-adhemerval.zanella@linaro.org> In-Reply-To: <20190614152908.8101-1-adhemerval.zanella@linaro.org> References: <20190614152908.8101-1-adhemerval.zanella@linaro.org> The time syscall has currently 3 possible implementations: 1. Wire-up __NR_time with a vDSO implementation (currently only x86 and powerpc). 2. Wire-up __NR_time (hppa, i686, m68k, microblaze, mips, powerpc, powerpc64, s390, sh4, sparcv9, x86_64). 3. Using internal gettimeofday (aarch64, alpha, arm, mips64, mips64-n32, nios2, s390x, sparc64). This patch consolidates all implementation on Linux generic sysdeps/unix/sysv/linux/time.c. To simplify the code, some changes are made: * The wire-up with vDSO implementation route external calls directly to vDSO through IFUNC. To enable it the architecture need to explicit define USE_TIME_VSYSCALL_IFUNC. * Also, powerpc and x86 tries to route internal time usages to IFUNC mechanism, which is problematic since powerpc32 and i686 does not really support it. Instead, all internal calls are routed to a default internal symbol which in turn calls INTERNAL_VSYSCALL. * Static linking also uses the fallback mechanism which calls INTERNAL_VSYSCALL, so vDSO is used for this case as well. The generic implementation issues a syscall as default, calls the vDSO if the architecture defines HAVE_TIME_VSYSCALL, and route the external calls to iFUNC if the architecture also defines USE_TIME_VSYSCALL_IFUNC. Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc-linux-gnu, powerpc64-linux-gnu, powerpc64le-linux-gnu, and aarch64-linux-gnu. * include/libc-symbols.h (hidden_def_redir): New macro. * sysdeps/unix/sysv/linux/i386/sysdep.h (HAVE_TIME_VSYSCALL, USE_TIME_VSYSCALL_IFUNC): Define. * sysdeps/unix/sysv/linux/x86_64/sysdep.h (HAVE_TIME_VSYSCALL, USE_TIME_VSYSCALL_IFUNC): Likewise. * sysdeps/unix/sysv/linux/powerpc/sysdep.h (USE_TIME_VSYSCALL_IFUNC): Likewise. * sysdeps/unix/sysv/linux/i386/time.c: Remove file. * sysdeps/unix/sysv/linux/x86/time.c: Likewise. * sysdeps/unix/sysv/linux/powerpc/time.c: Likewise. * sysdeps/unix/sysv/linux/time.c (time): Handle all possible Linux implementations (wire-up syscall, vDSO implementation, iFUNC). (time_syscall): New function. --- include/libc-symbols.h | 5 ++ sysdeps/unix/sysv/linux/i386/sysdep.h | 2 + sysdeps/unix/sysv/linux/i386/time.c | 34 ---------- sysdeps/unix/sysv/linux/powerpc/sysdep.h | 1 + sysdeps/unix/sysv/linux/powerpc/time.c | 83 ------------------------ sysdeps/unix/sysv/linux/time.c | 53 ++++++++++++--- sysdeps/unix/sysv/linux/x86/time.c | 60 ----------------- sysdeps/unix/sysv/linux/x86_64/sysdep.h | 2 + 8 files changed, 55 insertions(+), 185 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/i386/time.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/time.c delete mode 100644 sysdeps/unix/sysv/linux/x86/time.c -- 2.17.1 diff --git a/include/libc-symbols.h b/include/libc-symbols.h index b68ec4b7f5..dc6f2e31e2 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -548,6 +548,7 @@ for linking") # define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name); # define hidden_data_ver(local, name) hidden_ver(local, name) # define hidden_def(name) __hidden_ver1(__GI_##name, name, name); +# define hidden_def_redir(redir, name) __hidden_ver1(redir, __GI_##name, redir); # define hidden_data_def(name) hidden_def(name) # define hidden_tls_def(name) \ __hidden_ver2 (__thread, __GI_##name, name, name); @@ -575,6 +576,7 @@ for linking") hidden_proto doesn't make sense for assembly but the equivalent is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */ # define hidden_def(name) strong_alias (name, __GI_##name) +# define hidden_def_redir(redir, name) strong_alias(redir, __GI_##name); # define hidden_weak(name) hidden_def (name) # define hidden_ver(local, name) strong_alias (local, __GI_##name) # define hidden_data_def(name) strong_data_alias (name, __GI_##name) @@ -605,6 +607,7 @@ for linking") # endif /* Not __ASSEMBLER__ */ # define hidden_weak(name) # define hidden_def(name) +# define hidden_def_redir(redir, name) # define hidden_ver(local, name) # define hidden_data_weak(name) # define hidden_data_def(name) @@ -617,6 +620,7 @@ for linking") # define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) # define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs) # define libc_hidden_def(name) hidden_def (name) +# define libc_hidden_def_redir(redir, name) hidden_def_redir (redir, name) # define libc_hidden_weak(name) hidden_weak (name) # ifdef LINK_OBSOLETE_RPC /* libc_hidden_nolink_sunrpc should only get used in sunrpc code. */ @@ -633,6 +637,7 @@ for linking") # define libc_hidden_proto(name, attrs...) # define libc_hidden_tls_proto(name, attrs...) # define libc_hidden_def(name) +# define libc_hidden_def_redir(redir, name) # define libc_hidden_weak(name) # define libc_hidden_ver(local, name) # define libc_hidden_data_def(name) diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index e793fdc936..4f79f25989 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -315,6 +315,8 @@ struct libc_do_syscall_args /* List of system calls which are supported as vsyscalls. */ # define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime" # define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday" +# define HAVE_TIME_VSYSCALL "__vdso_time" +# define USE_TIME_VSYSCALL_IFUNC 1 /* Define a macro which expands inline into the wrapper code for a system call. This use is for internal calls that do not need to handle errors diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c deleted file mode 100644 index 440e3e6ab4..0000000000 --- a/sysdeps/unix/sysv/linux/i386/time.c +++ /dev/null @@ -1,34 +0,0 @@ -/* time -- Get number of seconds since Epoch. Linux/i386 version. - Copyright (C) 2015-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef SHARED -# define time __redirect_time -#endif - -#include - -#ifdef SHARED -# undef time -# define time_type __redirect_time - -# undef libc_hidden_def -# define libc_hidden_def(name) \ - __hidden_ver1 (__time_syscall, __GI_time, __time_syscall); -#endif - -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h index cf967a8c33..44bfa3f1b6 100644 --- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h @@ -24,6 +24,7 @@ #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime" #define HAVE_GETCPU_VSYSCALL "__kernel_getcpu" #define HAVE_TIME_VSYSCALL "__kernel_time" +#define USE_TIME_VSYSCALL_IFUNC 1 #define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday" #define HAVE_GET_TBFREQ "__kernel_get_tbfreq" diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c deleted file mode 100644 index ca6721cf95..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/time.c +++ /dev/null @@ -1,83 +0,0 @@ -/* time system call for Linux/PowerPC. - Copyright (C) 2013-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef SHARED -# ifndef __powerpc64__ -# define time __redirect_time -# else -# define __redirect_time time -# endif - -# include -# include -# include -# include -# include - -# ifndef __powerpc64__ -# undef time - -time_t -__time_vsyscall (time_t *t) -{ - return INLINE_VSYSCALL (time, 1, t); -} - -/* __GI_time is defined as hidden and for ppc32 it enables the - compiler make a local call (symbol@local) for internal GLIBC usage. It - means the PLT won't be used and the ifunc resolver will be called directly. - For ppc64 a call to a function in another translation unit might use a - different toc pointer thus disallowing direct branchess and making internal - ifuncs calls safe. */ -# undef libc_hidden_def -# define libc_hidden_def(name) \ - __hidden_ver1 (__time_vsyscall, __GI_time, __time_vsyscall); - -# endif /* !__powerpc64__ */ - -static time_t -time_syscall (time_t *t) -{ - struct timeval tv; - time_t result; - - if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0) - result = (time_t) -1; - else - result = (time_t) tv.tv_sec; - - if (t != NULL) - *t = result; - return result; -} - -# define INIT_ARCH() \ - void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL); - -/* If the vDSO is not available we fall back to the syscall. */ -libc_ifunc_hidden (__redirect_time, time, - vdso_time - ? vdso_time - : (void *) time_syscall); -libc_hidden_def (time) - -#else - -#include - -#endif /* !SHARED */ diff --git a/sysdeps/unix/sysv/linux/time.c b/sysdeps/unix/sysv/linux/time.c index 1978f6d817..93e036fe16 100644 --- a/sysdeps/unix/sysv/linux/time.c +++ b/sysdeps/unix/sysv/linux/time.c @@ -15,27 +15,64 @@ License along with the GNU C Library; if not, see . */ -#include +/* Currently we have 3 possible time implementations, which is also selected + in the order: + + 1. Wire-up __NR_time with a vDSO implementation (currently only x86 and + powerpc). + 2. Only wire-up __NR_time (usually old kABIs). + 3. Using internal gettimeofday (which may call a vDSO as well). */ + +#define time __redirect_time #include +#undef time +#include #include +#ifdef HAVE_TIME_VSYSCALL +# define HAVE_VSYSCALL +#endif +#include +#include -#ifdef __NR_time - -time_t -time (time_t *t) +static time_t +time_syscall (time_t *t) { + time_t res; +#ifdef __NR_time INTERNAL_SYSCALL_DECL (err); - time_t res = INTERNAL_SYSCALL (time, err, 1, NULL); + res = INTERNAL_VSYSCALL (time, err, 1, NULL); /* There cannot be any error. */ +#else + struct timeval tv; + /* gettimeofday does not fail with valid 'tv' and null timezone. */ + __gettimeofday (&tv, NULL); + res = tv.tv_sec; +#endif if (t != NULL) *t = res; return res; } -libc_hidden_def (time) +#if HAVE_IFUNC && defined USE_TIME_VSYSCALL_IFUNC +/* Route externals calls direct to vDSO and static and internal calls to + fallback implementation (which also might call the vDSO). */ +# ifdef SHARED +# define INIT_ARCH() +libc_ifunc_redirected (__redirect_time, time, + get_vdso_symbol (HAVE_TIME_VSYSCALL) + ?: time_syscall); +libc_hidden_def_redir (time_syscall, time) +# else +strong_alias (time_syscall, time) +# endif /* SHARED */ #else -# include +time_t +time (time_t *t) +{ + return time_syscall (t); +} +libc_hidden_def_redir (time, time) #endif diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c deleted file mode 100644 index 60e6d1b7c0..0000000000 --- a/sysdeps/unix/sysv/linux/x86/time.c +++ /dev/null @@ -1,60 +0,0 @@ -/* time -- Get number of seconds since Epoch. Linux/x86 version. - Copyright (C) 2015-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -#ifdef SHARED - -#include -#include -#include - -static time_t -__time_syscall (time_t *t) -{ - INTERNAL_SYSCALL_DECL (err); - return INTERNAL_SYSCALL (time, err, 1, t); -} - -# ifndef time_type -/* The i386 time.c includes this file with a defined time_type macro. - For x86_64 we have to define it to time as the internal symbol is the - ifunc'ed one. */ -# define time_type time -# endif - -#undef INIT_ARCH -#define INIT_ARCH() - -/* If the vDSO is not available we fall back on the syscall. */ -libc_ifunc_hidden (time_type, time, - (get_vdso_symbol ("__vdso_time") ?: __time_syscall)) -libc_hidden_def (time) - -#else - -# include - -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_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 4541c0d492..c64fbd1e26 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -376,6 +376,8 @@ /* List of system calls which are supported as vsyscalls. */ # define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime" # define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday" +# define HAVE_TIME_VSYSCALL "__vdso_time" +# define USE_TIME_VSYSCALL_IFUNC 1 # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu" # define SINGLE_THREAD_BY_GLOBAL 1