[15/16] linux: Add {f}stat{at} y2038 support
Commit Message
A new struct __stat{64}_t64 type is added with the required
__timespec64 time definition. Both non-LFS and LFS support were
done with an extra __NR_statx call plus a conversion to the new
__stat{64}_t64 type. The statx call is done only for architectures
with support for 32-bit time_t ABI.
Internally some extra routines to copy from/to struct stat{64}
to struct __stat{64} used on multiple implementations (stat, fstat,
lstat, and fstatat) are added on a extra file (stat_t64_cp.c). Aslo
some extra routines to copy from statx to __stat{64} is added on
statx_cp.c.
Checked with a build for all affected ABIs. I also checked on x86_64,
i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x.
---
include/sys/stat.h | 32 +++++
sysdeps/generic/struct_stat_time64.h | 7 +
sysdeps/unix/sysv/linux/Makefile | 2 +-
sysdeps/unix/sysv/linux/fstat.c | 13 +-
sysdeps/unix/sysv/linux/fstat64.c | 20 ++-
sysdeps/unix/sysv/linux/fstatat.c | 64 +++++----
sysdeps/unix/sysv/linux/fstatat64.c | 88 ++++++++++---
sysdeps/unix/sysv/linux/lstat.c | 13 +-
sysdeps/unix/sysv/linux/lstat64.c | 19 ++-
.../unix/sysv/linux/mips/mips64/kstat_cp.h | 23 +---
.../unix/sysv/linux/mips/mips64/statx_cp.c | 3 -
sysdeps/unix/sysv/linux/stat.c | 13 +-
sysdeps/unix/sysv/linux/stat64.c | 20 ++-
sysdeps/unix/sysv/linux/stat_t64_cp.c | 92 +++++++++++++
sysdeps/unix/sysv/linux/stat_t64_cp.h | 28 ++++
sysdeps/unix/sysv/linux/statx_cp.c | 54 ++++++++
sysdeps/unix/sysv/linux/statx_cp.h | 6 +
sysdeps/unix/sysv/linux/struct_stat_time64.h | 122 ++++++++++++++++++
18 files changed, 539 insertions(+), 80 deletions(-)
create mode 100644 sysdeps/generic/struct_stat_time64.h
delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
create mode 100644 sysdeps/unix/sysv/linux/stat_t64_cp.c
create mode 100644 sysdeps/unix/sysv/linux/stat_t64_cp.h
create mode 100644 sysdeps/unix/sysv/linux/struct_stat_time64.h
Comments
On Thu, 23 Jul 2020, Adhemerval Zanella via Libc-alpha wrote:
> A new struct __stat{64}_t64 type is added with the required
> __timespec64 time definition. Both non-LFS and LFS support were
> done with an extra __NR_statx call plus a conversion to the new
> __stat{64}_t64 type. The statx call is done only for architectures
> with support for 32-bit time_t ABI.
The combination of 64-bit times with 32-bit offsets is not supposed to be
supported (no existing glibc configuration supports such a combination);
_TIME_BITS=64 without _FILE_OFFSET_BITS=64 should be an error. Thus, the
__stat_t64 type and functions shouldn't be present.
On 23/07/2020 17:55, Joseph Myers wrote:
> On Thu, 23 Jul 2020, Adhemerval Zanella via Libc-alpha wrote:
>
>> A new struct __stat{64}_t64 type is added with the required
>> __timespec64 time definition. Both non-LFS and LFS support were
>> done with an extra __NR_statx call plus a conversion to the new
>> __stat{64}_t64 type. The statx call is done only for architectures
>> with support for 32-bit time_t ABI.
>
> The combination of 64-bit times with 32-bit offsets is not supposed to be
> supported (no existing glibc configuration supports such a combination);
> _TIME_BITS=64 without _FILE_OFFSET_BITS=64 should be an error. Thus, the
> __stat_t64 type and functions shouldn't be present.
>
Ok, I was not sure if the plan was to enforce it, but I agree that it
does make sense. And this simplifies the require work as well.
Hi Adhemerval,
> A new struct __stat{64}_t64 type is added with the required
> __timespec64 time definition. Both non-LFS and LFS support were
> done with an extra __NR_statx call plus a conversion to the new
> __stat{64}_t64 type. The statx call is done only for architectures
> with support for 32-bit time_t ABI.
>
> Internally some extra routines to copy from/to struct stat{64}
> to struct __stat{64} used on multiple implementations (stat, fstat,
> lstat, and fstatat) are added on a extra file (stat_t64_cp.c). Aslo
> some extra routines to copy from statx to __stat{64} is added on
> statx_cp.c.
>
> Checked with a build for all affected ABIs. I also checked on x86_64,
> i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x.
This patch set is a huge step forward for the *stat* conversion to
support 64 bit time.
In fact we will only need redirections when -D__USE_TIME_BITS64 support
is added.
> ---
> include/sys/stat.h | 32 +++++
> sysdeps/generic/struct_stat_time64.h | 7 +
> sysdeps/unix/sysv/linux/Makefile | 2 +-
> sysdeps/unix/sysv/linux/fstat.c | 13 +-
> sysdeps/unix/sysv/linux/fstat64.c | 20 ++-
> sysdeps/unix/sysv/linux/fstatat.c | 64 +++++----
> sysdeps/unix/sysv/linux/fstatat64.c | 88 ++++++++++---
> sysdeps/unix/sysv/linux/lstat.c | 13 +-
> sysdeps/unix/sysv/linux/lstat64.c | 19 ++-
> .../unix/sysv/linux/mips/mips64/kstat_cp.h | 23 +---
> .../unix/sysv/linux/mips/mips64/statx_cp.c | 3 -
> sysdeps/unix/sysv/linux/stat.c | 13 +-
> sysdeps/unix/sysv/linux/stat64.c | 20 ++-
> sysdeps/unix/sysv/linux/stat_t64_cp.c | 92 +++++++++++++
> sysdeps/unix/sysv/linux/stat_t64_cp.h | 28 ++++
> sysdeps/unix/sysv/linux/statx_cp.c | 54 ++++++++
> sysdeps/unix/sysv/linux/statx_cp.h | 6 +
> sysdeps/unix/sysv/linux/struct_stat_time64.h | 122
> ++++++++++++++++++ 18 files changed, 539 insertions(+), 80
> deletions(-) create mode 100644 sysdeps/generic/struct_stat_time64.h
> delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
> create mode 100644 sysdeps/unix/sysv/linux/stat_t64_cp.c
> create mode 100644 sysdeps/unix/sysv/linux/stat_t64_cp.h
> create mode 100644 sysdeps/unix/sysv/linux/struct_stat_time64.h
>
> diff --git a/include/sys/stat.h b/include/sys/stat.h
> index 199173b007..87d4a5ec4f 100644
> --- a/include/sys/stat.h
> +++ b/include/sys/stat.h
> @@ -3,6 +3,8 @@
>
> #ifndef _ISOMAC
> # include <xstatver.h>
> +# include <struct___timespec64.h>
> +# include <struct_stat_time64.h>
> # include <stdbool.h>
>
> static inline bool
> @@ -44,6 +46,36 @@ hidden_proto (__lstat64)
> hidden_proto (__fstatat64)
> # endif
>
> +# if __TIMESIZE == 64
> +# define __stat_time64 __stat
> +# define __stat64_time64 __stat64
> +# define __fstat_time64 __fstat
> +# define __fstat64_time64 __fstat64
> +# define __lstat_time64 __lstat
> +# define __lstat64_time64 __lstat64
> +# define __fstatat_time64 __fstatat
> +# define __fstatat64_time64 __fstatat64
> +# else
> +extern int __stat_time64 (const char *file, struct __stat_t64 *buf);
> +libc_hidden_proto (__stat_time64);
> +extern int __stat64_time64 (const char *file, struct __stat64_t64
> *buf); +hidden_proto (__stat64_time64);
> +extern int __lstat_time64 (const char *file, struct __stat_t64 *buf);
> +libc_hidden_proto (__lstat_time64);
> +extern int __lstat64_time64 (const char *file, struct __stat64_t64
> *buf); +hidden_proto (__lstat64_time64);
> +extern int __fstat_time64 (int fd, struct __stat_t64 *buf);
> +libc_hidden_proto (__fstat_time64);
> +extern int __fstat64_time64 (int fd, struct __stat64_t64 *buf);
> +hidden_proto (__fstat64_time64);
> +extern int __fstatat_time64 (int dirfd, const char *pathname,
> + struct __stat_t64 *buf, int flags);
> +libc_hidden_proto (__fstatat_time64);
> +extern int __fstatat64_time64 (int dirfd, const char *pathname,
> + struct __stat64_t64 *buf, int flags);
> +hidden_proto (__fstatat64_time64);
> +# endif
> +
> extern int __chmod (const char *__file, __mode_t __mode);
> libc_hidden_proto (__chmod)
> extern int __fchmod (int __fd, __mode_t __mode);
> diff --git a/sysdeps/generic/struct_stat_time64.h
> b/sysdeps/generic/struct_stat_time64.h new file mode 100644
> index 0000000000..24bb9f75cb
> --- /dev/null
> +++ b/sysdeps/generic/struct_stat_time64.h
> @@ -0,0 +1,7 @@
> +#ifndef _BITS_STRUCT_STAT_TIME64_H
> +#define _BITS_STRUCT_STAT_TIME64_H 1
> +
> +#define __stat_t64 stat
> +#define __stat64_t64 stat64
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index f189f65daf..95a51ee4f2 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -273,7 +273,7 @@ sysdep_routines += xstatconv internal_statvfs
> internal_statvfs64 \ open_nocancel open64_nocancel \
> openat_nocancel openat64_nocancel \
> read_nocancel pread64_nocancel \
> - write_nocancel statx_cp
> + write_nocancel statx_cp stat_t64_cp
>
> sysdep_headers += bits/fcntl-linux.h
>
> diff --git a/sysdeps/unix/sysv/linux/fstat.c
> b/sysdeps/unix/sysv/linux/fstat.c index bdbeded956..0981dbaa95 100644
> --- a/sysdeps/unix/sysv/linux/fstat.c
> +++ b/sysdeps/unix/sysv/linux/fstat.c
> @@ -19,13 +19,24 @@
> #include <sys/stat.h>
> #include <kernel_stat.h>
> #include <fcntl.h>
> +#include <stat_t64_cp.h>
>
> #if !XSTAT_IS_XSTAT64
> +int
> +__fstat_time64 (int fd, struct __stat_t64 *buf)
> +{
> + return __fstatat_time64 (fd, "", buf, AT_EMPTY_PATH);
> +}
> +# if __TIMESIZE != 64
> +libc_hidden_def (__fstat_time64)
> +
> int
> __fstat (int fd, struct stat *buf)
> {
> - return __fstatat (fd, "", buf, AT_EMPTY_PATH);
> + struct __stat_t64 st_t64;
> + return __fstat_time64 (fd, &st_t64) ?: __cp_stat_t64_stat
> (&st_t64, buf); }
> +# endif
>
> weak_alias (__fstat, fstat)
> #endif
> diff --git a/sysdeps/unix/sysv/linux/fstat64.c
> b/sysdeps/unix/sysv/linux/fstat64.c index c2ff1ff577..67667e79d8
> 100644 --- a/sysdeps/unix/sysv/linux/fstat64.c
> +++ b/sysdeps/unix/sysv/linux/fstat64.c
> @@ -19,16 +19,30 @@
> #define __fstat __redirect___fstat
> #define fstat __redirect_fstat
> #include <sys/stat.h>
> -#undef __fstat
> -#undef fstat
> #include <fcntl.h>
> #include <kernel_stat.h>
> +#include <stat_t64_cp.h>
> +
> +int
> +__fstat64_time64 (int fd, struct __stat64_t64 *buf)
> +{
> + return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH);
> +}
> +#if __TIMESIZE != 64
> +hidden_def (__fstat64_time64)
>
> int
> __fstat64 (int fd, struct stat64 *buf)
> {
> - return __fstatat64 (fd, "", buf, AT_EMPTY_PATH);
> + struct __stat64_t64 st_t64;
> + return __fstat64_time64 (fd, &st_t64)
> + ?: __cp_stat64_t64_stat64 (&st_t64, buf);
> }
> +#endif
> +
> +#undef __fstat
> +#undef fstat
> +
> hidden_def (__fstat64)
> weak_alias (__fstat64, fstat64)
>
> diff --git a/sysdeps/unix/sysv/linux/fstatat.c
> b/sysdeps/unix/sysv/linux/fstatat.c index 03ddb3f493..f65d3b74a6
> 100644 --- a/sysdeps/unix/sysv/linux/fstatat.c
> +++ b/sysdeps/unix/sysv/linux/fstatat.c
> @@ -22,25 +22,28 @@
>
> #if !XSTAT_IS_XSTAT64
> # include <kstat_cp.h>
> +# include <statx_cp.h>
> +# include <stat_t64_cp.h>
>
> int
> -__fstatat (int fd, const char *file, struct stat *st, int flag)
> +__fstatat_time64 (int fd, const char *file, struct __stat_t64 *st,
> int flag) {
> -# if STAT_IS_KERNEL_STAT
> - /* New kABIs which uses generic pre 64-bit time Linux ABI, e.g.
> - csky, nios2 */
> - int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
> - if (r == 0 && (st->__st_ino_pad != 0
> - || st->__st_size_pad != 0
> - || st->__st_blocks_pad != 0))
> - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> - return r;
> -# else
> -# ifdef __NR_fstatat64
> - /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k,
> mips32,
> - microblaze, s390, sh, powerpc, and sparc. */
> + struct statx stx;
> + int r = INLINE_SYSCALL_CALL (statx, fd, file, flag,
> STATX_BASIC_STATS,
> + &stx);
I'm wondering about the indentation here - I do see 3*TAB and some
spaces. Shouldn't we only use spaces?
And one more question what is the correct alignment:
(statx, fd, file, flag
&stx);
or
(statx, fd, file, flag
&stx);
> + if (r == 0 || errno != ENOSYS)
> + {
> + if (r == 0)
> + __cp_stat_t64_statx (st, &stx);
> + return r;
> + }
Great that the statx is used here.
> +
> +# ifdef __NR_fstatat64
> + /* Both new kABI which uses generic pre 64-bit time Linux ABI
> (e.g. csky
> + and nios) and old kABI with non-LFS support (e.g. arm, i386,
> hppa, m68k,
> + mips32, microblaze, s390, sh, powerpc, and sparc32). */
> struct stat64 st64;
> - int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
> + r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
> if (r == 0)
> {
> if (! in_ino_t_range (st64.st_ino)
> @@ -48,7 +51,7 @@ __fstatat (int fd, const char *file, struct stat
> *st, int flag) || ! in_blkcnt_t_range (st64.st_blocks))
> return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
>
> - /* Clear internal pad and reserved fields. */
> + /* Clear both pad and reserved fields. */
> memset (st, 0, sizeof (*st));
>
> st->st_dev = st64.st_dev,
> @@ -61,22 +64,29 @@ __fstatat (int fd, const char *file, struct stat
> *st, int flag) st->st_size = st64.st_size;
> st->st_blksize = st64.st_blksize;
> st->st_blocks = st64.st_blocks;
> - st->st_atim.tv_sec = st64.st_atim.tv_sec;
> - st->st_atim.tv_nsec = st64.st_atim.tv_nsec;
> - st->st_mtim.tv_sec = st64.st_mtim.tv_sec;
> - st->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;
> - st->st_ctim.tv_sec = st64.st_ctim.tv_sec;
> - st->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;
> + st->st_atim = valid_timespec_to_timespec64 (st64.st_atim);
> + st->st_mtim = valid_timespec_to_timespec64 (st64.st_mtim);
> + st->st_ctim = valid_timespec_to_timespec64 (st64.st_ctim);
> }
> return r;
> -# else
> +# else
> /* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
> struct kernel_stat kst;
> - int r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
> - return r ?: __cp_kstat_stat (&kst, st);
> -# endif /* __nr_fstatat64 */
> -# endif /* STAT_IS_KERNEL_STAT */
> + r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
> + return r ?: __cp_kstat_stat_t64 (&kst, st);
> +# endif /* __NR_fstatat64 */
> +}
> +# if __TIMESIZE != 64
> +libc_hidden_def (__fstatat_time64)
> +
> +int
> +__fstatat (int fd, const char *file, struct stat *buf, int flags)
> +{
> + struct __stat_t64 st_t64;
> + return __fstatat_time64 (fd, file, &st_t64, flags)
> + ?: __cp_stat_t64_stat (&st_t64, buf);
> }
> +# endif
>
> weak_alias (__fstatat, fstatat)
> #endif
> diff --git a/sysdeps/unix/sysv/linux/fstatat64.c
> b/sysdeps/unix/sysv/linux/fstatat64.c index 82fab107a5..b3940f0d20
> 100644 --- a/sysdeps/unix/sysv/linux/fstatat64.c
> +++ b/sysdeps/unix/sysv/linux/fstatat64.c
> @@ -19,56 +19,102 @@
> #define __fstatat __redirect___fstatat
> #define fstatat __redirect_fstatat
> #include <sys/stat.h>
> -#undef __fstatat
> -#undef fstatat
> #include <fcntl.h>
> -
> +#include <string.h>
> #include <kernel_stat.h>
> #include <sysdep.h>
> -
> +#include <time.h>
> #include <statx_cp.h>
> #include <kstat_cp.h>
> +#include <stat_t64_cp.h>
>
> int
> -__fstatat64 (int fd, const char *file, struct stat64 *st, int flag)
> +__fstatat64_time64 (int fd, const char *file, struct __stat64_t64
> *st,
> + int flag)
> {
> + int r;
> +
> +#if (__WORDSIZE == 32 \
> + && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
I do guess that the above condition is to ensure that 32 bit archs
(excluding x86_64-x32 - e.g. arm, riscv, etc) use statx?
> + struct statx tmp;
> + r = INLINE_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
> + STATX_BASIC_STATS, &tmp);
> + if (r == 0 || errno != ENOSYS)
> + {
> + if (r == 0)
> + __cp_stat64_t64_statx (st, &tmp);
> + return r;
> + }
> +#endif
> +
> #if XSTAT_IS_XSTAT64
> # ifdef __NR_newfstatat
> /* 64-bit kABI, e.g. aarch64, ia64, powerpc64*, s390x, riscv64, and
> x86_64. */
> - return INLINE_SYSCALL_CALL (newfstatat, fd, file, st, flag);
> + r = INLINE_SYSCALL_CALL (newfstatat, fd, file, st, flag);
> # elif defined __NR_fstatat64
> # if STAT64_IS_KERNEL_STAT64
> - /* 64-bit kABI outlier, e.g. alpha. */
> - return INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
> + /* 64-bit kABI outlier, e.g. alpha */
> + r = INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
> # else
> /* 64-bit kABI outlier, e.g. sparc64. */
> struct kernel_stat64 kst64;
> - int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &kst64, flag);
> - return r ?: __cp_stat64_kstat64 (st, &kst64);
> -# endif
> -# else
> - /* 32-bit kABI with default 64-bit time_t, e.g. arc, riscv32. */
> - struct statx tmp;
> - int r = INLINE_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT |
> flag,
> - STATX_BASIC_STATS, &tmp);
> + r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &kst64, flag);
> if (r == 0)
> - __cp_stat64_statx (st, &tmp);
> - return r;
> + r = __cp_stat64_kstat64 (st, &kst64);
> +# endif
> # endif
> #else
> # ifdef __NR_fstatat64
> /* All kABIs with non-LFS support, e.g. arm, csky, i386, hppa,
> m68k, microblaze, nios2, sh, powerpc32, and sparc32. */
> - return INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
> + struct stat64 st64;
> + r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
> + if (r == 0)
> + {
> + /* Clear both pad and reserved fields. */
> + memset (st, 0, sizeof (*st));
> +
> + st->st_dev = st64.st_dev,
> + st->st_ino = st64.st_ino;
> + st->st_mode = st64.st_mode;
> + st->st_nlink = st64.st_nlink;
> + st->st_uid = st64.st_uid;
> + st->st_gid = st64.st_gid;
> + st->st_rdev = st64.st_rdev;
> + st->st_size = st64.st_size;
> + st->st_blksize = st64.st_blksize;
> + st->st_blocks = st64.st_blocks;
> + st->st_atim = valid_timespec_to_timespec64 (st64.st_atim);
> + st->st_mtim = valid_timespec_to_timespec64 (st64.st_mtim);
> + st->st_ctim = valid_timespec_to_timespec64 (st64.st_ctim);
> + }
> # else
> /* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
> struct kernel_stat kst;
> - int r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
> - return r ?: __cp_kstat_stat64 (&kst, st);
> + r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
> + if (r == 0)
> + r = __cp_kstat_stat64_t64 (&kst, st);
> # endif
> #endif
> +
> + return r;
> }
> +#if __TIMESIZE != 64
> +hidden_def (__fstatat64_time64)
> +
> +int
> +__fstatat64 (int fd, const char *file, struct stat64 *st, int flags)
> +{
> + struct __stat64_t64 st_t64;
> + return __fstatat64_time64 (fd, file, &st_t64, flags)
> + ?: __cp_stat64_t64_stat64 (&st_t64, st);
> +}
> +#endif
> +
> +#undef __fstatat
> +#undef fstatat
> +
> hidden_def (__fstatat64)
> weak_alias (__fstatat64, fstatat64)
>
> diff --git a/sysdeps/unix/sysv/linux/lstat.c
> b/sysdeps/unix/sysv/linux/lstat.c index b0bdeee9e9..803ad78171 100644
> --- a/sysdeps/unix/sysv/linux/lstat.c
> +++ b/sysdeps/unix/sysv/linux/lstat.c
> @@ -19,13 +19,24 @@
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <kernel_stat.h>
> +#include <stat_t64_cp.h>
>
> #if !XSTAT_IS_XSTAT64
> +int
> +__lstat_time64 (const char *file, struct __stat_t64 *buf)
> +{
> + return __fstatat_time64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
> +}
> +# if __TIMESIZE != 64
> +libc_hidden_def (__lstat_time64)
> +
> int
> __lstat (const char *file, struct stat *buf)
> {
> - return __fstatat (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
> + struct __stat_t64 st_t64;
> + return __lstat_time64 (file, &st_t64) ?: __cp_stat_t64_stat
> (&st_t64, buf); }
> +# endif
>
> weak_alias (__lstat, lstat)
> #endif
> diff --git a/sysdeps/unix/sysv/linux/lstat64.c
> b/sysdeps/unix/sysv/linux/lstat64.c index e5f02e9822..971ab8469d
> 100644 --- a/sysdeps/unix/sysv/linux/lstat64.c
> +++ b/sysdeps/unix/sysv/linux/lstat64.c
> @@ -19,19 +19,32 @@
> #define __lstat __redirect___lstat
> #define lstat __redirect_lstat
> #include <sys/stat.h>
> -#undef __lstat
> -#undef lstat
> #include <fcntl.h>
> #include <kernel_stat.h>
> +#include <stat_t64_cp.h>
> +
> +int
> +__lstat64_time64 (const char *file, struct __stat64_t64 *buf)
> +{
> + return __fstatat64_time64 (AT_FDCWD, file, buf,
> AT_SYMLINK_NOFOLLOW); +}
> +#if __TIMESIZE != 64
> +hidden_def (__lstat64_time64)
>
> int
> __lstat64 (const char *file, struct stat64 *buf)
> {
> - return __fstatat64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
> + struct __stat64_t64 st_t64;
> + return __lstat64_time64 (file, &st_t64)
> + ?: __cp_stat64_t64_stat64 (&st_t64, buf);
> }
> +#endif
> hidden_def (__lstat64)
> weak_alias (__lstat64, lstat64)
>
> +#undef __lstat
> +#undef lstat
> +
> #if XSTAT_IS_XSTAT64
> strong_alias (__lstat64, __lstat)
> weak_alias (__lstat64, lstat)
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h
> b/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h index
> 7f226416f9..553f4226bc 100644 ---
> a/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h +++
> b/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h @@ -20,23 +20,21 @@
> #include <kernel_stat.h>
>
> static inline int
> -__cp_kstat_stat (const struct kernel_stat *kst, struct stat *st)
> +__cp_kstat_stat_t64 (const struct kernel_stat *kst, struct
> __stat_t64 *st) {
> + if (! in_ino_t_range (kst->st_ino)
> + || ! in_off_t_range (kst->st_size)
> + || ! in_blkcnt_t_range (kst->st_blocks))
> + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> +
> st->st_dev = kst->st_dev;
> - memset (&st->st_pad1, 0, sizeof (st->st_pad1));
> st->st_ino = kst->st_ino;
> - if (st->st_ino != kst->st_ino)
> - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> st->st_mode = kst->st_mode;
> st->st_nlink = kst->st_nlink;
> st->st_uid = kst->st_uid;
> st->st_gid = kst->st_gid;
> st->st_rdev = kst->st_rdev;
> - memset (&st->st_pad2, 0, sizeof (st->st_pad2));
> st->st_size = kst->st_size;
> - if (st->st_size != kst->st_size)
> - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> - st->st_pad3 = 0;
> st->st_atim.tv_sec = kst->st_atime_sec;
> st->st_atim.tv_nsec = kst->st_atime_nsec;
> st->st_mtim.tv_sec = kst->st_mtime_sec;
> @@ -45,26 +43,20 @@ __cp_kstat_stat (const struct kernel_stat *kst,
> struct stat *st) st->st_ctim.tv_nsec = kst->st_ctime_nsec;
> st->st_blksize = kst->st_blksize;
> st->st_blocks = kst->st_blocks;
> - if (st->st_blocks != kst->st_blocks)
> - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> - memset (&st->st_pad5, 0, sizeof (st->st_pad5));
>
> return 0;
> }
>
> static inline int
> -__cp_kstat_stat64 (const struct kernel_stat *kst, struct stat64 *st)
> +__cp_kstat_stat64_t64 (const struct kernel_stat *kst, struct
> __stat64_t64 *st) {
> st->st_dev = kst->st_dev;
> - memset (&st->st_pad1, 0, sizeof (st->st_pad1));
> st->st_ino = kst->st_ino;
> st->st_mode = kst->st_mode;
> st->st_nlink = kst->st_nlink;
> st->st_uid = kst->st_uid;
> st->st_gid = kst->st_gid;
> st->st_rdev = kst->st_rdev;
> - memset (&st->st_pad2, 0, sizeof (st->st_pad2));
> - st->st_pad3 = 0;
> st->st_size = kst->st_size;
> st->st_blksize = kst->st_blksize;
> st->st_blocks = kst->st_blocks;
> @@ -74,7 +66,6 @@ __cp_kstat_stat64 (const struct kernel_stat *kst,
> struct stat64 *st) st->st_mtim.tv_nsec = kst->st_mtime_nsec;
> st->st_ctim.tv_sec = kst->st_ctime_sec;
> st->st_ctim.tv_nsec = kst->st_ctime_nsec;
> - memset (&st->st_pad4, 0, sizeof (st->st_pad4));
>
> return 0;
> }
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
> b/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c deleted file mode
> 100644 index 260cda987e..0000000000
> --- a/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
> +++ /dev/null
> @@ -1,3 +0,0 @@
> -/* Override the generic statx_cp.c which is only needed for new
> 32-bit arch
> - without stat64 family support.
> - */
> diff --git a/sysdeps/unix/sysv/linux/stat.c
> b/sysdeps/unix/sysv/linux/stat.c index a77502eb95..dcbc22da29 100644
> --- a/sysdeps/unix/sysv/linux/stat.c
> +++ b/sysdeps/unix/sysv/linux/stat.c
> @@ -19,13 +19,24 @@
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <kernel_stat.h>
> +#include <stat_t64_cp.h>
>
> #if !XSTAT_IS_XSTAT64
> +int
> +__stat_time64 (const char *file, struct __stat_t64 *buf)
> +{
> + return __fstatat_time64 (AT_FDCWD, file, buf, 0);
> +}
> +# if __TIMESIZE != 64
> +libc_hidden_def (__stat_time64);
> +
> int
> __stat (const char *file, struct stat *buf)
> {
> - return __fstatat (AT_FDCWD, file, buf, 0);
> + struct __stat_t64 st_t64;
> + return __stat_time64 (file, &st_t64) ?: __cp_stat_t64_stat
> (&st_t64, buf); }
> +# endif
>
> weak_alias (__stat, stat)
> #endif
> diff --git a/sysdeps/unix/sysv/linux/stat64.c
> b/sysdeps/unix/sysv/linux/stat64.c index 2f40037c2c..bd8b17ac49 100644
> --- a/sysdeps/unix/sysv/linux/stat64.c
> +++ b/sysdeps/unix/sysv/linux/stat64.c
> @@ -19,16 +19,30 @@
> #define __stat __redirect___stat
> #define stat __redirect_stat
> #include <sys/stat.h>
> -#undef __stat
> -#undef stat
> #include <fcntl.h>
> #include <kernel_stat.h>
> +#include <stat_t64_cp.h>
> +
> +int
> +__stat64_time64 (const char *file, struct __stat64_t64 *buf)
> +{
> + return __fstatat64_time64 (AT_FDCWD, file, buf, 0);
> +}
> +#if __TIMESIZE != 64
> +hidden_def (__stat64_time64)
>
> int
> __stat64 (const char *file, struct stat64 *buf)
> {
> - return __fstatat64 (AT_FDCWD, file, buf, 0);
> + struct __stat64_t64 st_t64;
> + return __stat64_time64 (file, &st_t64)
> + ?: __cp_stat64_t64_stat64 (&st_t64, buf);
> }
> +#endif
> +
> +#undef __stat
> +#undef stat
> +
> hidden_def (__stat64)
> weak_alias (__stat64, stat64)
>
> diff --git a/sysdeps/unix/sysv/linux/stat_t64_cp.c
> b/sysdeps/unix/sysv/linux/stat_t64_cp.c new file mode 100644
> index 0000000000..56459b6266
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/stat_t64_cp.c
> @@ -0,0 +1,92 @@
> +/* Struct stat/stat64 to stat/stat64 conversion for Linux.
> + Copyright (C) 2020 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <stat_t64_cp.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <time.h>
> +
> +#if __TIMESIZE != 64
> +/* Convert the 64-bit time_t stat ST_T64 to the non-LFS ST stat and
> returns
> + EOVERFLOW if any of time (access, modification, status) is larger
> than
> + 32-bit time_t. It is used on non-LFS stat, fstat, lstat, and
> fstatat to
> + convert from the the 64-bit time_t call. */
> +int
> +__cp_stat_t64_stat (const struct __stat_t64 *st_t64, struct stat *st)
> +{
> + if (! in_time_t_range (st_t64->st_atim.tv_sec)
> + || ! in_time_t_range (st_t64->st_mtim.tv_sec)
> + || ! in_time_t_range (st_t64->st_ctim.tv_sec))
> + {
> + __set_errno (EOVERFLOW);
> + return -1;
> + }
> +
> + /* Clear both pad and reserved fields. */
> + memset (st, 0, sizeof (*st));
> +
> + st->st_dev = st_t64->st_dev,
> + st->st_ino = st_t64->st_ino;
> + st->st_mode = st_t64->st_mode;
> + st->st_nlink = st_t64->st_nlink;
> + st->st_uid = st_t64->st_uid;
> + st->st_gid = st_t64->st_gid;
> + st->st_rdev = st_t64->st_rdev;
> + st->st_size = st_t64->st_size;
> + st->st_blksize = st_t64->st_blksize;
> + st->st_blocks = st_t64->st_blocks;
> + st->st_atim = valid_timespec64_to_timespec (st_t64->st_atim);
> + st->st_mtim = valid_timespec64_to_timespec (st_t64->st_mtim);
> + st->st_ctim = valid_timespec64_to_timespec (st_t64->st_ctim);
> +
> + return 0;
> +}
> +
> +int
> +__cp_stat64_t64_stat64 (const struct __stat64_t64 *st64_t64,
> + struct stat64 *st64)
> +{
> + if (! in_time_t_range (st64_t64->st_atim.tv_sec)
> + || ! in_time_t_range (st64_t64->st_mtim.tv_sec)
> + || ! in_time_t_range (st64_t64->st_ctim.tv_sec))
> + {
> + __set_errno (EOVERFLOW);
> + return -1;
> + }
> +
> + /* Clear both pad and reserved fields. */
> + memset (st64, 0, sizeof (*st64));
> +
> + st64->st_dev = st64_t64->st_dev,
> + st64->st_ino = st64_t64->st_ino;
> + st64->st_mode = st64_t64->st_mode;
> + st64->st_nlink = st64_t64->st_nlink;
> + st64->st_uid = st64_t64->st_uid;
> + st64->st_gid = st64_t64->st_gid;
> + st64->st_rdev = st64_t64->st_rdev;
> + st64->st_size = st64_t64->st_size;
> + st64->st_blksize = st64_t64->st_blksize;
> + st64->st_blocks = st64_t64->st_blocks;
> + st64->st_atim = valid_timespec64_to_timespec (st64_t64->st_atim);
> + st64->st_mtim = valid_timespec64_to_timespec (st64_t64->st_mtim);
> + st64->st_ctim = valid_timespec64_to_timespec (st64_t64->st_ctim);
> +
> + return 0;
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/stat_t64_cp.h
> b/sysdeps/unix/sysv/linux/stat_t64_cp.h new file mode 100644
> index 0000000000..ad2bcc7a04
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/stat_t64_cp.h
> @@ -0,0 +1,28 @@
> +/* Copy to/from struct stat with and without 64-bit time_t support.
> + Copyright (C) 2020 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <sys/stat.h>
> +
> +#if __TIMESIZE != 64
> +extern int __cp_stat_t64_stat (const struct __stat_t64 *st_t64,
> + struct stat *st)
> + attribute_hidden;
> +extern int __cp_stat64_t64_stat64 (const struct __stat64_t64
> *st64_t64,
> + struct stat64 *st64)
> + attribute_hidden;
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/statx_cp.c
> b/sysdeps/unix/sysv/linux/statx_cp.c index cc6e17929e..4b35e86f8d
> 100644 --- a/sysdeps/unix/sysv/linux/statx_cp.c
> +++ b/sysdeps/unix/sysv/linux/statx_cp.c
> @@ -47,3 +47,57 @@ __cp_stat64_statx (struct stat64 *to, struct statx
> *from) to->st_blksize = from->stx_blksize;
> }
> #endif
> +
> +void
> +__cp_stat_t64_statx (struct __stat_t64 *to, const struct statx *from)
> +{
> + /* Clear both pad and reserved fields. */
> + memset (to, 0, sizeof (*to));
> +
> + to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major
> << 8)
> + | ((from->stx_dev_minor & ~0xff) << 12));
> + to->st_ino = from->stx_ino;
> + to->st_mode = from->stx_mode;
> + to->st_nlink = from->stx_nlink;
> + to->st_uid = from->stx_uid;
> + to->st_gid = from->stx_gid;
> + to->st_rdev = ((from->stx_rdev_minor & 0xff) |
> (from->stx_rdev_major << 8)
> + | ((from->stx_rdev_minor & ~0xff) << 12));
> + to->st_size = from->stx_size;
> + to->st_blksize = from->stx_blksize;
> + to->st_blocks = from->stx_blocks;
> +
> + to->st_atime = from->stx_atime.tv_sec;
> + to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
> + to->st_mtime = from->stx_mtime.tv_sec;
> + to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
> + to->st_ctime = from->stx_ctime.tv_sec;
> + to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
> +}
> +
> +void
> +__cp_stat64_t64_statx (struct __stat64_t64 *to, const struct statx
> *from) +{
> + /* Clear both pad and reserved fields. */
> + memset (to, 0, sizeof (*to));
> +
> + to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major
> << 8)
> + | ((from->stx_dev_minor & ~0xff) << 12));
> + to->st_ino = from->stx_ino;
> + to->st_mode = from->stx_mode;
> + to->st_nlink = from->stx_nlink;
> + to->st_uid = from->stx_uid;
> + to->st_gid = from->stx_gid;
> + to->st_rdev = ((from->stx_rdev_minor & 0xff) |
> (from->stx_rdev_major << 8)
> + | ((from->stx_rdev_minor & ~0xff) << 12));
> + to->st_size = from->stx_size;
> + to->st_blksize = from->stx_blksize;
> + to->st_blocks = from->stx_blocks;
> +
> + to->st_atime = from->stx_atime.tv_sec;
> + to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
> + to->st_mtime = from->stx_mtime.tv_sec;
> + to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
> + to->st_ctime = from->stx_ctime.tv_sec;
> + to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
> +}
> diff --git a/sysdeps/unix/sysv/linux/statx_cp.h
> b/sysdeps/unix/sysv/linux/statx_cp.h index fdbb807a31..bf3186ffac
> 100644 --- a/sysdeps/unix/sysv/linux/statx_cp.h
> +++ b/sysdeps/unix/sysv/linux/statx_cp.h
> @@ -18,3 +18,9 @@
>
> extern void __cp_stat64_statx (struct stat64 *to, struct statx *from)
> attribute_hidden;
> +extern void __cp_stat_t64_statx (struct __stat_t64 *to,
> + const struct statx *from)
> + attribute_hidden;
> +extern void __cp_stat64_t64_statx (struct __stat64_t64 *to,
> + const struct statx *from)
> + attribute_hidden;
> diff --git a/sysdeps/unix/sysv/linux/struct_stat_time64.h
> b/sysdeps/unix/sysv/linux/struct_stat_time64.h new file mode 100644
> index 0000000000..b2a51927d0
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/struct_stat_time64.h
> @@ -0,0 +1,122 @@
> +/* Struct stat with 64-bit time support.
> + Copyright (C) 2020 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#ifndef _BITS_STRUCT_STAT_TIME64_H
> +#define _BITS_STRUCT_STAT_TIME64_H 1
> +
> +#if __TIMESIZE == 64
> +# define __stat_t64 stat
> +# define __stat64_t64 stat64
> +#else
> +# include <endian.h>
> +
> +# ifdef __USE_FILE_OFFSET64
> +# define __field64(type, type64, name) type64 name
> +# else
> +# define __field64(type, type64, name) type name
> +# endif
> +
> +/* The definition should be equal to the 'struct __timespec64'
> internal
> + layout. */
> +# if BYTE_ORDER == BIG_ENDIAN
> +# define __fieldts64(name) \
> + __time64_t name; __int32_t :32; __int32_t name ## nsec
> +# else
> +# define __fieldts64(name) \
> + __time64_t name; __int32_t name ## nsec; __int32_t :32
> +# endif
> +
> +/* Workaround for the definition from struct_stat.h */
> +# undef st_atime
> +# undef st_mtime
> +# undef st_ctime
> +
> +struct __stat_t64
> + {
> + __dev_t st_dev; /* Device. */
> + __field64(__ino_t, __ino64_t, st_ino); /* File serial number.
> */
> + __mode_t st_mode; /* File mode. */
> + __nlink_t st_nlink; /* Link count. */
> + __uid_t st_uid; /* User ID of the file's
> owner. */
> + __gid_t st_gid; /* Group ID of the file's
> group.*/
> + __dev_t st_rdev; /* Device number, if
> device. */
> + __field64(__off_t, __off64_t, st_size); /* Size of file, in
> bytes. */
> + __blksize_t st_blksize; /* Optimal block size for
> I/O. */
> + __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte
> blocks */ +# ifdef __USE_XOPEN2K8
> + /* Nanosecond resolution timestamps are stored in a format
> + equivalent to 'struct timespec'. This is the type used
> + whenever possible but the Unix namespace rules do not allow
> the
> + identifier 'timespec' to appear in the <sys/stat.h> header.
> + Therefore we have to handle the use of this header in strictly
> + standard-compliant sources special. */
> + struct __timespec64 st_atim; /* Time of last access. */
> + struct __timespec64 st_mtim; /* Time of last
> modification. */
> + struct __timespec64 st_ctim; /* Time of last status
> change. */ +# define st_atime st_atim.tv_sec /* Backward
> compatibility. */ +# define st_mtime st_mtim.tv_sec
> +# define st_ctime st_ctim.tv_sec
> +# else
> + __fieldts64 (st_atime);
> + __fieldts64 (st_mtime);
> + __fieldts64 (st_ctime);
> +# endif /* __USE_XOPEN2K8 */
> + };
> +
> +# undef __field64
> +
> +#ifdef __USE_LARGEFILE64
> +struct __stat64_t64
> + {
> + __dev_t st_dev; /* Device. */
> + __ino64_t st_ino; /* file serial
> number. */
> + __mode_t st_mode; /* File mode. */
> + __nlink_t st_nlink; /* Link count. */
> + __uid_t st_uid; /* User ID of the file's
> owner. */
> + __gid_t st_gid; /* Group ID of the file's
> group.*/
> + __dev_t st_rdev; /* Device number, if
> device. */
> + __off64_t st_size; /* Size of file, in
> bytes. */
> + __blksize_t st_blksize; /* Optimal block size for
> I/O. */
> + __blkcnt64_t st_blocks; /* Number 512-byte blocks
> allocated. */ +# ifdef __USE_XOPEN2K8
> + /* Nanosecond resolution timestamps are stored in a format
> + equivalent to 'struct timespec'. This is the type used
> + whenever possible but the Unix namespace rules do not allow
> the
> + identifier 'timespec' to appear in the <sys/stat.h> header.
> + Therefore we have to handle the use of this header in strictly
> + standard-compliant sources special. */
> + struct __timespec64 st_atim; /* Time of last access. */
> + struct __timespec64 st_mtim; /* Time of last
> modification. */
> + struct __timespec64 st_ctim; /* Time of last status
> change. */ +# else
> + __fieldts64 (st_atime);
> + __fieldts64 (st_mtime);
> + __fieldts64 (st_ctime);
> +# endif /* __USE_XOPEN2K8 */
> + };
> +# endif /* __USE_LARGEFILE64 */
> +
> +# undef __fieldts64
> +
> +# define _STATBUF_ST_BLKSIZE
> +# define _STATBUF_ST_RDEV
> +# define _STATBUF_ST_NSEC
> +
> +# endif /* __TIMESIZE == 64 */
> +
> +#endif /* _BITS_STRUCT_STAT_TIME64_H */
Despite some very minor comments,
Acked-by: Lukasz Majewski <lukma@denx.de>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 24/07/2020 07:53, Lukasz Majewski wrote:
>>
>> diff --git a/sysdeps/unix/sysv/linux/fstatat.c
>> b/sysdeps/unix/sysv/linux/fstatat.c index 03ddb3f493..f65d3b74a6
>> 100644 --- a/sysdeps/unix/sysv/linux/fstatat.c
>> +++ b/sysdeps/unix/sysv/linux/fstatat.c
>> -# ifdef __NR_fstatat64
>> - /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k,
>> mips32,
>> - microblaze, s390, sh, powerpc, and sparc. */
>> + struct statx stx;
>> + int r = INLINE_SYSCALL_CALL (statx, fd, file, flag,
>> STATX_BASIC_STATS,
>> + &stx);
>
> I'm wondering about the indentation here - I do see 3*TAB and some
> spaces. Shouldn't we only use spaces?
Afaik the GNU code guidelines requires to use TAB indentations instead
of space in this case.
>
> And one more question what is the correct alignment:
> (statx, fd, file, flag
> &stx);
>
> or
> (statx, fd, file, flag
> &stx);
My understanding the latter.
>
>> + if (r == 0 || errno != ENOSYS)
>> + {
>> + if (r == 0)
>> + __cp_stat_t64_statx (st, &stx);
>> + return r;
>> + }
>
> Great that the statx is used here.
>
>> +
>> +# ifdef __NR_fstatat64
>> + /* Both new kABI which uses generic pre 64-bit time Linux ABI
>> (e.g. csky
>> + and nios) and old kABI with non-LFS support (e.g. arm, i386,
>> hppa, m68k,
>> + mips32, microblaze, s390, sh, powerpc, and sparc32). */
>> struct stat64 st64;
>> - int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
>> + r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
>> if (r == 0)
>> {
>> if (! in_ino_t_range (st64.st_ino)
>> @@ -48,7 +51,7 @@ __fstatat (int fd, const char *file, struct stat
>> *st, int flag) || ! in_blkcnt_t_range (st64.st_blocks))
>> return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
>>
>> - /* Clear internal pad and reserved fields. */
>> + /* Clear both pad and reserved fields. */
>> memset (st, 0, sizeof (*st));
>>
>> st->st_dev = st64.st_dev,
>> @@ -61,22 +64,29 @@ __fstatat (int fd, const char *file, struct stat
>> *st, int flag) st->st_size = st64.st_size;
>> st->st_blksize = st64.st_blksize;
>> st->st_blocks = st64.st_blocks;
>> - st->st_atim.tv_sec = st64.st_atim.tv_sec;
>> - st->st_atim.tv_nsec = st64.st_atim.tv_nsec;
>> - st->st_mtim.tv_sec = st64.st_mtim.tv_sec;
>> - st->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;
>> - st->st_ctim.tv_sec = st64.st_ctim.tv_sec;
>> - st->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;
>> + st->st_atim = valid_timespec_to_timespec64 (st64.st_atim);
>> + st->st_mtim = valid_timespec_to_timespec64 (st64.st_mtim);
>> + st->st_ctim = valid_timespec_to_timespec64 (st64.st_ctim);
>> }
>> return r;
>> -# else
>> +# else
>> /* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
>> struct kernel_stat kst;
>> - int r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
>> - return r ?: __cp_kstat_stat (&kst, st);
>> -# endif /* __nr_fstatat64 */
>> -# endif /* STAT_IS_KERNEL_STAT */
>> + r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
>> + return r ?: __cp_kstat_stat_t64 (&kst, st);
>> +# endif /* __NR_fstatat64 */
>> +}
>> +# if __TIMESIZE != 64
>> +libc_hidden_def (__fstatat_time64)
>> +
>> +int
>> +__fstatat (int fd, const char *file, struct stat *buf, int flags)
>> +{
>> + struct __stat_t64 st_t64;
>> + return __fstatat_time64 (fd, file, &st_t64, flags)
>> + ?: __cp_stat_t64_stat (&st_t64, buf);
>> }
>> +# endif
>>
>> weak_alias (__fstatat, fstatat)
>> #endif
>> diff --git a/sysdeps/unix/sysv/linux/fstatat64.c
>> b/sysdeps/unix/sysv/linux/fstatat64.c index 82fab107a5..b3940f0d20
>> 100644 --- a/sysdeps/unix/sysv/linux/fstatat64.c
>> +++ b/sysdeps/unix/sysv/linux/fstatat64.c
>> @@ -19,56 +19,102 @@
>> #define __fstatat __redirect___fstatat
>> #define fstatat __redirect_fstatat
>> #include <sys/stat.h>
>> -#undef __fstatat
>> -#undef fstatat
>> #include <fcntl.h>
>> -
>> +#include <string.h>
>> #include <kernel_stat.h>
>> #include <sysdep.h>
>> -
>> +#include <time.h>
>> #include <statx_cp.h>
>> #include <kstat_cp.h>
>> +#include <stat_t64_cp.h>
>>
>> int
>> -__fstatat64 (int fd, const char *file, struct stat64 *st, int flag)
>> +__fstatat64_time64 (int fd, const char *file, struct __stat64_t64
>> *st,
>> + int flag)
>> {
>> + int r;
>> +
>> +#if (__WORDSIZE == 32 \
>> + && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
>
> I do guess that the above condition is to ensure that 32 bit archs
> (excluding x86_64-x32 - e.g. arm, riscv, etc) use statx?
Yes, this is similar for what is done by SysVIPC fixes.
On Thu, 30 Jul 2020, Adhemerval Zanella via Libc-alpha wrote:
> > And one more question what is the correct alignment:
> > (statx, fd, file, flag
> > &stx);
> >
> > or
> > (statx, fd, file, flag
> > &stx);
>
> My understanding the latter.
The opposite AFAIK, and you can always use `indent -gnu' to get the stuff
right as far as "The GNU Coding Standards" are concerned, except perhaps
for some really obscure code such as I believe some multi-line macros, and
also some newer constructs such as ISO C99 compound literals may not work
out well and have to be fixed up by hand (at least with older versions of
GNU indent; I haven't checked what the most recent behaves like).
Of course GNU indent will not handle project-specific extra rules such as
ours: <https://sourceware.org/glibc/wiki/Style_and_Conventions>.
Maciej
Hi Adhemerval,
> A new struct __stat{64}_t64 type is added with the required
> __timespec64 time definition. Both non-LFS and LFS support were
> done with an extra __NR_statx call plus a conversion to the new
> __stat{64}_t64 type. The statx call is done only for architectures
> with support for 32-bit time_t ABI.
>
> Internally some extra routines to copy from/to struct stat{64}
> to struct __stat{64} used on multiple implementations (stat, fstat,
> lstat, and fstatat) are added on a extra file (stat_t64_cp.c). Aslo
> some extra routines to copy from statx to __stat{64} is added on
> statx_cp.c.
>
> Checked with a build for all affected ABIs. I also checked on x86_64,
> i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x.
When do you plan to pull this patch set to -master?
Those patches have been available for review on the mailing list for
more than two months now.
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 06/10/2020 06:48, Lukasz Majewski wrote:
> Hi Adhemerval,
>
>> A new struct __stat{64}_t64 type is added with the required
>> __timespec64 time definition. Both non-LFS and LFS support were
>> done with an extra __NR_statx call plus a conversion to the new
>> __stat{64}_t64 type. The statx call is done only for architectures
>> with support for 32-bit time_t ABI.
>>
>> Internally some extra routines to copy from/to struct stat{64}
>> to struct __stat{64} used on multiple implementations (stat, fstat,
>> lstat, and fstatat) are added on a extra file (stat_t64_cp.c). Aslo
>> some extra routines to copy from statx to __stat{64} is added on
>> statx_cp.c.
>>
>> Checked with a build for all affected ABIs. I also checked on x86_64,
>> i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x.
>
> When do you plan to pull this patch set to -master?
> Those patches have been available for review on the mailing list for
> more than two months now.
Hi Lukasz, thanks to remind me. I will rebase against master and run
some regressions tests against some platforms and push it.
On 07/10/2020 09:52, Adhemerval Zanella wrote:
>
>
> On 06/10/2020 06:48, Lukasz Majewski wrote:
>> Hi Adhemerval,
>>
>>> A new struct __stat{64}_t64 type is added with the required
>>> __timespec64 time definition. Both non-LFS and LFS support were
>>> done with an extra __NR_statx call plus a conversion to the new
>>> __stat{64}_t64 type. The statx call is done only for architectures
>>> with support for 32-bit time_t ABI.
>>>
>>> Internally some extra routines to copy from/to struct stat{64}
>>> to struct __stat{64} used on multiple implementations (stat, fstat,
>>> lstat, and fstatat) are added on a extra file (stat_t64_cp.c). Aslo
>>> some extra routines to copy from statx to __stat{64} is added on
>>> statx_cp.c.
>>>
>>> Checked with a build for all affected ABIs. I also checked on x86_64,
>>> i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x.
>>
>> When do you plan to pull this patch set to -master?
>> Those patches have been available for review on the mailing list for
>> more than two months now.
>
> Hi Lukasz, thanks to remind me. I will rebase against master and run
> some regressions tests against some platforms and push it.
>
One required change with the rebase is adapt the riscv32 ABI to exclude
the __{f,l}xstat{at} symbol and replace with proper {f,l}stat ones.
It is possible because the new ABI was added on current development
branch, however one minor inconvenient is the toolchain need to be
rebuild with a updated glibc branch to avoid linking failures with
libstd++ (which uses __{f,l}xstat{at}).
Hi Adhemerval,
> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >
> >
> > On 06/10/2020 06:48, Lukasz Majewski wrote:
> >> Hi Adhemerval,
> >>
> >>> A new struct __stat{64}_t64 type is added with the required
> >>> __timespec64 time definition. Both non-LFS and LFS support were
> >>> done with an extra __NR_statx call plus a conversion to the new
> >>> __stat{64}_t64 type. The statx call is done only for
> >>> architectures with support for 32-bit time_t ABI.
> >>>
> >>> Internally some extra routines to copy from/to struct stat{64}
> >>> to struct __stat{64} used on multiple implementations (stat,
> >>> fstat, lstat, and fstatat) are added on a extra file
> >>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
> >>> __stat{64} is added on statx_cp.c.
> >>>
> >>> Checked with a build for all affected ABIs. I also checked on
> >>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>> s390x.
> >>
> >> When do you plan to pull this patch set to -master?
> >> Those patches have been available for review on the mailing list
> >> for more than two months now.
> >
> > Hi Lukasz, thanks to remind me. I will rebase against master and run
> > some regressions tests against some platforms and push it.
> >
>
> One required change with the rebase is adapt the riscv32 ABI to
> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
> ones. It is possible because the new ABI was added on current
> development branch, however one minor inconvenient is the toolchain
> need to be rebuild with a updated glibc branch to avoid linking
> failures with libstd++ (which uses __{f,l}xstat{at}).
>
Does it mean that we would need to run glibc-many-builds with
{checkout,host-libraries,compilers} after we update the branch?
We would need to rebuild the toolchain anyway for rv32 anyway?
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 07/10/2020 17:20, Lukasz Majewski wrote:
> Hi Adhemerval,
>
>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>>
>>>
>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>>> Hi Adhemerval,
>>>>
>>>>> A new struct __stat{64}_t64 type is added with the required
>>>>> __timespec64 time definition. Both non-LFS and LFS support were
>>>>> done with an extra __NR_statx call plus a conversion to the new
>>>>> __stat{64}_t64 type. The statx call is done only for
>>>>> architectures with support for 32-bit time_t ABI.
>>>>>
>>>>> Internally some extra routines to copy from/to struct stat{64}
>>>>> to struct __stat{64} used on multiple implementations (stat,
>>>>> fstat, lstat, and fstatat) are added on a extra file
>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
>>>>> __stat{64} is added on statx_cp.c.
>>>>>
>>>>> Checked with a build for all affected ABIs. I also checked on
>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
>>>>> s390x.
>>>>
>>>> When do you plan to pull this patch set to -master?
>>>> Those patches have been available for review on the mailing list
>>>> for more than two months now.
>>>
>>> Hi Lukasz, thanks to remind me. I will rebase against master and run
>>> some regressions tests against some platforms and push it.
>>>
>>
>> One required change with the rebase is adapt the riscv32 ABI to
>> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
>> ones. It is possible because the new ABI was added on current
>> development branch, however one minor inconvenient is the toolchain
>> need to be rebuild with a updated glibc branch to avoid linking
>> failures with libstd++ (which uses __{f,l}xstat{at}).
>>
>
> Does it mean that we would need to run glibc-many-builds with
> {checkout,host-libraries,compilers} after we update the branch?
>
> We would need to rebuild the toolchain anyway for rv32 anyway?
Yes, at least 'checkout' to get the most recent glibc and 'compilers'
to build a proper toolchain with the expect baseline ABI.
On 07/10/2020 11:25, Adhemerval Zanella wrote:
>
>
> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>
>>
>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>> Hi Adhemerval,
>>>
>>>> A new struct __stat{64}_t64 type is added with the required
>>>> __timespec64 time definition. Both non-LFS and LFS support were
>>>> done with an extra __NR_statx call plus a conversion to the new
>>>> __stat{64}_t64 type. The statx call is done only for architectures
>>>> with support for 32-bit time_t ABI.
>>>>
>>>> Internally some extra routines to copy from/to struct stat{64}
>>>> to struct __stat{64} used on multiple implementations (stat, fstat,
>>>> lstat, and fstatat) are added on a extra file (stat_t64_cp.c). Aslo
>>>> some extra routines to copy from statx to __stat{64} is added on
>>>> statx_cp.c.
>>>>
>>>> Checked with a build for all affected ABIs. I also checked on x86_64,
>>>> i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x.
>>>
>>> When do you plan to pull this patch set to -master?
>>> Those patches have been available for review on the mailing list for
>>> more than two months now.
>>
>> Hi Lukasz, thanks to remind me. I will rebase against master and run
>> some regressions tests against some platforms and push it.
>>
>
> One required change with the rebase is adapt the riscv32 ABI to exclude
> the __{f,l}xstat{at} symbol and replace with proper {f,l}stat ones.
> It is possible because the new ABI was added on current development
> branch, however one minor inconvenient is the toolchain need to be
> rebuild with a updated glibc branch to avoid linking failures with
> libstd++ (which uses __{f,l}xstat{at}).
>
Ok, I have ran the testsuite on x86_64, x32, i686, aarch64, armhf,
powerpc, powerpc64, powerpc64le, sparc64, sparcv9, s390x, and s390
without regression. I will just finish the testing on mips, mips64,
and alpha since they require some specific implementations.
Hi Adhemerval,
> On 07/10/2020 11:25, Adhemerval Zanella wrote:
> >
> >
> > On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >>
> >>
> >> On 06/10/2020 06:48, Lukasz Majewski wrote:
> >>> Hi Adhemerval,
> >>>
> >>>> A new struct __stat{64}_t64 type is added with the required
> >>>> __timespec64 time definition. Both non-LFS and LFS support were
> >>>> done with an extra __NR_statx call plus a conversion to the new
> >>>> __stat{64}_t64 type. The statx call is done only for
> >>>> architectures with support for 32-bit time_t ABI.
> >>>>
> >>>> Internally some extra routines to copy from/to struct stat{64}
> >>>> to struct __stat{64} used on multiple implementations (stat,
> >>>> fstat, lstat, and fstatat) are added on a extra file
> >>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
> >>>> __stat{64} is added on statx_cp.c.
> >>>>
> >>>> Checked with a build for all affected ABIs. I also checked on
> >>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>>> s390x.
> >>>
> >>> When do you plan to pull this patch set to -master?
> >>> Those patches have been available for review on the mailing list
> >>> for more than two months now.
> >>
> >> Hi Lukasz, thanks to remind me. I will rebase against master and
> >> run some regressions tests against some platforms and push it.
> >>
> >
> > One required change with the rebase is adapt the riscv32 ABI to
> > exclude the __{f,l}xstat{at} symbol and replace with proper
> > {f,l}stat ones. It is possible because the new ABI was added on
> > current development branch, however one minor inconvenient is the
> > toolchain need to be rebuild with a updated glibc branch to avoid
> > linking failures with libstd++ (which uses __{f,l}xstat{at}).
> >
>
> Ok, I have ran the testsuite on x86_64, x32, i686, aarch64, armhf,
> powerpc, powerpc64, powerpc64le, sparc64, sparcv9, s390x, and s390
> without regression. I will just finish the testing on mips, mips64,
> and alpha since they require some specific implementations.
>
That would be a huge step forward.
According to list in the following commit message:
https://github.com/lmajewski/y2038_glibc/commit/73215359e184d96b415e87b585a4396b5bd0936c
Then I will send an RFC for enabling support for 64 bit time on
eligible architectures.
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 08/10/2020 04:57, Lukasz Majewski wrote:
> Hi Adhemerval,
>
>> On 07/10/2020 11:25, Adhemerval Zanella wrote:
>>>
>>>
>>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>>>
>>>>
>>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>>>> Hi Adhemerval,
>>>>>
>>>>>> A new struct __stat{64}_t64 type is added with the required
>>>>>> __timespec64 time definition. Both non-LFS and LFS support were
>>>>>> done with an extra __NR_statx call plus a conversion to the new
>>>>>> __stat{64}_t64 type. The statx call is done only for
>>>>>> architectures with support for 32-bit time_t ABI.
>>>>>>
>>>>>> Internally some extra routines to copy from/to struct stat{64}
>>>>>> to struct __stat{64} used on multiple implementations (stat,
>>>>>> fstat, lstat, and fstatat) are added on a extra file
>>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
>>>>>> __stat{64} is added on statx_cp.c.
>>>>>>
>>>>>> Checked with a build for all affected ABIs. I also checked on
>>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
>>>>>> s390x.
>>>>>
>>>>> When do you plan to pull this patch set to -master?
>>>>> Those patches have been available for review on the mailing list
>>>>> for more than two months now.
>>>>
>>>> Hi Lukasz, thanks to remind me. I will rebase against master and
>>>> run some regressions tests against some platforms and push it.
>>>>
>>>
>>> One required change with the rebase is adapt the riscv32 ABI to
>>> exclude the __{f,l}xstat{at} symbol and replace with proper
>>> {f,l}stat ones. It is possible because the new ABI was added on
>>> current development branch, however one minor inconvenient is the
>>> toolchain need to be rebuild with a updated glibc branch to avoid
>>> linking failures with libstd++ (which uses __{f,l}xstat{at}).
>>>
>>
>> Ok, I have ran the testsuite on x86_64, x32, i686, aarch64, armhf,
>> powerpc, powerpc64, powerpc64le, sparc64, sparcv9, s390x, and s390
>> without regression. I will just finish the testing on mips, mips64,
>> and alpha since they require some specific implementations.
>>
>
> That would be a huge step forward.
>
> According to list in the following commit message:
> https://github.com/lmajewski/y2038_glibc/commit/73215359e184d96b415e87b585a4396b5bd0936c
The mips testing caught an issue on where the "linux: Disentangle
fstatat from fxstatat" patch uses INTERNAL_SYSCALL_CALL where
it should use INLINE_SYSCALL_CALL (which sets the errno). I have
fixed and this only affects mips, so my testing should cover all
the affects architectures (I got access to a ia64 machine again
and I will run a regression test once I commit this to master).
>
> Then I will send an RFC for enabling support for 64 bit time on
> eligible architectures.
There still some missing implementations I have on my local tree:
1. wait3: it is a straightforward fix since it just calls __wait4_time64.
2. ftime: we need to move it to a compatibility symbol, so there will
be no need to add a time64 variant to support the deprecated symbol.
3. futimesat: we need to remove the implementation on generic folder
and handle UTIME_NOW and UTIME_OMIT correctly.
4. recvvmsg/recvmsg: we need to handle ancillary data. I recently send
patch that tries to handle it [1] [2] [3]. It is more in a RFC and
I don't think it is strictly necessary.
5. utmp/utmpx/lastlog: I also sent a fix to handle the 64-bit support
on this [4]
I will send 1. 2. 3., since they are the easiest one to review.
[1] https://sourceware.org/pipermail/libc-alpha/2020-September/117484.html
[2] https://sourceware.org/pipermail/libc-alpha/2020-September/117485.html
[3] https://sourceware.org/pipermail/libc-alpha/2020-September/117486.html
[4] https://sourceware.org/pipermail/libc-alpha/2020-August/116850.html
Hi Adhemerval,
> On 08/10/2020 04:57, Lukasz Majewski wrote:
> > Hi Adhemerval,
> >
> >> On 07/10/2020 11:25, Adhemerval Zanella wrote:
> >>>
> >>>
> >>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >>>>
> >>>>
> >>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
> >>>>> Hi Adhemerval,
> >>>>>
> >>>>>> A new struct __stat{64}_t64 type is added with the required
> >>>>>> __timespec64 time definition. Both non-LFS and LFS support
> >>>>>> were done with an extra __NR_statx call plus a conversion to
> >>>>>> the new __stat{64}_t64 type. The statx call is done only for
> >>>>>> architectures with support for 32-bit time_t ABI.
> >>>>>>
> >>>>>> Internally some extra routines to copy from/to struct stat{64}
> >>>>>> to struct __stat{64} used on multiple implementations (stat,
> >>>>>> fstat, lstat, and fstatat) are added on a extra file
> >>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx
> >>>>>> to __stat{64} is added on statx_cp.c.
> >>>>>>
> >>>>>> Checked with a build for all affected ABIs. I also checked on
> >>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>>>>> s390x.
> >>>>>
> >>>>> When do you plan to pull this patch set to -master?
> >>>>> Those patches have been available for review on the mailing list
> >>>>> for more than two months now.
> >>>>
> >>>> Hi Lukasz, thanks to remind me. I will rebase against master and
> >>>> run some regressions tests against some platforms and push it.
> >>>>
> >>>
> >>> One required change with the rebase is adapt the riscv32 ABI to
> >>> exclude the __{f,l}xstat{at} symbol and replace with proper
> >>> {f,l}stat ones. It is possible because the new ABI was added on
> >>> current development branch, however one minor inconvenient is the
> >>> toolchain need to be rebuild with a updated glibc branch to avoid
> >>> linking failures with libstd++ (which uses __{f,l}xstat{at}).
> >>>
> >>
> >> Ok, I have ran the testsuite on x86_64, x32, i686, aarch64, armhf,
> >> powerpc, powerpc64, powerpc64le, sparc64, sparcv9, s390x, and s390
> >> without regression. I will just finish the testing on mips, mips64,
> >> and alpha since they require some specific implementations.
> >>
> >
> > That would be a huge step forward.
> >
> > According to list in the following commit message:
> > https://github.com/lmajewski/y2038_glibc/commit/73215359e184d96b415e87b585a4396b5bd0936c
> >
>
> The mips testing caught an issue on where the "linux: Disentangle
> fstatat from fxstatat" patch uses INTERNAL_SYSCALL_CALL where
> it should use INLINE_SYSCALL_CALL (which sets the errno). I have
> fixed and this only affects mips, so my testing should cover all
> the affects architectures (I got access to a ia64 machine again
> and I will run a regression test once I commit this to master).
Ok. Does it mean that we can expect those patches being pull to -master
soon?
>
> >
> > Then I will send an RFC for enabling support for 64 bit time on
> > eligible architectures.
>
> There still some missing implementations I have on my local tree:
>
> 1. wait3: it is a straightforward fix since it just calls
> __wait4_time64.
Ok.
>2. ftime: we need to move it to a compatibility
> symbol, so there will be no need to add a time64 variant to support
> the deprecated symbol.
IIRC, such deprecation patch for ftime was already pulled to master:
SHA1: 2b5fea833bcd0f651579afd16ed7842770ecbae1
"Consolidate and deprecate ftime"
From the commit description - it shall be removed by Y2038 :-)
> 3. futimesat: we need to remove the
> implementation on generic folder and handle UTIME_NOW and UTIME_OMIT
> correctly.
Ok.
> 4. recvvmsg/recvmsg: we need to handle ancillary data. I
> recently send patch that tries to handle it [1] [2] [3]. It is more
> in a RFC and I don't think it is strictly necessary.
Ok.
> 5. utmp/utmpx/lastlog: I also sent a fix to handle the 64-bit support
> on this [4]
I saw conversion patches in your y2038 tree (sourceware/azanella/y2038)
on top of the stat conversion work, so I guess that it will be next in
the queue.
>
> I will send 1. 2. 3., since they are the easiest one to review.
Ok. Thanks :-)
>
> [1]
> https://sourceware.org/pipermail/libc-alpha/2020-September/117484.html
> [2]
> https://sourceware.org/pipermail/libc-alpha/2020-September/117485.html
> [3]
> https://sourceware.org/pipermail/libc-alpha/2020-September/117486.html
> [4]
> https://sourceware.org/pipermail/libc-alpha/2020-August/116850.html
>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 09/10/2020 12:39, Lukasz Majewski wrote:
>
> Ok. Does it mean that we can expect those patches being pull to -master
> soon?
>
Yes, I just push it upstream.
>>
>>>
>>> Then I will send an RFC for enabling support for 64 bit time on
>>> eligible architectures.
>>
>> There still some missing implementations I have on my local tree:
>>
>> 1. wait3: it is a straightforward fix since it just calls
>> __wait4_time64.
>
> Ok.
>
>> 2. ftime: we need to move it to a compatibility
>> symbol, so there will be no need to add a time64 variant to support
>> the deprecated symbol.
>
> IIRC, such deprecation patch for ftime was already pulled to master:
>
> SHA1: 2b5fea833bcd0f651579afd16ed7842770ecbae1
> "Consolidate and deprecate ftime"
>
> From the commit description - it shall be removed by Y2038 :-)
This patch just make the prototype deprecated, it is still exported on
all architecture and built for newer ABIs (riscv32 for instance).
The idea of my patch is move it to a compat symbol only, meaning that
it won't be available to binaries build against glibc 2.33 and new
ABIs won't provide it (which will be the case for riscv32).
>
>> 3. futimesat: we need to remove the
>> implementation on generic folder and handle UTIME_NOW and UTIME_OMIT
>> correctly.
>
> Ok.
>
>> 4. recvvmsg/recvmsg: we need to handle ancillary data. I
>> recently send patch that tries to handle it [1] [2] [3]. It is more
>> in a RFC and I don't think it is strictly necessary.
>
> Ok.
>
>> 5. utmp/utmpx/lastlog: I also sent a fix to handle the 64-bit support
>> on this [4]
>
> I saw conversion patches in your y2038 tree (sourceware/azanella/y2038)
> on top of the stat conversion work, so I guess that it will be next in
> the queue.
I will rebase my y2038 changes and update my tree.
Hi Adhemerval,
> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >
> >
> > On 06/10/2020 06:48, Lukasz Majewski wrote:
> >> Hi Adhemerval,
> >>
> >>> A new struct __stat{64}_t64 type is added with the required
> >>> __timespec64 time definition. Both non-LFS and LFS support were
> >>> done with an extra __NR_statx call plus a conversion to the new
> >>> __stat{64}_t64 type. The statx call is done only for
> >>> architectures with support for 32-bit time_t ABI.
> >>>
> >>> Internally some extra routines to copy from/to struct stat{64}
> >>> to struct __stat{64} used on multiple implementations (stat,
> >>> fstat, lstat, and fstatat) are added on a extra file
> >>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
> >>> __stat{64} is added on statx_cp.c.
> >>>
> >>> Checked with a build for all affected ABIs. I also checked on
> >>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>> s390x.
> >>
> >> When do you plan to pull this patch set to -master?
> >> Those patches have been available for review on the mailing list
> >> for more than two months now.
> >
> > Hi Lukasz, thanks to remind me. I will rebase against master and run
> > some regressions tests against some platforms and push it.
> >
>
> One required change with the rebase is adapt the riscv32 ABI to
> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
> ones. It is possible because the new ABI was added on current
> development branch, however one minor inconvenient is the toolchain
> need to be rebuild with a updated glibc branch to avoid linking
> failures with libstd++ (which uses __{f,l}xstat{at}).
>
I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox there
is an issue with fstat accesses to files.
When I try to run a program build against newest glibc (installed in
/opt/lib) I do see issues with {f}stat on other libraries (e.g.
/opt/lib/librt.so). To be more specific I do experience the EOVERFLOW
error:
error while loading shared libraries: librt.so.1: cannot stat shared
object: Error 75
The "base" glibc is 2.28 (installed in /lib). The glibc under test is
the newest master installed in /opt/lib.
I'm now investigating this issue.
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 13/10/2020 10:58, Lukasz Majewski wrote:
> Hi Adhemerval,
>
>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>>
>>>
>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>>> Hi Adhemerval,
>>>>
>>>>> A new struct __stat{64}_t64 type is added with the required
>>>>> __timespec64 time definition. Both non-LFS and LFS support were
>>>>> done with an extra __NR_statx call plus a conversion to the new
>>>>> __stat{64}_t64 type. The statx call is done only for
>>>>> architectures with support for 32-bit time_t ABI.
>>>>>
>>>>> Internally some extra routines to copy from/to struct stat{64}
>>>>> to struct __stat{64} used on multiple implementations (stat,
>>>>> fstat, lstat, and fstatat) are added on a extra file
>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
>>>>> __stat{64} is added on statx_cp.c.
>>>>>
>>>>> Checked with a build for all affected ABIs. I also checked on
>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
>>>>> s390x.
>>>>
>>>> When do you plan to pull this patch set to -master?
>>>> Those patches have been available for review on the mailing list
>>>> for more than two months now.
>>>
>>> Hi Lukasz, thanks to remind me. I will rebase against master and run
>>> some regressions tests against some platforms and push it.
>>>
>>
>> One required change with the rebase is adapt the riscv32 ABI to
>> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
>> ones. It is possible because the new ABI was added on current
>> development branch, however one minor inconvenient is the toolchain
>> need to be rebuild with a updated glibc branch to avoid linking
>> failures with libstd++ (which uses __{f,l}xstat{at}).
>>
>
> I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox there
> is an issue with fstat accesses to files.
>
> When I try to run a program build against newest glibc (installed in
> /opt/lib) I do see issues with {f}stat on other libraries (e.g.
> /opt/lib/librt.so). To be more specific I do experience the EOVERFLOW
> error:
>
> error while loading shared libraries: librt.so.1: cannot stat shared
> object: Error 75
>
> The "base" glibc is 2.28 (installed in /lib). The glibc under test is
> the newest master installed in /opt/lib.
>
> I'm now investigating this issue.
I am not sure what it might be based on these information, could you
provide a strace so we can pinpoint what might the issue?
The arm-linux-gnueabihf testing I did was on a aarch64 kernel (4.12.13).
Besides the make check without regression, I could run system binaries
with ./testrun.sh.
I will check on a different kernel/system with a 32-bit kernel.
On Tue, Oct 13, 2020 at 7:18 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
>
>
> On 13/10/2020 10:58, Lukasz Majewski wrote:
> > Hi Adhemerval,
> >
> >> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >>>
> >>>
> >>> On 06/10/2020 06:48, Lukasz Majewski wrote:
> >>>> Hi Adhemerval,
> >>>>
> >>>>> A new struct __stat{64}_t64 type is added with the required
> >>>>> __timespec64 time definition. Both non-LFS and LFS support were
> >>>>> done with an extra __NR_statx call plus a conversion to the new
> >>>>> __stat{64}_t64 type. The statx call is done only for
> >>>>> architectures with support for 32-bit time_t ABI.
> >>>>>
> >>>>> Internally some extra routines to copy from/to struct stat{64}
> >>>>> to struct __stat{64} used on multiple implementations (stat,
> >>>>> fstat, lstat, and fstatat) are added on a extra file
> >>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
> >>>>> __stat{64} is added on statx_cp.c.
> >>>>>
> >>>>> Checked with a build for all affected ABIs. I also checked on
> >>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>>>> s390x.
> >>>>
> >>>> When do you plan to pull this patch set to -master?
> >>>> Those patches have been available for review on the mailing list
> >>>> for more than two months now.
> >>>
> >>> Hi Lukasz, thanks to remind me. I will rebase against master and run
> >>> some regressions tests against some platforms and push it.
> >>>
> >>
> >> One required change with the rebase is adapt the riscv32 ABI to
> >> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
> >> ones. It is possible because the new ABI was added on current
> >> development branch, however one minor inconvenient is the toolchain
> >> need to be rebuild with a updated glibc branch to avoid linking
> >> failures with libstd++ (which uses __{f,l}xstat{at}).
> >>
> >
> > I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox there
> > is an issue with fstat accesses to files.
> >
> > When I try to run a program build against newest glibc (installed in
> > /opt/lib) I do see issues with {f}stat on other libraries (e.g.
> > /opt/lib/librt.so). To be more specific I do experience the EOVERFLOW
> > error:
> >
> > error while loading shared libraries: librt.so.1: cannot stat shared
> > object: Error 75
> >
> > The "base" glibc is 2.28 (installed in /lib). The glibc under test is
> > the newest master installed in /opt/lib.
> >
> > I'm now investigating this issue.
>
> I am not sure what it might be based on these information, could you
> provide a strace so we can pinpoint what might the issue?
>
> The arm-linux-gnueabihf testing I did was on a aarch64 kernel (4.12.13).
> Besides the make check without regression, I could run system binaries
> with ./testrun.sh.
>
> I will check on a different kernel/system with a 32-bit kernel.
FWIW, I got
FAIL: glibcs-armeb-linux-gnueabi-be8 check
FAIL: glibcs-armeb-linux-gnueabi check
FAIL: glibcs-armeb-linux-gnueabihf-be8 check
FAIL: glibcs-armeb-linux-gnueabihf check
FAIL: glibcs-m68k-linux-gnu-coldfire check
FAIL: glibcs-m68k-linux-gnu-coldfire-soft check
FAIL: glibcs-microblazeel-linux-gnu check
FAIL: glibcs-mipsel-linux-gnu-nan2008-soft check
FAIL: glibcs-mipsel-linux-gnu-soft check
FAIL: glibcs-mips-linux-gnu-nan2008-soft check
FAIL: glibcs-mips-linux-gnu-soft check
FAIL: glibcs-powerpc-linux-gnu-soft check
FAIL: glibcs-riscv32-linux-gnu-rv32imac-ilp32 build
FAIL: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 build
FAIL: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d build
FAIL: glibcs-sh3eb-linux-gnu check
FAIL: glibcs-sh4eb-linux-gnu check
FAIL: glibcs-sh4eb-linux-gnu-soft check
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imac-ilp32 check
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imac-ilp32 install
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imac-ilp32 mkdir-lib
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 check
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d check
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d install
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d mkdir-lib
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 install
UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 mkdir-lib
On 13/10/2020 11:23, H.J. Lu wrote:
> On Tue, Oct 13, 2020 at 7:18 AM Adhemerval Zanella via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
>>
>>
>>
>> On 13/10/2020 10:58, Lukasz Majewski wrote:
>>> Hi Adhemerval,
>>>
>>>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>>>>
>>>>>
>>>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>>>>> Hi Adhemerval,
>>>>>>
>>>>>>> A new struct __stat{64}_t64 type is added with the required
>>>>>>> __timespec64 time definition. Both non-LFS and LFS support were
>>>>>>> done with an extra __NR_statx call plus a conversion to the new
>>>>>>> __stat{64}_t64 type. The statx call is done only for
>>>>>>> architectures with support for 32-bit time_t ABI.
>>>>>>>
>>>>>>> Internally some extra routines to copy from/to struct stat{64}
>>>>>>> to struct __stat{64} used on multiple implementations (stat,
>>>>>>> fstat, lstat, and fstatat) are added on a extra file
>>>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
>>>>>>> __stat{64} is added on statx_cp.c.
>>>>>>>
>>>>>>> Checked with a build for all affected ABIs. I also checked on
>>>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
>>>>>>> s390x.
>>>>>>
>>>>>> When do you plan to pull this patch set to -master?
>>>>>> Those patches have been available for review on the mailing list
>>>>>> for more than two months now.
>>>>>
>>>>> Hi Lukasz, thanks to remind me. I will rebase against master and run
>>>>> some regressions tests against some platforms and push it.
>>>>>
>>>>
>>>> One required change with the rebase is adapt the riscv32 ABI to
>>>> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
>>>> ones. It is possible because the new ABI was added on current
>>>> development branch, however one minor inconvenient is the toolchain
>>>> need to be rebuild with a updated glibc branch to avoid linking
>>>> failures with libstd++ (which uses __{f,l}xstat{at}).
>>>>
>>>
>>> I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox there
>>> is an issue with fstat accesses to files.
>>>
>>> When I try to run a program build against newest glibc (installed in
>>> /opt/lib) I do see issues with {f}stat on other libraries (e.g.
>>> /opt/lib/librt.so). To be more specific I do experience the EOVERFLOW
>>> error:
>>>
>>> error while loading shared libraries: librt.so.1: cannot stat shared
>>> object: Error 75
>>>
>>> The "base" glibc is 2.28 (installed in /lib). The glibc under test is
>>> the newest master installed in /opt/lib.
>>>
>>> I'm now investigating this issue.
>>
>> I am not sure what it might be based on these information, could you
>> provide a strace so we can pinpoint what might the issue?
>>
>> The arm-linux-gnueabihf testing I did was on a aarch64 kernel (4.12.13).
>> Besides the make check without regression, I could run system binaries
>> with ./testrun.sh.
>>
>> I will check on a different kernel/system with a 32-bit kernel.
>
> FWIW, I got
>
> FAIL: glibcs-armeb-linux-gnueabi-be8 check
> FAIL: glibcs-armeb-linux-gnueabi check
> FAIL: glibcs-armeb-linux-gnueabihf-be8 check
> FAIL: glibcs-armeb-linux-gnueabihf check
> FAIL: glibcs-m68k-linux-gnu-coldfire check
> FAIL: glibcs-m68k-linux-gnu-coldfire-soft check
> FAIL: glibcs-microblazeel-linux-gnu check
> FAIL: glibcs-mipsel-linux-gnu-nan2008-soft check
> FAIL: glibcs-mipsel-linux-gnu-soft check
> FAIL: glibcs-mips-linux-gnu-nan2008-soft check
> FAIL: glibcs-mips-linux-gnu-soft check
> FAIL: glibcs-powerpc-linux-gnu-soft check
> FAIL: glibcs-riscv32-linux-gnu-rv32imac-ilp32 build
> FAIL: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 build
> FAIL: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d build
> FAIL: glibcs-sh3eb-linux-gnu check
> FAIL: glibcs-sh4eb-linux-gnu check
> FAIL: glibcs-sh4eb-linux-gnu-soft check
Joseph has raised this earlier, I just pushed a fix to update
the libc.abilist (880a12e96df8b330350f565d93677bccf4237e1d).
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imac-ilp32 check
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imac-ilp32 install
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imac-ilp32 mkdir-lib
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 check
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d check
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d install
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32d mkdir-lib
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 install
> UNRESOLVED: glibcs-riscv32-linux-gnu-rv32imafdc-ilp32 mkdir-lib
Since this moved the __{f,l}xstat{at}{64} symbols to compatibility
ones and made it the {f,l}stat{at}{64} the ones exported by libc,
it requires to rebuild the riscv32 toolchain (since libstdc++.so
is linked against the __xstat symbols).
On 13/10/2020 11:18, Adhemerval Zanella wrote:
>
>
> On 13/10/2020 10:58, Lukasz Majewski wrote:
>> Hi Adhemerval,
>>
>>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>>>
>>>>
>>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>>>> Hi Adhemerval,
>>>>>
>>>>>> A new struct __stat{64}_t64 type is added with the required
>>>>>> __timespec64 time definition. Both non-LFS and LFS support were
>>>>>> done with an extra __NR_statx call plus a conversion to the new
>>>>>> __stat{64}_t64 type. The statx call is done only for
>>>>>> architectures with support for 32-bit time_t ABI.
>>>>>>
>>>>>> Internally some extra routines to copy from/to struct stat{64}
>>>>>> to struct __stat{64} used on multiple implementations (stat,
>>>>>> fstat, lstat, and fstatat) are added on a extra file
>>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
>>>>>> __stat{64} is added on statx_cp.c.
>>>>>>
>>>>>> Checked with a build for all affected ABIs. I also checked on
>>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
>>>>>> s390x.
>>>>>
>>>>> When do you plan to pull this patch set to -master?
>>>>> Those patches have been available for review on the mailing list
>>>>> for more than two months now.
>>>>
>>>> Hi Lukasz, thanks to remind me. I will rebase against master and run
>>>> some regressions tests against some platforms and push it.
>>>>
>>>
>>> One required change with the rebase is adapt the riscv32 ABI to
>>> exclude the __{f,l}xstat{at} symbol and replace with proper {f,l}stat
>>> ones. It is possible because the new ABI was added on current
>>> development branch, however one minor inconvenient is the toolchain
>>> need to be rebuild with a updated glibc branch to avoid linking
>>> failures with libstd++ (which uses __{f,l}xstat{at}).
>>>
>>
>> I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox there
>> is an issue with fstat accesses to files.
>>
>> When I try to run a program build against newest glibc (installed in
>> /opt/lib) I do see issues with {f}stat on other libraries (e.g.
>> /opt/lib/librt.so). To be more specific I do experience the EOVERFLOW
>> error:
>>
>> error while loading shared libraries: librt.so.1: cannot stat shared
>> object: Error 75
>>
>> The "base" glibc is 2.28 (installed in /lib). The glibc under test is
>> the newest master installed in /opt/lib.
>>
>> I'm now investigating this issue.
>
> I am not sure what it might be based on these information, could you
> provide a strace so we can pinpoint what might the issue?
>
> The arm-linux-gnueabihf testing I did was on a aarch64 kernel (4.12.13).
> Besides the make check without regression, I could run system binaries
> with ./testrun.sh.
>
> I will check on a different kernel/system with a 32-bit kernel.
Ok, this change in fact triggered a very subtle issue at dl-load.c that
I saw in both arm-linux-gnueabihf system with a 32-bit kernel and on
mips-linux-gnu.
The issue is at:
elf/dl-load.c
1982 if (here_any && (err = errno) != ENOENT && err != EACCES)
1983 /* The file exists and is readable, but something went wrong. */
1984 return -1;
And it is just triggered on system where {f,l}stat{at}{64} issues
__NR_statx and it fails with ENOSYS but later success with the system
stat* syscall.
This code here checks the errno value without checking whether the
previous function call that might change err actually has failed
(in this specific case the stat64 at line 1931). And this due how we
currently implement the y2038 support with INLINE_SYSCALL_CALL
(a function that succeeds is allowed to change errno and it simplifies
the resulting y2038 support a bit).
In fact this check does not really make sense, since either 'fd' will
be different than '0' (meaning it has being opened) or the 'stat64'
at line 1931 failed and 'here_any' won't be set (the stat64 at line
1951 already explicit sets errno in failure case).
Also, git history does not give much information on why it was added
at fist place. So I think we just need to remove this extra check,
you can check if the following patch helps (I am running some
regression tests before sensing it upstream):
diff --git a/elf/dl-load.c b/elf/dl-load.c
index f3201e7c14..39ae43c6ce 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1878,7 +1878,6 @@ open_path (const char *name, size_t namelen, int mode,
size_t cnt;
char *edp;
int here_any = 0;
- int err;
/* If we are debugging the search for libraries print the path
now if it hasn't happened now. */
@@ -1979,9 +1978,6 @@ open_path (const char *name, size_t namelen, int mode,
return -1;
}
}
- if (here_any && (err = errno) != ENOENT && err != EACCES)
- /* The file exists and is readable, but something went wrong. */
- return -1;
/* Remember whether we found anything. */
any |= here_any;
Hi Adhemerval,
> On 13/10/2020 11:18, Adhemerval Zanella wrote:
> >
> >
> > On 13/10/2020 10:58, Lukasz Majewski wrote:
> >> Hi Adhemerval,
> >>
> >>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >>>>
> >>>>
> >>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
> >>>>> Hi Adhemerval,
> >>>>>
> >>>>>> A new struct __stat{64}_t64 type is added with the required
> >>>>>> __timespec64 time definition. Both non-LFS and LFS support
> >>>>>> were done with an extra __NR_statx call plus a conversion to
> >>>>>> the new __stat{64}_t64 type. The statx call is done only for
> >>>>>> architectures with support for 32-bit time_t ABI.
> >>>>>>
> >>>>>> Internally some extra routines to copy from/to struct stat{64}
> >>>>>> to struct __stat{64} used on multiple implementations (stat,
> >>>>>> fstat, lstat, and fstatat) are added on a extra file
> >>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx
> >>>>>> to __stat{64} is added on statx_cp.c.
> >>>>>>
> >>>>>> Checked with a build for all affected ABIs. I also checked on
> >>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>>>>> s390x.
> >>>>>
> >>>>> When do you plan to pull this patch set to -master?
> >>>>> Those patches have been available for review on the mailing list
> >>>>> for more than two months now.
> >>>>
> >>>> Hi Lukasz, thanks to remind me. I will rebase against master and
> >>>> run some regressions tests against some platforms and push it.
> >>>>
> >>>
> >>> One required change with the rebase is adapt the riscv32 ABI to
> >>> exclude the __{f,l}xstat{at} symbol and replace with proper
> >>> {f,l}stat ones. It is possible because the new ABI was added on
> >>> current development branch, however one minor inconvenient is the
> >>> toolchain need to be rebuild with a updated glibc branch to avoid
> >>> linking failures with libstd++ (which uses __{f,l}xstat{at}).
> >>>
> >>
> >> I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox
> >> there is an issue with fstat accesses to files.
> >>
> >> When I try to run a program build against newest glibc (installed
> >> in /opt/lib) I do see issues with {f}stat on other libraries (e.g.
> >> /opt/lib/librt.so). To be more specific I do experience the
> >> EOVERFLOW error:
> >>
> >> error while loading shared libraries: librt.so.1: cannot stat
> >> shared object: Error 75
> >>
> >> The "base" glibc is 2.28 (installed in /lib). The glibc under test
> >> is the newest master installed in /opt/lib.
> >>
> >> I'm now investigating this issue.
> >
> > I am not sure what it might be based on these information, could you
> > provide a strace so we can pinpoint what might the issue?
> >
> > The arm-linux-gnueabihf testing I did was on a aarch64 kernel
> > (4.12.13). Besides the make check without regression, I could run
> > system binaries with ./testrun.sh.
> >
> > I will check on a different kernel/system with a 32-bit kernel.
>
> Ok, this change in fact triggered a very subtle issue at dl-load.c
> that I saw in both arm-linux-gnueabihf system with a 32-bit kernel
> and on mips-linux-gnu.
>
> The issue is at:
>
> elf/dl-load.c
>
> 1982 if (here_any && (err = errno) != ENOENT && err != EACCES)
> 1983 /* The file exists and is readable, but something went
> wrong. */ 1984 return -1;
>
> And it is just triggered on system where {f,l}stat{at}{64} issues
> __NR_statx and it fails with ENOSYS but later success with the system
> stat* syscall.
>
> This code here checks the errno value without checking whether the
> previous function call that might change err actually has failed
> (in this specific case the stat64 at line 1931). And this due how we
> currently implement the y2038 support with INLINE_SYSCALL_CALL
> (a function that succeeds is allowed to change errno and it
> simplifies the resulting y2038 support a bit).
>
> In fact this check does not really make sense, since either 'fd' will
> be different than '0' (meaning it has being opened) or the 'stat64'
> at line 1931 failed and 'here_any' won't be set (the stat64 at line
> 1951 already explicit sets errno in failure case).
>
> Also, git history does not give much information on why it was added
> at fist place. So I think we just need to remove this extra check,
> you can check if the following patch helps (I am running some
> regression tests before sensing it upstream):
>
> diff --git a/elf/dl-load.c b/elf/dl-load.c
> index f3201e7c14..39ae43c6ce 100644
> --- a/elf/dl-load.c
> +++ b/elf/dl-load.c
> @@ -1878,7 +1878,6 @@ open_path (const char *name, size_t namelen,
> int mode, size_t cnt;
> char *edp;
> int here_any = 0;
> - int err;
>
> /* If we are debugging the search for libraries print the path
> now if it hasn't happened now. */
> @@ -1979,9 +1978,6 @@ open_path (const char *name, size_t namelen,
> int mode, return -1;
> }
> }
> - if (here_any && (err = errno) != ENOENT && err != EACCES)
> - /* The file exists and is readable, but something went wrong.
> */
> - return -1;
>
> /* Remember whether we found anything. */
> any |= here_any;
>
>
I've tested this patch and it doesn't fix my issue.
>
>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Hi Adhemerval,
> On 13/10/2020 10:58, Lukasz Majewski wrote:
> > Hi Adhemerval,
> >
> >> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> >>>
> >>>
> >>> On 06/10/2020 06:48, Lukasz Majewski wrote:
> >>>> Hi Adhemerval,
> >>>>
> >>>>> A new struct __stat{64}_t64 type is added with the required
> >>>>> __timespec64 time definition. Both non-LFS and LFS support were
> >>>>> done with an extra __NR_statx call plus a conversion to the new
> >>>>> __stat{64}_t64 type. The statx call is done only for
> >>>>> architectures with support for 32-bit time_t ABI.
> >>>>>
> >>>>> Internally some extra routines to copy from/to struct stat{64}
> >>>>> to struct __stat{64} used on multiple implementations (stat,
> >>>>> fstat, lstat, and fstatat) are added on a extra file
> >>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx to
> >>>>> __stat{64} is added on statx_cp.c.
> >>>>>
> >>>>> Checked with a build for all affected ABIs. I also checked on
> >>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and
> >>>>> s390x.
> >>>>
> >>>> When do you plan to pull this patch set to -master?
> >>>> Those patches have been available for review on the mailing list
> >>>> for more than two months now.
> >>>
> >>> Hi Lukasz, thanks to remind me. I will rebase against master and
> >>> run some regressions tests against some platforms and push it.
> >>>
> >>
> >> One required change with the rebase is adapt the riscv32 ABI to
> >> exclude the __{f,l}xstat{at} symbol and replace with proper
> >> {f,l}stat ones. It is possible because the new ABI was added on
> >> current development branch, however one minor inconvenient is the
> >> toolchain need to be rebuild with a updated glibc branch to avoid
> >> linking failures with libstd++ (which uses __{f,l}xstat{at}).
> >>
> >
> > I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox
> > there is an issue with fstat accesses to files.
> >
> > When I try to run a program build against newest glibc (installed in
> > /opt/lib) I do see issues with {f}stat on other libraries (e.g.
> > /opt/lib/librt.so). To be more specific I do experience the
> > EOVERFLOW error:
> >
> > error while loading shared libraries: librt.so.1: cannot stat shared
> > object: Error 75
> >
> > The "base" glibc is 2.28 (installed in /lib). The glibc under test
> > is the newest master installed in /opt/lib.
> >
> > I'm now investigating this issue.
>
> I am not sure what it might be based on these information, could you
> provide a strace so we can pinpoint what might the issue?
Things are getting more and more interesting.
Let's consider the /opt/lib/librt.so.1
After qemu boot:
root@y2038arm:~# stat /opt/lib/librt.so.1
File: /opt/lib/librt.so.1 -> librt-2.32.9000.so
Size: 18 Blocks: 0 IO Block: 4096 symbolic
link Device: b300h/45824d Inode: 17490 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-13 23:14:56.800000000 +0000 ----> OK
Modify: 2020-10-13 23:14:52.770000000 +0000
Change: 2020-10-13 23:14:52.770000000 +0000
Then I do run gdb (which was build with 2.28 glibc as a base and gcc
8.1, which uses the same library):
gdb test_y2038:
...
(gdb) run
Starting program: /usr/bin/test_y2038
/usr/bin/test_y2038: error while loading shared libraries: librt.so.1:
cannot stat shared object: Error 75 [Inferior 1 (process 1045) exited
with code 0177]
So I've accessed the librt.so.1 with some old - i.e. 2.28 ABI - now:
root@y2038arm:~# stat /opt/lib/librt.so.1
File: /opt/lib/librt.so.1 -> librt-2.32.9000.so
Size: 18 Blocks: 0 IO Block: 4096 symbolic
link Device: b300h/45824d Inode: 17490 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 1901-12-13 20:46:33.625721000 +0000 ----> Overflow
Modify: 2020-10-13 23:14:52.770000000 +0000
Change: 2020-10-13 23:14:52.770000000 +0000
root@y2038arm:~# strace -v -Tf -e trace=file test_y2038
openat(AT_FDCWD, "/opt/lib/librt.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC)
= 3 <0.000409> statx(3, "",
AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS,
{stx_mask=STATX_ALL, stx_blksize=4096, stx_attributes=0, stx_nlink=1,
stx_uid=0, stx_gid=0, stx_mode=S_IFREG|0755, stx_ino=17487,
stx_size=425008, stx_blocks=832,
stx_attributes_mask=STATX_ATTR_COMPRESSED|STATX_ATTR_IMMUTABLE|STATX_ATTR_APPEND|STATX_ATTR_NODUMP|STATX_ATTR_ENCRYPTED,
stx_atime={tv_sec=1602625090, tv_nsec=600000000} /*
2020-10-13T21:38:10.600000000+0000 */, stx_btime={tv_sec=1602622592,
tv_nsec=0} /* 2020-10-13T20:56:32+0000 */,
stx_ctime={tv_sec=2147484284, tv_nsec=335721000},
stx_mtime={tv_sec=2147484263, tv_nsec=545721000}, stx_rdev_major=0,
stx_rdev_minor=0, stx_dev_major=179, stx_dev_minor=0}) = 0 <0.000494>
test_y2038: error while loading shared libraries: librt.so.1: cannot
stat shared object: Error 75 +++ exited with 127 +++
Here the ctime and mtime are wrong - i.e. overflowed.
The system date is not changed:
root@y2038arm:~# date
Tue Oct 13 21:40:02 UTC 2020
root@y2038arm:~# date +%s
1602625224
I will continue investigation tomorrow...
>
> The arm-linux-gnueabihf testing I did was on a aarch64 kernel
> (4.12.13). Besides the make check without regression, I could run
> system binaries with ./testrun.sh.
>
> I will check on a different kernel/system with a 32-bit kernel.
>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Dear Community,
> Hi Adhemerval,
>
> > On 13/10/2020 10:58, Lukasz Majewski wrote:
> > > Hi Adhemerval,
> > >
> > >> On 07/10/2020 09:52, Adhemerval Zanella wrote:
> > >>>
> > >>>
> > >>> On 06/10/2020 06:48, Lukasz Majewski wrote:
> > >>>> Hi Adhemerval,
> > >>>>
> > >>>>> A new struct __stat{64}_t64 type is added with the required
> > >>>>> __timespec64 time definition. Both non-LFS and LFS support
> > >>>>> were done with an extra __NR_statx call plus a conversion to
> > >>>>> the new __stat{64}_t64 type. The statx call is done only for
> > >>>>> architectures with support for 32-bit time_t ABI.
> > >>>>>
> > >>>>> Internally some extra routines to copy from/to struct stat{64}
> > >>>>> to struct __stat{64} used on multiple implementations (stat,
> > >>>>> fstat, lstat, and fstatat) are added on a extra file
> > >>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx
> > >>>>> to __stat{64} is added on statx_cp.c.
> > >>>>>
> > >>>>> Checked with a build for all affected ABIs. I also checked on
> > >>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390,
> > >>>>> and s390x.
> > >>>>
> > >>>> When do you plan to pull this patch set to -master?
> > >>>> Those patches have been available for review on the mailing
> > >>>> list for more than two months now.
> > >>>
> > >>> Hi Lukasz, thanks to remind me. I will rebase against master and
> > >>> run some regressions tests against some platforms and push it.
> > >>>
> > >>
> > >> One required change with the rebase is adapt the riscv32 ABI to
> > >> exclude the __{f,l}xstat{at} symbol and replace with proper
> > >> {f,l}stat ones. It is possible because the new ABI was added on
> > >> current development branch, however one minor inconvenient is the
> > >> toolchain need to be rebuild with a updated glibc branch to avoid
> > >> linking failures with libstd++ (which uses __{f,l}xstat{at}).
> > >>
> > >
> > > I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox
> > > there is an issue with fstat accesses to files.
> > >
> > > When I try to run a program build against newest glibc (installed
> > > in /opt/lib) I do see issues with {f}stat on other libraries (e.g.
> > > /opt/lib/librt.so). To be more specific I do experience the
> > > EOVERFLOW error:
> > >
> > > error while loading shared libraries: librt.so.1: cannot stat
> > > shared object: Error 75
> > >
> > > The "base" glibc is 2.28 (installed in /lib). The glibc under test
> > > is the newest master installed in /opt/lib.
> > >
> > > I'm now investigating this issue.
> >
> > I am not sure what it might be based on these information, could you
> > provide a strace so we can pinpoint what might the issue?
>
> Things are getting more and more interesting.
>
> Let's consider the /opt/lib/librt.so.1
>
> After qemu boot:
>
> root@y2038arm:~# stat /opt/lib/librt.so.1
> File: /opt/lib/librt.so.1 -> librt-2.32.9000.so
> Size: 18 Blocks: 0 IO Block: 4096 symbolic
> link Device: b300h/45824d Inode: 17490 Links: 1
> Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/
> root) Access: 2020-10-13 23:14:56.800000000 +0000 ----> OK
> Modify: 2020-10-13 23:14:52.770000000 +0000
> Change: 2020-10-13 23:14:52.770000000 +0000
>
> Then I do run gdb (which was build with 2.28 glibc as a base and gcc
> 8.1, which uses the same library):
>
> gdb test_y2038:
> ...
> (gdb) run
> Starting program: /usr/bin/test_y2038
> /usr/bin/test_y2038: error while loading shared libraries: librt.so.1:
> cannot stat shared object: Error 75 [Inferior 1 (process 1045) exited
> with code 0177]
>
> So I've accessed the librt.so.1 with some old - i.e. 2.28 ABI - now:
>
> root@y2038arm:~# stat /opt/lib/librt.so.1
> File: /opt/lib/librt.so.1 -> librt-2.32.9000.so
> Size: 18 Blocks: 0 IO Block: 4096 symbolic
> link Device: b300h/45824d Inode: 17490 Links: 1
> Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/
> root) Access: 1901-12-13 20:46:33.625721000 +0000 ----> Overflow
> Modify: 2020-10-13 23:14:52.770000000 +0000
> Change: 2020-10-13 23:14:52.770000000 +0000
>
> root@y2038arm:~# strace -v -Tf -e trace=file test_y2038
>
> openat(AT_FDCWD, "/opt/lib/librt.so.1",
> O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 <0.000409> statx(3, "",
> AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH,
> STATX_BASIC_STATS, {stx_mask=STATX_ALL, stx_blksize=4096,
> stx_attributes=0, stx_nlink=1, stx_uid=0, stx_gid=0,
> stx_mode=S_IFREG|0755, stx_ino=17487, stx_size=425008, stx_blocks=832,
> stx_attributes_mask=STATX_ATTR_COMPRESSED|STATX_ATTR_IMMUTABLE|STATX_ATTR_APPEND|STATX_ATTR_NODUMP|STATX_ATTR_ENCRYPTED,
> stx_atime={tv_sec=1602625090, tv_nsec=600000000} /*
> 2020-10-13T21:38:10.600000000+0000 */, stx_btime={tv_sec=1602622592,
> tv_nsec=0} /* 2020-10-13T20:56:32+0000 */,
> stx_ctime={tv_sec=2147484284, tv_nsec=335721000},
> stx_mtime={tv_sec=2147484263, tv_nsec=545721000}, stx_rdev_major=0,
> stx_rdev_minor=0, stx_dev_major=179, stx_dev_minor=0}) = 0 <0.000494>
> test_y2038: error while loading shared libraries: librt.so.1: cannot
> stat shared object: Error 75 +++ exited with 127 +++
>
>
> Here the ctime and mtime are wrong - i.e. overflowed.
>
> The system date is not changed:
> root@y2038arm:~# date
> Tue Oct 13 21:40:02 UTC 2020
> root@y2038arm:~# date +%s
> 1602625224
>
> I will continue investigation tomorrow...
And now the penny has dropped...
The issue was that:
1. Adhemerval has added extra checks for overflowing the time in
{f}stat{at} patches - this is obviously good :-)
2. In my test system - I've been using "time" syscall (glibc function)
to get the seconds after epoch. This was not yet [*] converted to
support 64 bit time.
3. Some tests (like clock_gettime / clock_settime) require time
modifications after Y2038. Broken time() caused wrong data after
casting from __time_t to __time64_t and the proper time couldn't be
restored.
4. As a result - the date was wrong during the following tests
execution and {mac}time for external files (like librt.so.1,
libgcc_s.so) was set to wrong value.
5. Each subsequent call of {fl}stat{64} returned error due to date
overflow check.
Fix:
Convert time to support 64 bit time.
[*] I will send patches after build-many-glibcs.py and xcheck finish.
>
> >
> > The arm-linux-gnueabihf testing I did was on a aarch64 kernel
> > (4.12.13). Besides the make check without regression, I could run
> > system binaries with ./testrun.sh.
> >
> > I will check on a different kernel/system with a 32-bit kernel.
> >
>
>
>
>
> Best regards,
>
> Lukasz Majewski
>
> --
>
> DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> lukma@denx.de
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 14/10/2020 10:15, Lukasz Majewski wrote:
> Dear Community,
>
>> Hi Adhemerval,
>>
>>> On 13/10/2020 10:58, Lukasz Majewski wrote:
>>>> Hi Adhemerval,
>>>>
>>>>> On 07/10/2020 09:52, Adhemerval Zanella wrote:
>>>>>>
>>>>>>
>>>>>> On 06/10/2020 06:48, Lukasz Majewski wrote:
>>>>>>> Hi Adhemerval,
>>>>>>>
>>>>>>>> A new struct __stat{64}_t64 type is added with the required
>>>>>>>> __timespec64 time definition. Both non-LFS and LFS support
>>>>>>>> were done with an extra __NR_statx call plus a conversion to
>>>>>>>> the new __stat{64}_t64 type. The statx call is done only for
>>>>>>>> architectures with support for 32-bit time_t ABI.
>>>>>>>>
>>>>>>>> Internally some extra routines to copy from/to struct stat{64}
>>>>>>>> to struct __stat{64} used on multiple implementations (stat,
>>>>>>>> fstat, lstat, and fstatat) are added on a extra file
>>>>>>>> (stat_t64_cp.c). Aslo some extra routines to copy from statx
>>>>>>>> to __stat{64} is added on statx_cp.c.
>>>>>>>>
>>>>>>>> Checked with a build for all affected ABIs. I also checked on
>>>>>>>> x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390,
>>>>>>>> and s390x.
>>>>>>>
>>>>>>> When do you plan to pull this patch set to -master?
>>>>>>> Those patches have been available for review on the mailing
>>>>>>> list for more than two months now.
>>>>>>
>>>>>> Hi Lukasz, thanks to remind me. I will rebase against master and
>>>>>> run some regressions tests against some platforms and push it.
>>>>>>
>>>>>
>>>>> One required change with the rebase is adapt the riscv32 ABI to
>>>>> exclude the __{f,l}xstat{at} symbol and replace with proper
>>>>> {f,l}stat ones. It is possible because the new ABI was added on
>>>>> current development branch, however one minor inconvenient is the
>>>>> toolchain need to be rebuild with a updated glibc branch to avoid
>>>>> linking failures with libstd++ (which uses __{f,l}xstat{at}).
>>>>>
>>>>
>>>> I'm not sure if this is related, but on my ARMv7 (32 bit) sandbox
>>>> there is an issue with fstat accesses to files.
>>>>
>>>> When I try to run a program build against newest glibc (installed
>>>> in /opt/lib) I do see issues with {f}stat on other libraries (e.g.
>>>> /opt/lib/librt.so). To be more specific I do experience the
>>>> EOVERFLOW error:
>>>>
>>>> error while loading shared libraries: librt.so.1: cannot stat
>>>> shared object: Error 75
>>>>
>>>> The "base" glibc is 2.28 (installed in /lib). The glibc under test
>>>> is the newest master installed in /opt/lib.
>>>>
>>>> I'm now investigating this issue.
>>>
>>> I am not sure what it might be based on these information, could you
>>> provide a strace so we can pinpoint what might the issue?
>>
>> Things are getting more and more interesting.
>>
>> Let's consider the /opt/lib/librt.so.1
>>
>> After qemu boot:
>>
>> root@y2038arm:~# stat /opt/lib/librt.so.1
>> File: /opt/lib/librt.so.1 -> librt-2.32.9000.so
>> Size: 18 Blocks: 0 IO Block: 4096 symbolic
>> link Device: b300h/45824d Inode: 17490 Links: 1
>> Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/
>> root) Access: 2020-10-13 23:14:56.800000000 +0000 ----> OK
>> Modify: 2020-10-13 23:14:52.770000000 +0000
>> Change: 2020-10-13 23:14:52.770000000 +0000
>>
>> Then I do run gdb (which was build with 2.28 glibc as a base and gcc
>> 8.1, which uses the same library):
>>
>> gdb test_y2038:
>> ...
>> (gdb) run
>> Starting program: /usr/bin/test_y2038
>> /usr/bin/test_y2038: error while loading shared libraries: librt.so.1:
>> cannot stat shared object: Error 75 [Inferior 1 (process 1045) exited
>> with code 0177]
>>
>> So I've accessed the librt.so.1 with some old - i.e. 2.28 ABI - now:
>>
>> root@y2038arm:~# stat /opt/lib/librt.so.1
>> File: /opt/lib/librt.so.1 -> librt-2.32.9000.so
>> Size: 18 Blocks: 0 IO Block: 4096 symbolic
>> link Device: b300h/45824d Inode: 17490 Links: 1
>> Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/
>> root) Access: 1901-12-13 20:46:33.625721000 +0000 ----> Overflow
>> Modify: 2020-10-13 23:14:52.770000000 +0000
>> Change: 2020-10-13 23:14:52.770000000 +0000
>>
>> root@y2038arm:~# strace -v -Tf -e trace=file test_y2038
>>
>> openat(AT_FDCWD, "/opt/lib/librt.so.1",
>> O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 <0.000409> statx(3, "",
>> AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH,
>> STATX_BASIC_STATS, {stx_mask=STATX_ALL, stx_blksize=4096,
>> stx_attributes=0, stx_nlink=1, stx_uid=0, stx_gid=0,
>> stx_mode=S_IFREG|0755, stx_ino=17487, stx_size=425008, stx_blocks=832,
>> stx_attributes_mask=STATX_ATTR_COMPRESSED|STATX_ATTR_IMMUTABLE|STATX_ATTR_APPEND|STATX_ATTR_NODUMP|STATX_ATTR_ENCRYPTED,
>> stx_atime={tv_sec=1602625090, tv_nsec=600000000} /*
>> 2020-10-13T21:38:10.600000000+0000 */, stx_btime={tv_sec=1602622592,
>> tv_nsec=0} /* 2020-10-13T20:56:32+0000 */,
>> stx_ctime={tv_sec=2147484284, tv_nsec=335721000},
>> stx_mtime={tv_sec=2147484263, tv_nsec=545721000}, stx_rdev_major=0,
>> stx_rdev_minor=0, stx_dev_major=179, stx_dev_minor=0}) = 0 <0.000494>
>> test_y2038: error while loading shared libraries: librt.so.1: cannot
>> stat shared object: Error 75 +++ exited with 127 +++
>>
>>
>> Here the ctime and mtime are wrong - i.e. overflowed.
>>
>> The system date is not changed:
>> root@y2038arm:~# date
>> Tue Oct 13 21:40:02 UTC 2020
>> root@y2038arm:~# date +%s
>> 1602625224
>>
>> I will continue investigation tomorrow...
>
> And now the penny has dropped...
>
> The issue was that:
>
> 1. Adhemerval has added extra checks for overflowing the time in
> {f}stat{at} patches - this is obviously good :-)
>
> 2. In my test system - I've been using "time" syscall (glibc function)
> to get the seconds after epoch. This was not yet [*] converted to
> support 64 bit time.
>
> 3. Some tests (like clock_gettime / clock_settime) require time
> modifications after Y2038. Broken time() caused wrong data after
> casting from __time_t to __time64_t and the proper time couldn't be
> restored.
>
> 4. As a result - the date was wrong during the following tests
> execution and {mac}time for external files (like librt.so.1,
> libgcc_s.so) was set to wrong value.
>
> 5. Each subsequent call of {fl}stat{64} returned error due to date
> overflow check.
>
> Fix:
>
> Convert time to support 64 bit time.
>
> [*] I will send patches after build-many-glibcs.py and xcheck finish.
Good to know this is an issue not related to the stat patches itself.
I was confused because you initially didn't describe the test you
are doing in details, so it was hard to pinpoint the issue.
@@ -3,6 +3,8 @@
#ifndef _ISOMAC
# include <xstatver.h>
+# include <struct___timespec64.h>
+# include <struct_stat_time64.h>
# include <stdbool.h>
static inline bool
@@ -44,6 +46,36 @@ hidden_proto (__lstat64)
hidden_proto (__fstatat64)
# endif
+# if __TIMESIZE == 64
+# define __stat_time64 __stat
+# define __stat64_time64 __stat64
+# define __fstat_time64 __fstat
+# define __fstat64_time64 __fstat64
+# define __lstat_time64 __lstat
+# define __lstat64_time64 __lstat64
+# define __fstatat_time64 __fstatat
+# define __fstatat64_time64 __fstatat64
+# else
+extern int __stat_time64 (const char *file, struct __stat_t64 *buf);
+libc_hidden_proto (__stat_time64);
+extern int __stat64_time64 (const char *file, struct __stat64_t64 *buf);
+hidden_proto (__stat64_time64);
+extern int __lstat_time64 (const char *file, struct __stat_t64 *buf);
+libc_hidden_proto (__lstat_time64);
+extern int __lstat64_time64 (const char *file, struct __stat64_t64 *buf);
+hidden_proto (__lstat64_time64);
+extern int __fstat_time64 (int fd, struct __stat_t64 *buf);
+libc_hidden_proto (__fstat_time64);
+extern int __fstat64_time64 (int fd, struct __stat64_t64 *buf);
+hidden_proto (__fstat64_time64);
+extern int __fstatat_time64 (int dirfd, const char *pathname,
+ struct __stat_t64 *buf, int flags);
+libc_hidden_proto (__fstatat_time64);
+extern int __fstatat64_time64 (int dirfd, const char *pathname,
+ struct __stat64_t64 *buf, int flags);
+hidden_proto (__fstatat64_time64);
+# endif
+
extern int __chmod (const char *__file, __mode_t __mode);
libc_hidden_proto (__chmod)
extern int __fchmod (int __fd, __mode_t __mode);
new file mode 100644
@@ -0,0 +1,7 @@
+#ifndef _BITS_STRUCT_STAT_TIME64_H
+#define _BITS_STRUCT_STAT_TIME64_H 1
+
+#define __stat_t64 stat
+#define __stat64_t64 stat64
+
+#endif
@@ -273,7 +273,7 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
open_nocancel open64_nocancel \
openat_nocancel openat64_nocancel \
read_nocancel pread64_nocancel \
- write_nocancel statx_cp
+ write_nocancel statx_cp stat_t64_cp
sysdep_headers += bits/fcntl-linux.h
@@ -19,13 +19,24 @@
#include <sys/stat.h>
#include <kernel_stat.h>
#include <fcntl.h>
+#include <stat_t64_cp.h>
#if !XSTAT_IS_XSTAT64
+int
+__fstat_time64 (int fd, struct __stat_t64 *buf)
+{
+ return __fstatat_time64 (fd, "", buf, AT_EMPTY_PATH);
+}
+# if __TIMESIZE != 64
+libc_hidden_def (__fstat_time64)
+
int
__fstat (int fd, struct stat *buf)
{
- return __fstatat (fd, "", buf, AT_EMPTY_PATH);
+ struct __stat_t64 st_t64;
+ return __fstat_time64 (fd, &st_t64) ?: __cp_stat_t64_stat (&st_t64, buf);
}
+# endif
weak_alias (__fstat, fstat)
#endif
@@ -19,16 +19,30 @@
#define __fstat __redirect___fstat
#define fstat __redirect_fstat
#include <sys/stat.h>
-#undef __fstat
-#undef fstat
#include <fcntl.h>
#include <kernel_stat.h>
+#include <stat_t64_cp.h>
+
+int
+__fstat64_time64 (int fd, struct __stat64_t64 *buf)
+{
+ return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH);
+}
+#if __TIMESIZE != 64
+hidden_def (__fstat64_time64)
int
__fstat64 (int fd, struct stat64 *buf)
{
- return __fstatat64 (fd, "", buf, AT_EMPTY_PATH);
+ struct __stat64_t64 st_t64;
+ return __fstat64_time64 (fd, &st_t64)
+ ?: __cp_stat64_t64_stat64 (&st_t64, buf);
}
+#endif
+
+#undef __fstat
+#undef fstat
+
hidden_def (__fstat64)
weak_alias (__fstat64, fstat64)
@@ -22,25 +22,28 @@
#if !XSTAT_IS_XSTAT64
# include <kstat_cp.h>
+# include <statx_cp.h>
+# include <stat_t64_cp.h>
int
-__fstatat (int fd, const char *file, struct stat *st, int flag)
+__fstatat_time64 (int fd, const char *file, struct __stat_t64 *st, int flag)
{
-# if STAT_IS_KERNEL_STAT
- /* New kABIs which uses generic pre 64-bit time Linux ABI, e.g.
- csky, nios2 */
- int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
- if (r == 0 && (st->__st_ino_pad != 0
- || st->__st_size_pad != 0
- || st->__st_blocks_pad != 0))
- return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
- return r;
-# else
-# ifdef __NR_fstatat64
- /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k, mips32,
- microblaze, s390, sh, powerpc, and sparc. */
+ struct statx stx;
+ int r = INLINE_SYSCALL_CALL (statx, fd, file, flag, STATX_BASIC_STATS,
+ &stx);
+ if (r == 0 || errno != ENOSYS)
+ {
+ if (r == 0)
+ __cp_stat_t64_statx (st, &stx);
+ return r;
+ }
+
+# ifdef __NR_fstatat64
+ /* Both new kABI which uses generic pre 64-bit time Linux ABI (e.g. csky
+ and nios) and old kABI with non-LFS support (e.g. arm, i386, hppa, m68k,
+ mips32, microblaze, s390, sh, powerpc, and sparc32). */
struct stat64 st64;
- int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
+ r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
if (r == 0)
{
if (! in_ino_t_range (st64.st_ino)
@@ -48,7 +51,7 @@ __fstatat (int fd, const char *file, struct stat *st, int flag)
|| ! in_blkcnt_t_range (st64.st_blocks))
return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
- /* Clear internal pad and reserved fields. */
+ /* Clear both pad and reserved fields. */
memset (st, 0, sizeof (*st));
st->st_dev = st64.st_dev,
@@ -61,22 +64,29 @@ __fstatat (int fd, const char *file, struct stat *st, int flag)
st->st_size = st64.st_size;
st->st_blksize = st64.st_blksize;
st->st_blocks = st64.st_blocks;
- st->st_atim.tv_sec = st64.st_atim.tv_sec;
- st->st_atim.tv_nsec = st64.st_atim.tv_nsec;
- st->st_mtim.tv_sec = st64.st_mtim.tv_sec;
- st->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;
- st->st_ctim.tv_sec = st64.st_ctim.tv_sec;
- st->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;
+ st->st_atim = valid_timespec_to_timespec64 (st64.st_atim);
+ st->st_mtim = valid_timespec_to_timespec64 (st64.st_mtim);
+ st->st_ctim = valid_timespec_to_timespec64 (st64.st_ctim);
}
return r;
-# else
+# else
/* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
struct kernel_stat kst;
- int r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
- return r ?: __cp_kstat_stat (&kst, st);
-# endif /* __nr_fstatat64 */
-# endif /* STAT_IS_KERNEL_STAT */
+ r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
+ return r ?: __cp_kstat_stat_t64 (&kst, st);
+# endif /* __NR_fstatat64 */
+}
+# if __TIMESIZE != 64
+libc_hidden_def (__fstatat_time64)
+
+int
+__fstatat (int fd, const char *file, struct stat *buf, int flags)
+{
+ struct __stat_t64 st_t64;
+ return __fstatat_time64 (fd, file, &st_t64, flags)
+ ?: __cp_stat_t64_stat (&st_t64, buf);
}
+# endif
weak_alias (__fstatat, fstatat)
#endif
@@ -19,56 +19,102 @@
#define __fstatat __redirect___fstatat
#define fstatat __redirect_fstatat
#include <sys/stat.h>
-#undef __fstatat
-#undef fstatat
#include <fcntl.h>
-
+#include <string.h>
#include <kernel_stat.h>
#include <sysdep.h>
-
+#include <time.h>
#include <statx_cp.h>
#include <kstat_cp.h>
+#include <stat_t64_cp.h>
int
-__fstatat64 (int fd, const char *file, struct stat64 *st, int flag)
+__fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *st,
+ int flag)
{
+ int r;
+
+#if (__WORDSIZE == 32 \
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+ struct statx tmp;
+ r = INLINE_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
+ STATX_BASIC_STATS, &tmp);
+ if (r == 0 || errno != ENOSYS)
+ {
+ if (r == 0)
+ __cp_stat64_t64_statx (st, &tmp);
+ return r;
+ }
+#endif
+
#if XSTAT_IS_XSTAT64
# ifdef __NR_newfstatat
/* 64-bit kABI, e.g. aarch64, ia64, powerpc64*, s390x, riscv64, and
x86_64. */
- return INLINE_SYSCALL_CALL (newfstatat, fd, file, st, flag);
+ r = INLINE_SYSCALL_CALL (newfstatat, fd, file, st, flag);
# elif defined __NR_fstatat64
# if STAT64_IS_KERNEL_STAT64
- /* 64-bit kABI outlier, e.g. alpha. */
- return INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
+ /* 64-bit kABI outlier, e.g. alpha */
+ r = INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
# else
/* 64-bit kABI outlier, e.g. sparc64. */
struct kernel_stat64 kst64;
- int r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &kst64, flag);
- return r ?: __cp_stat64_kstat64 (st, &kst64);
-# endif
-# else
- /* 32-bit kABI with default 64-bit time_t, e.g. arc, riscv32. */
- struct statx tmp;
- int r = INLINE_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
- STATX_BASIC_STATS, &tmp);
+ r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &kst64, flag);
if (r == 0)
- __cp_stat64_statx (st, &tmp);
- return r;
+ r = __cp_stat64_kstat64 (st, &kst64);
+# endif
# endif
#else
# ifdef __NR_fstatat64
/* All kABIs with non-LFS support, e.g. arm, csky, i386, hppa, m68k,
microblaze, nios2, sh, powerpc32, and sparc32. */
- return INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag);
+ struct stat64 st64;
+ r = INLINE_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
+ if (r == 0)
+ {
+ /* Clear both pad and reserved fields. */
+ memset (st, 0, sizeof (*st));
+
+ st->st_dev = st64.st_dev,
+ st->st_ino = st64.st_ino;
+ st->st_mode = st64.st_mode;
+ st->st_nlink = st64.st_nlink;
+ st->st_uid = st64.st_uid;
+ st->st_gid = st64.st_gid;
+ st->st_rdev = st64.st_rdev;
+ st->st_size = st64.st_size;
+ st->st_blksize = st64.st_blksize;
+ st->st_blocks = st64.st_blocks;
+ st->st_atim = valid_timespec_to_timespec64 (st64.st_atim);
+ st->st_mtim = valid_timespec_to_timespec64 (st64.st_mtim);
+ st->st_ctim = valid_timespec_to_timespec64 (st64.st_ctim);
+ }
# else
/* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
struct kernel_stat kst;
- int r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
- return r ?: __cp_kstat_stat64 (&kst, st);
+ r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
+ if (r == 0)
+ r = __cp_kstat_stat64_t64 (&kst, st);
# endif
#endif
+
+ return r;
}
+#if __TIMESIZE != 64
+hidden_def (__fstatat64_time64)
+
+int
+__fstatat64 (int fd, const char *file, struct stat64 *st, int flags)
+{
+ struct __stat64_t64 st_t64;
+ return __fstatat64_time64 (fd, file, &st_t64, flags)
+ ?: __cp_stat64_t64_stat64 (&st_t64, st);
+}
+#endif
+
+#undef __fstatat
+#undef fstatat
+
hidden_def (__fstatat64)
weak_alias (__fstatat64, fstatat64)
@@ -19,13 +19,24 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <kernel_stat.h>
+#include <stat_t64_cp.h>
#if !XSTAT_IS_XSTAT64
+int
+__lstat_time64 (const char *file, struct __stat_t64 *buf)
+{
+ return __fstatat_time64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
+}
+# if __TIMESIZE != 64
+libc_hidden_def (__lstat_time64)
+
int
__lstat (const char *file, struct stat *buf)
{
- return __fstatat (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
+ struct __stat_t64 st_t64;
+ return __lstat_time64 (file, &st_t64) ?: __cp_stat_t64_stat (&st_t64, buf);
}
+# endif
weak_alias (__lstat, lstat)
#endif
@@ -19,19 +19,32 @@
#define __lstat __redirect___lstat
#define lstat __redirect_lstat
#include <sys/stat.h>
-#undef __lstat
-#undef lstat
#include <fcntl.h>
#include <kernel_stat.h>
+#include <stat_t64_cp.h>
+
+int
+__lstat64_time64 (const char *file, struct __stat64_t64 *buf)
+{
+ return __fstatat64_time64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
+}
+#if __TIMESIZE != 64
+hidden_def (__lstat64_time64)
int
__lstat64 (const char *file, struct stat64 *buf)
{
- return __fstatat64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW);
+ struct __stat64_t64 st_t64;
+ return __lstat64_time64 (file, &st_t64)
+ ?: __cp_stat64_t64_stat64 (&st_t64, buf);
}
+#endif
hidden_def (__lstat64)
weak_alias (__lstat64, lstat64)
+#undef __lstat
+#undef lstat
+
#if XSTAT_IS_XSTAT64
strong_alias (__lstat64, __lstat)
weak_alias (__lstat64, lstat)
@@ -20,23 +20,21 @@
#include <kernel_stat.h>
static inline int
-__cp_kstat_stat (const struct kernel_stat *kst, struct stat *st)
+__cp_kstat_stat_t64 (const struct kernel_stat *kst, struct __stat_t64 *st)
{
+ if (! in_ino_t_range (kst->st_ino)
+ || ! in_off_t_range (kst->st_size)
+ || ! in_blkcnt_t_range (kst->st_blocks))
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
+
st->st_dev = kst->st_dev;
- memset (&st->st_pad1, 0, sizeof (st->st_pad1));
st->st_ino = kst->st_ino;
- if (st->st_ino != kst->st_ino)
- return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
st->st_mode = kst->st_mode;
st->st_nlink = kst->st_nlink;
st->st_uid = kst->st_uid;
st->st_gid = kst->st_gid;
st->st_rdev = kst->st_rdev;
- memset (&st->st_pad2, 0, sizeof (st->st_pad2));
st->st_size = kst->st_size;
- if (st->st_size != kst->st_size)
- return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
- st->st_pad3 = 0;
st->st_atim.tv_sec = kst->st_atime_sec;
st->st_atim.tv_nsec = kst->st_atime_nsec;
st->st_mtim.tv_sec = kst->st_mtime_sec;
@@ -45,26 +43,20 @@ __cp_kstat_stat (const struct kernel_stat *kst, struct stat *st)
st->st_ctim.tv_nsec = kst->st_ctime_nsec;
st->st_blksize = kst->st_blksize;
st->st_blocks = kst->st_blocks;
- if (st->st_blocks != kst->st_blocks)
- return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
- memset (&st->st_pad5, 0, sizeof (st->st_pad5));
return 0;
}
static inline int
-__cp_kstat_stat64 (const struct kernel_stat *kst, struct stat64 *st)
+__cp_kstat_stat64_t64 (const struct kernel_stat *kst, struct __stat64_t64 *st)
{
st->st_dev = kst->st_dev;
- memset (&st->st_pad1, 0, sizeof (st->st_pad1));
st->st_ino = kst->st_ino;
st->st_mode = kst->st_mode;
st->st_nlink = kst->st_nlink;
st->st_uid = kst->st_uid;
st->st_gid = kst->st_gid;
st->st_rdev = kst->st_rdev;
- memset (&st->st_pad2, 0, sizeof (st->st_pad2));
- st->st_pad3 = 0;
st->st_size = kst->st_size;
st->st_blksize = kst->st_blksize;
st->st_blocks = kst->st_blocks;
@@ -74,7 +66,6 @@ __cp_kstat_stat64 (const struct kernel_stat *kst, struct stat64 *st)
st->st_mtim.tv_nsec = kst->st_mtime_nsec;
st->st_ctim.tv_sec = kst->st_ctime_sec;
st->st_ctim.tv_nsec = kst->st_ctime_nsec;
- memset (&st->st_pad4, 0, sizeof (st->st_pad4));
return 0;
}
deleted file mode 100644
@@ -1,3 +0,0 @@
-/* Override the generic statx_cp.c which is only needed for new 32-bit arch
- without stat64 family support.
- */
@@ -19,13 +19,24 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <kernel_stat.h>
+#include <stat_t64_cp.h>
#if !XSTAT_IS_XSTAT64
+int
+__stat_time64 (const char *file, struct __stat_t64 *buf)
+{
+ return __fstatat_time64 (AT_FDCWD, file, buf, 0);
+}
+# if __TIMESIZE != 64
+libc_hidden_def (__stat_time64);
+
int
__stat (const char *file, struct stat *buf)
{
- return __fstatat (AT_FDCWD, file, buf, 0);
+ struct __stat_t64 st_t64;
+ return __stat_time64 (file, &st_t64) ?: __cp_stat_t64_stat (&st_t64, buf);
}
+# endif
weak_alias (__stat, stat)
#endif
@@ -19,16 +19,30 @@
#define __stat __redirect___stat
#define stat __redirect_stat
#include <sys/stat.h>
-#undef __stat
-#undef stat
#include <fcntl.h>
#include <kernel_stat.h>
+#include <stat_t64_cp.h>
+
+int
+__stat64_time64 (const char *file, struct __stat64_t64 *buf)
+{
+ return __fstatat64_time64 (AT_FDCWD, file, buf, 0);
+}
+#if __TIMESIZE != 64
+hidden_def (__stat64_time64)
int
__stat64 (const char *file, struct stat64 *buf)
{
- return __fstatat64 (AT_FDCWD, file, buf, 0);
+ struct __stat64_t64 st_t64;
+ return __stat64_time64 (file, &st_t64)
+ ?: __cp_stat64_t64_stat64 (&st_t64, buf);
}
+#endif
+
+#undef __stat
+#undef stat
+
hidden_def (__stat64)
weak_alias (__stat64, stat64)
new file mode 100644
@@ -0,0 +1,92 @@
+/* Struct stat/stat64 to stat/stat64 conversion for Linux.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <stat_t64_cp.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#if __TIMESIZE != 64
+/* Convert the 64-bit time_t stat ST_T64 to the non-LFS ST stat and returns
+ EOVERFLOW if any of time (access, modification, status) is larger than
+ 32-bit time_t. It is used on non-LFS stat, fstat, lstat, and fstatat to
+ convert from the the 64-bit time_t call. */
+int
+__cp_stat_t64_stat (const struct __stat_t64 *st_t64, struct stat *st)
+{
+ if (! in_time_t_range (st_t64->st_atim.tv_sec)
+ || ! in_time_t_range (st_t64->st_mtim.tv_sec)
+ || ! in_time_t_range (st_t64->st_ctim.tv_sec))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ /* Clear both pad and reserved fields. */
+ memset (st, 0, sizeof (*st));
+
+ st->st_dev = st_t64->st_dev,
+ st->st_ino = st_t64->st_ino;
+ st->st_mode = st_t64->st_mode;
+ st->st_nlink = st_t64->st_nlink;
+ st->st_uid = st_t64->st_uid;
+ st->st_gid = st_t64->st_gid;
+ st->st_rdev = st_t64->st_rdev;
+ st->st_size = st_t64->st_size;
+ st->st_blksize = st_t64->st_blksize;
+ st->st_blocks = st_t64->st_blocks;
+ st->st_atim = valid_timespec64_to_timespec (st_t64->st_atim);
+ st->st_mtim = valid_timespec64_to_timespec (st_t64->st_mtim);
+ st->st_ctim = valid_timespec64_to_timespec (st_t64->st_ctim);
+
+ return 0;
+}
+
+int
+__cp_stat64_t64_stat64 (const struct __stat64_t64 *st64_t64,
+ struct stat64 *st64)
+{
+ if (! in_time_t_range (st64_t64->st_atim.tv_sec)
+ || ! in_time_t_range (st64_t64->st_mtim.tv_sec)
+ || ! in_time_t_range (st64_t64->st_ctim.tv_sec))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ /* Clear both pad and reserved fields. */
+ memset (st64, 0, sizeof (*st64));
+
+ st64->st_dev = st64_t64->st_dev,
+ st64->st_ino = st64_t64->st_ino;
+ st64->st_mode = st64_t64->st_mode;
+ st64->st_nlink = st64_t64->st_nlink;
+ st64->st_uid = st64_t64->st_uid;
+ st64->st_gid = st64_t64->st_gid;
+ st64->st_rdev = st64_t64->st_rdev;
+ st64->st_size = st64_t64->st_size;
+ st64->st_blksize = st64_t64->st_blksize;
+ st64->st_blocks = st64_t64->st_blocks;
+ st64->st_atim = valid_timespec64_to_timespec (st64_t64->st_atim);
+ st64->st_mtim = valid_timespec64_to_timespec (st64_t64->st_mtim);
+ st64->st_ctim = valid_timespec64_to_timespec (st64_t64->st_ctim);
+
+ return 0;
+}
+
+#endif
new file mode 100644
@@ -0,0 +1,28 @@
+/* Copy to/from struct stat with and without 64-bit time_t support.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+
+#if __TIMESIZE != 64
+extern int __cp_stat_t64_stat (const struct __stat_t64 *st_t64,
+ struct stat *st)
+ attribute_hidden;
+extern int __cp_stat64_t64_stat64 (const struct __stat64_t64 *st64_t64,
+ struct stat64 *st64)
+ attribute_hidden;
+#endif
@@ -47,3 +47,57 @@ __cp_stat64_statx (struct stat64 *to, struct statx *from)
to->st_blksize = from->stx_blksize;
}
#endif
+
+void
+__cp_stat_t64_statx (struct __stat_t64 *to, const struct statx *from)
+{
+ /* Clear both pad and reserved fields. */
+ memset (to, 0, sizeof (*to));
+
+ to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8)
+ | ((from->stx_dev_minor & ~0xff) << 12));
+ to->st_ino = from->stx_ino;
+ to->st_mode = from->stx_mode;
+ to->st_nlink = from->stx_nlink;
+ to->st_uid = from->stx_uid;
+ to->st_gid = from->stx_gid;
+ to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8)
+ | ((from->stx_rdev_minor & ~0xff) << 12));
+ to->st_size = from->stx_size;
+ to->st_blksize = from->stx_blksize;
+ to->st_blocks = from->stx_blocks;
+
+ to->st_atime = from->stx_atime.tv_sec;
+ to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
+ to->st_mtime = from->stx_mtime.tv_sec;
+ to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
+ to->st_ctime = from->stx_ctime.tv_sec;
+ to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
+}
+
+void
+__cp_stat64_t64_statx (struct __stat64_t64 *to, const struct statx *from)
+{
+ /* Clear both pad and reserved fields. */
+ memset (to, 0, sizeof (*to));
+
+ to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8)
+ | ((from->stx_dev_minor & ~0xff) << 12));
+ to->st_ino = from->stx_ino;
+ to->st_mode = from->stx_mode;
+ to->st_nlink = from->stx_nlink;
+ to->st_uid = from->stx_uid;
+ to->st_gid = from->stx_gid;
+ to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8)
+ | ((from->stx_rdev_minor & ~0xff) << 12));
+ to->st_size = from->stx_size;
+ to->st_blksize = from->stx_blksize;
+ to->st_blocks = from->stx_blocks;
+
+ to->st_atime = from->stx_atime.tv_sec;
+ to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
+ to->st_mtime = from->stx_mtime.tv_sec;
+ to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
+ to->st_ctime = from->stx_ctime.tv_sec;
+ to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
+}
@@ -18,3 +18,9 @@
extern void __cp_stat64_statx (struct stat64 *to, struct statx *from)
attribute_hidden;
+extern void __cp_stat_t64_statx (struct __stat_t64 *to,
+ const struct statx *from)
+ attribute_hidden;
+extern void __cp_stat64_t64_statx (struct __stat64_t64 *to,
+ const struct statx *from)
+ attribute_hidden;
new file mode 100644
@@ -0,0 +1,122 @@
+/* Struct stat with 64-bit time support.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_STRUCT_STAT_TIME64_H
+#define _BITS_STRUCT_STAT_TIME64_H 1
+
+#if __TIMESIZE == 64
+# define __stat_t64 stat
+# define __stat64_t64 stat64
+#else
+# include <endian.h>
+
+# ifdef __USE_FILE_OFFSET64
+# define __field64(type, type64, name) type64 name
+# else
+# define __field64(type, type64, name) type name
+# endif
+
+/* The definition should be equal to the 'struct __timespec64' internal
+ layout. */
+# if BYTE_ORDER == BIG_ENDIAN
+# define __fieldts64(name) \
+ __time64_t name; __int32_t :32; __int32_t name ## nsec
+# else
+# define __fieldts64(name) \
+ __time64_t name; __int32_t name ## nsec; __int32_t :32
+# endif
+
+/* Workaround for the definition from struct_stat.h */
+# undef st_atime
+# undef st_mtime
+# undef st_ctime
+
+struct __stat_t64
+ {
+ __dev_t st_dev; /* Device. */
+ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct __timespec64 st_atim; /* Time of last access. */
+ struct __timespec64 st_mtim; /* Time of last modification. */
+ struct __timespec64 st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# else
+ __fieldts64 (st_atime);
+ __fieldts64 (st_mtime);
+ __fieldts64 (st_ctime);
+# endif /* __USE_XOPEN2K8 */
+ };
+
+# undef __field64
+
+#ifdef __USE_LARGEFILE64
+struct __stat64_t64
+ {
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct __timespec64 st_atim; /* Time of last access. */
+ struct __timespec64 st_mtim; /* Time of last modification. */
+ struct __timespec64 st_ctim; /* Time of last status change. */
+# else
+ __fieldts64 (st_atime);
+ __fieldts64 (st_mtime);
+ __fieldts64 (st_ctime);
+# endif /* __USE_XOPEN2K8 */
+ };
+# endif /* __USE_LARGEFILE64 */
+
+# undef __fieldts64
+
+# define _STATBUF_ST_BLKSIZE
+# define _STATBUF_ST_RDEV
+# define _STATBUF_ST_NSEC
+
+# endif /* __TIMESIZE == 64 */
+
+#endif /* _BITS_STRUCT_STAT_TIME64_H */