From patchwork Tue May 7 13:18:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 32587 Received: (qmail 126693 invoked by alias); 7 May 2019 13:19:29 -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 126598 invoked by uid 89); 7 May 2019 13:19:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 spammy= X-HELO: mail-out.m-online.net From: Lukasz Majewski To: libc-alpha@sourceware.org Cc: Stepan Golosunov , Arnd Bergmann , Paul Eggert , Joseph Myers , Lukasz Majewski Subject: [PATCH v3 5/5] y2038: Support for Y2038 safe time on 32 bit systems Date: Tue, 7 May 2019 15:18:48 +0200 Message-Id: <20190507131848.30980-12-lukma@denx.de> In-Reply-To: <20190507131848.30980-1-lukma@denx.de> References: <20190414220841.20243-1-lukma@denx.de> <20190507131848.30980-1-lukma@denx.de> The time_t type is now Y2038 safe, which means that it is aliased to __time64_t when __USE_TIME_BITS64 is defined or __time_t otherwise. On the contrary the __time_t for 32 bit systems is only 32 bit, so for Y2038 safe system it must be 64 bit (as is time_t) This patch introduces the Y2038 specific code to make clock_settime/ __clock_settime64 Y2038 safe on 32 bit systems. This goal is achieved by using aliasing to clock_settime names when __USE_TIME_BITS64 is defined. As a result user programs call 64 bit versions of functions (i.e. __clock_settime64 instead of __clock_settime), which must have been globally visible for this purpose - for non Y2038 safe code those are hidden in glibc. * include/features.h: Add logic to set __USE_TIME_BITS64 according to passed (when building userspace Y2038 safe program on 32 bit system) _TIME_BITS and _FILE_OFFSET_BITS * manual/creature.texi: Add description of _TIME_BITS * time/bits/types/time_t.h: Use __time64_t as time_t when __USE_TIME_BITS64 is defined * time/bits/types/struct_timespec.h: Replace tv_sec's __time_t type to Y2038 safe time_t * include/time.h: Remove libc_hidden_proto (__clock_settime64) - make the __clock_settime64 publicly available for Y2038 safe system * time/time.h: Redirect clock_settime call to __clock_settime64 on 32 bit Y2038 safe systems * time/Versions (GLIBC_PRIVATE): Export __clock_settime64 function as glibc private one, to be accessible from user programs when y2038 support is enabled * time/bits/types/struct_timespec.h: Add unnamed padding around tv_nsec when __USE_TIME_BITS64 is defined --- Changes for v3: - Only support clock_settime conversion to be Y2038 (use it as an example conversion code) Changes for v2: - Introduce unnamed padding in the struct timespec exported by glibc (to the /usr/include) --- include/features.h | 19 +++++++++++++++++++ include/time.h | 3 ++- manual/creature.texi | 28 ++++++++++++++++++++++++++++ time/Versions | 3 +++ time/bits/types/struct_timespec.h | 15 +++++++++++++-- time/bits/types/time_t.h | 4 ++++ time/time.h | 9 +++++++++ 7 files changed, 78 insertions(+), 3 deletions(-) diff --git a/include/features.h b/include/features.h index e016b3e5c7..153c6320f0 100644 --- a/include/features.h +++ b/include/features.h @@ -365,6 +365,25 @@ # define __USE_FILE_OFFSET64 1 #endif +/* We need to know the word size in order to check the time size. */ +#include + +#if defined _TIME_BITS +# if _TIME_BITS == 64 +# if ! defined (_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64 +# error _TIME_BITS==64 is allowed only when _FILE_OFFSET_BITS==64 +# elif __WORDSIZE == 32 +# define __USE_TIME_BITS64 1 +# endif +# elif _TIME_BITS == 32 +# if __WORDSIZE > 32 +# error _TIME_BITS=32 is not compatible with __WORDSIZE > 32 +# endif +# else +# error Invalid _TIME_BITS value (can only be 32 or 64) +# endif +#endif + #if defined _DEFAULT_SOURCE # define __USE_MISC 1 #endif diff --git a/include/time.h b/include/time.h index 670226df0c..d4b11cb1a9 100644 --- a/include/time.h +++ b/include/time.h @@ -132,7 +132,8 @@ libc_hidden_proto (__timegm64) #else extern int __clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp); -libc_hidden_proto (__clock_settime64) +/* For Y2038 safe system the __clock_settime64 needs to be a visible + symbol as a replacement for Y2038 unsafe clock_settime. */ #endif /* Compute the `struct tm' representation of T, diff --git a/manual/creature.texi b/manual/creature.texi index 8876b2ab77..10b7111043 100644 --- a/manual/creature.texi +++ b/manual/creature.texi @@ -165,6 +165,34 @@ This macro was introduced as part of the Large File Support extension (LFS). @end defvr +@defvr Macro _TIME_BITS +This macro determines the bit size of @code{time_t} (and therefore the +bit size of all @code{time_t} derived types and the prototypes of all +related functions). If @code{_TIME_BITS} is undefined, the bit size of +time_t equals the bit size of the architecture. + +If @code{_TIME_BITS} is undefined, or if @code{_TIME_BITS} is defined +to the value @code{32} and @code{__WORDSIZE} is defined to the value +@code{32}, or or if @code{_TIME_BITS} is defined to the value @code{64} +and @code{__WORDSIZE} is defined to the value @code{64}, nothing changes. + +If @code{_TIME_BITS} is defined to the value @code{64} and if +@code{__WORDSIZE} is defined to the value @code{32}, then the @w{64 bit} +time API and implementation are used even though the architecture word +size is @code{32}. Also, if the kernel provides @w{64 bit} time support, +it is used; otherwise, the @w{32 bit} kernel time support is used (with +no provision to address kernel Y2038 shortcomings). + +If @code{_TIME_BITS} is defined to the value @code{32} and if +@code{__WORDSIZE} is defined to the value @code{64}, then a compile-time +error is emitted. + +If @code{_TIME_BITS} is defined to a value different from both @code{32} +and @code{64}, then a compile-time error is emitted. + +This macro was introduced as part of the Y2038 support. +@end defvr + @defvr Macro _ISOC99_SOURCE @standards{GNU, (none)} If this macro is defined, features from ISO C99 are included. Since diff --git a/time/Versions b/time/Versions index fd838181e4..5109c45ce2 100644 --- a/time/Versions +++ b/time/Versions @@ -1,4 +1,7 @@ libc { + GLIBC_PRIVATE { + __clock_settime64; + } GLIBC_2.0 { # global variables __daylight; __timezone; __tzname; diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h index 5b77c52b4f..f34df0a18c 100644 --- a/time/bits/types/struct_timespec.h +++ b/time/bits/types/struct_timespec.h @@ -3,13 +3,24 @@ #define _STRUCT_TIMESPEC 1 #include +#include /* POSIX.1b structure for a time value. This is like a `struct timeval' but has nanoseconds instead of microseconds. */ struct timespec { - __time_t tv_sec; /* Seconds. */ - __syscall_slong_t tv_nsec; /* Nanoseconds. */ + time_t tv_sec; /* Seconds. */ +# ifdef __USE_TIME_BITS64 +# if __BYTE_ORDER == __BIG_ENDIAN + int : 32; + __syscall_slong_t tv_nsec; /* Nanoseconds. */ +# else + __syscall_slong_t tv_nsec; /* Nanoseconds. */ + int : 32; +# endif +# else + __syscall_slong_t tv_nsec; /* Nanoseconds. */ +# endif }; #endif diff --git a/time/bits/types/time_t.h b/time/bits/types/time_t.h index ab8287c6fe..84d67f6ac3 100644 --- a/time/bits/types/time_t.h +++ b/time/bits/types/time_t.h @@ -4,6 +4,10 @@ #include /* Returned by `time'. */ +#ifdef __USE_TIME_BITS64 +typedef __time64_t time_t; +#else typedef __time_t time_t; +#endif #endif diff --git a/time/time.h b/time/time.h index cba6d15260..0bfd1de925 100644 --- a/time/time.h +++ b/time/time.h @@ -222,6 +222,15 @@ extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW; extern int clock_settime (clockid_t __clock_id, const struct timespec *__tp) __THROW; +#ifdef __USE_TIME_BITS64 +# if defined(__REDIRECT) +extern int __REDIRECT (clock_settime, (clockid_t __clock_id, const struct + timespec *__tp), __clock_settime64) __THROW; +# else +# define clock_settime __clock_settime64 +# endif +#endif + # ifdef __USE_XOPEN2K /* High-resolution sleep with the specified clock.