From patchwork Wed Sep 26 07:30:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Albert ARIBAUD (3ADEV)" X-Patchwork-Id: 974880 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96094-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=3adev.fr Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="y7g/UqWM"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42KqPh6g7Rz9s5c for ; Wed, 26 Sep 2018 17:31:35 +1000 (AEST) 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:cc:subject:date:message-id; q=dns; s= default; b=keNdXo1KIfCb+kAqtu+Y8mOobtNOfy4lSMrhhxJT20TCVlaEI7r/Z S5qnnYzRYiLExltYVjojA1cl1KUSd3ofYwnBR2PkUdKEisyC5lm/BacWIc3uMg5+ /yyZ3HWhyVMKg3vgAsBaoI5NPIYBJmWvH2WXoFY5YgZ+SqN/9b0BHQ= 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:cc:subject:date:message-id; s=default; bh=OwAreG0pjni7O9BrTDDRaCm77tk=; b=y7g/UqWMqLeMTdanr7xiGjxUakmH oBBKSQq3Jz9bJ4ewJgekVvB9mhJdwil1JoJwEz6WVWP/5waWKH/jKIt+gqGOhzJG uYdFRojYpKxDBJU1OCpI59El/+FTzVIHdbg11T0++2IljTZwXedPbh3e/VW6ZVej m0ozV8f0qMK+TL0= Received: (qmail 87746 invoked by alias); 26 Sep 2018 07:31:28 -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 87599 invoked by uid 89); 26 Sep 2018 07:31:16 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=1138, H*r:212.27.42, HX-Envelope-From:sk:albert. X-HELO: smtp3-g21.free.fr From: "Albert ARIBAUD (3ADEV)" To: libc-alpha@sourceware.org Cc: "Albert ARIBAUD (3ADEV)" Subject: [PATCH v8 1/2] Y2038: Add 64-bit time for all architectures Date: Wed, 26 Sep 2018 09:30:52 +0200 Message-Id: <20180926073053.11710-1-albert.aribaud@3adev.fr> glibc support for 64-bit time_t on 32-bit architectures will involve: - Using 64-bit times inside glibc, with conversions to and from 32-bit times taking place as necessary for interfaces using such times. - Adding 64-bit-time support in the glibc public API. This support should be dynamic, i.e. iglibc should provide both 32-bit and 64-bit implementations and let user code choose at compile time whether to use the 32-bit or 64-bit interfaces. This requires a glibc-internal name for a type for times that are always 64-bit. To determine whether the default time_t interfaces are 32-bit and so need conversions, or are 64-bit and so are compatible with the internal 64-bit type without conversions, a macro giving the size of the default time_t is also required. This macro is called __TIMESIZE. Based on __TIMESIZE, a new macro is defined, __TIME64_T_TYPE, which is always the right __*_T_TYPE to hold a 64-bit-time. __TIME64_T_TYPE equals __TIME_T_TYPE if __TIMESIZE equals 64 and equals __SQUAD_T_TYPE otherwise. __time64_t can then replace uses of internal_time_t. * bit/time64.h: New file. * bits/timesize: (__TIMESIZE): New macro. * include/time.h: replace internal_time_t with __time64_t. * posix/bits/types (__time64_t): Add. * stdlib/Makefile: Add bits/time64.h to includes. * stdlib/Makefile: Add bits/timesize.h to includes. * sysdeps/unix/sysv/linux/x86/bits/time64.h: New file. * sysdeps/unix/sysv/linux/x86/bits/timesize.h (__TIMESIZE): New macro. --- bits/time64.h | 38 +++++++++++++++++++ bits/timesize.h | 22 +++++++++++ include/time.h | 7 +--- posix/bits/types.h | 8 ++++ stdlib/Makefile | 2 +- sysdeps/unix/sysv/linux/x86/bits/time64.h | 41 +++++++++++++++++++++ sysdeps/unix/sysv/linux/x86/bits/timesize.h | 25 +++++++++++++ time/tzfile.c | 18 ++++----- 8 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 bits/time64.h create mode 100644 bits/timesize.h create mode 100644 sysdeps/unix/sysv/linux/x86/bits/time64.h create mode 100644 sysdeps/unix/sysv/linux/x86/bits/timesize.h diff --git a/bits/time64.h b/bits/time64.h new file mode 100644 index 0000000000..4fd60fef7e --- /dev/null +++ b/bits/time64.h @@ -0,0 +1,38 @@ +/* bits/time64.h -- underlying types for __time64_t. Generic version. + Copyright (C) 2018 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 + . */ + +#ifndef _BITS_TYPES_H +# error "Never include directly; use instead." +#endif + +#ifndef _BITS_TIME64_H +#define _BITS_TIME64_H 1 + +/* Define __TIME64_T_TYPE so that it is always a 64-bit type. + * On 64-bit platforms and X32, there is already a 64-bit time. + * On 32-bit platforms except X32, we need to create one. */ + +#if __TIMESIZE == 64 +/* If we already have 64-bit time then use it. */ +# define __TIME64_T_TYPE __TIME_T_TYPE +#else +/* Define a 64-bit type alongsize the 32-bit one. */ +# define __TIME64_T_TYPE __SQUAD_TYPE +#endif + +#endif /* bits/time64.h */ diff --git a/bits/timesize.h b/bits/timesize.h new file mode 100644 index 0000000000..cc47ff165f --- /dev/null +++ b/bits/timesize.h @@ -0,0 +1,22 @@ +/* Bit size of the time_t type at glibc build time, general case. + Copyright (C) 2018 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 + +/* Size in bits of the 'time_t' type of the default ABI. */ +#define __TIMESIZE __WORDSIZE diff --git a/include/time.h b/include/time.h index e30c5fc3b1..e99711a556 100644 --- a/include/time.h +++ b/include/time.h @@ -26,10 +26,6 @@ extern __typeof (clock_getcpuclockid) __clock_getcpuclockid; /* Now define the internal interfaces. */ struct tm; -/* time_t variant for representing time zone data, independent of - time_t. */ -typedef __int64_t internal_time_t; - /* Defined in mktime.c. */ extern const unsigned short int __mon_yday[2][13] attribute_hidden; @@ -43,7 +39,7 @@ extern int __use_tzfile attribute_hidden; extern void __tzfile_read (const char *file, size_t extra, char **extrap) attribute_hidden; -extern void __tzfile_compute (internal_time_t timer, int use_localtime, +extern void __tzfile_compute (__time64_t timer, int use_localtime, long int *leap_correct, int *leap_hit, struct tm *tp) attribute_hidden; extern void __tzfile_default (const char *std, const char *dst, @@ -101,7 +97,6 @@ extern char * __strptime_internal (const char *rp, const char *fmt, extern double __difftime (time_t time1, time_t time0); - /* Use in the clock_* functions. Size of the field representing the actual clock ID. */ #define CLOCK_IDFIELD_SIZE 3 diff --git a/posix/bits/types.h b/posix/bits/types.h index 5e22ce41bf..cda0a70dd8 100644 --- a/posix/bits/types.h +++ b/posix/bits/types.h @@ -25,6 +25,7 @@ #include #include +#include /* Convenience types. */ typedef unsigned char __u_char; @@ -138,6 +139,7 @@ __extension__ typedef unsigned long long int __uintmax_t; # error #endif #include /* Defines __*_T_TYPE macros. */ +#include /* Defines __TIME*_T_TYPE macros. */ __STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */ @@ -211,6 +213,12 @@ __STD_TYPE __U32_TYPE __socklen_t; It is not currently necessary for this to be machine-specific. */ typedef int __sig_atomic_t; +#if __TIMESIZE == 64 +# define __time64_t __time_t +#else +__STD_TYPE __TIME64_T_TYPE __time64_t; /* Seconds since the Epoch. */ +#endif + #undef __STD_TYPE #endif /* bits/types.h */ diff --git a/stdlib/Makefile b/stdlib/Makefile index 01194bbf7c..bdb0a18295 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -29,7 +29,7 @@ headers := stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h \ ucontext.h sys/ucontext.h bits/indirect-return.h \ alloca.h fmtmsg.h \ bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h \ - bits/stdint-uintn.h + bits/stdint-uintn.h bits/time64.h bits/timesize.h \ routines := \ atof atoi atol atoll \ diff --git a/sysdeps/unix/sysv/linux/x86/bits/time64.h b/sysdeps/unix/sysv/linux/x86/bits/time64.h new file mode 100644 index 0000000000..81de09e23f --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/bits/time64.h @@ -0,0 +1,41 @@ +/* bits/time64.h -- underlying types for __time64_t. Linux/x86-64 version. + Copyright (C) 2018 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 + . */ + +#ifndef _BITS_TYPES_H +# error "Never include directly; use instead." +#endif + +#ifndef _BITS_TIME64_H +#define _BITS_TIME64_H 1 + +/* Define __TIME64_T_TYPE so that it is always a 64-bit type. + * On 64-bit platforms and X32, there is already a 64-bit time. + * On 32-bit platforms except X32, we need to create one. */ + +#if defined __x86_64__ && defined __ILP32__ +/* For x32, time is 64-bit even though word size is 32-bit. */ +# define __TIME64_T_TYPE __SQUAD_TYPE +#elif __TIMESIZE == 64 +/* If we already have 64-bit time then use it. */ +# define __TIME64_T_TYPE __TIME_T_TYPE +#else +/* Define a 64-bit type alongsize the 32-bit one. */ +# define __TIME64_T_TYPE __SQUAD_TYPE +#endif + +#endif /* bits/time64.h */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/timesize.h b/sysdeps/unix/sysv/linux/x86/bits/timesize.h new file mode 100644 index 0000000000..8b88ab84b0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/bits/timesize.h @@ -0,0 +1,25 @@ +/* Bit size of the time_t type at glibc build time, x86-64 and x32 case. + Copyright (C) 2018 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 + . */ + +#if defined __x86_64__ && defined __ILP32__ +/* For x32, time is 64-bit even though word size is 32-bit. */ +# define __TIMESIZE 64 +#else +/* For others, time size is word size. */ +# define __TIMESIZE __WORDSIZE +#endif diff --git a/time/tzfile.c b/time/tzfile.c index 72ef75f074..844a68de8c 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -44,12 +44,12 @@ struct ttinfo struct leap { - internal_time_t transition; /* Time the transition takes effect. */ + __time64_t transition; /* Time the transition takes effect. */ long int change; /* Seconds of correction to apply. */ }; static size_t num_transitions; -libc_freeres_ptr (static internal_time_t *transitions); +libc_freeres_ptr (static __time64_t *transitions); static unsigned char *type_idxs; static size_t num_types; static struct ttinfo *types; @@ -113,8 +113,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) size_t tzspec_len; char *new = NULL; - _Static_assert (sizeof (internal_time_t) == 8, - "internal_time_t must be eight bytes"); + _Static_assert (sizeof (__time64_t) == 8, + "__time64_t must be eight bytes"); __use_tzfile = 0; @@ -217,9 +217,9 @@ __tzfile_read (const char *file, size_t extra, char **extrap) if (__builtin_expect (num_transitions > ((SIZE_MAX - (__alignof__ (struct ttinfo) - 1)) - / (sizeof (internal_time_t) + 1)), 0)) + / (sizeof (__time64_t) + 1)), 0)) goto lose; - total_size = num_transitions * (sizeof (internal_time_t) + 1); + total_size = num_transitions * (sizeof (__time64_t) + 1); total_size = ((total_size + __alignof__ (struct ttinfo) - 1) & ~(__alignof__ (struct ttinfo) - 1)); types_idx = total_size; @@ -276,7 +276,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) goto lose; type_idxs = (unsigned char *) transitions + (num_transitions - * sizeof (internal_time_t)); + * sizeof (__time64_t)); types = (struct ttinfo *) ((char *) transitions + types_idx); zone_names = (char *) types + num_types * sizeof (struct ttinfo); leaps = (struct leap *) ((char *) transitions + leaps_idx); @@ -578,7 +578,7 @@ __tzfile_default (const char *std, const char *dst, } void -__tzfile_compute (internal_time_t timer, int use_localtime, +__tzfile_compute (__time64_t timer, int use_localtime, long int *leap_correct, int *leap_hit, struct tm *tp) { @@ -667,7 +667,7 @@ __tzfile_compute (internal_time_t timer, int use_localtime, initial search spot from it. Half of a gregorian year has on average 365.2425 * 86400 / 2 = 15778476 seconds. The value i can be truncated if size_t is smaller than - internal_time_t, but this is harmless because it is just + __time64_t, but this is harmless because it is just a guess. */ i = (transitions[num_transitions - 1] - timer) / 15778476; if (i < num_transitions)