summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chestnykh <dm.chestnykh@gmail.com>2024-02-29 19:35:53 +0300
committerWaldemar Brodkorb <wbx@openadk.org>2024-02-29 19:10:27 +0100
commite0a92849688f557d3e7153ecf6505ee1eedd7248 (patch)
tree0fc3c7fe9c3151e05ddb566f73cdc7a16d0cbad4
parentca4c9ca1286a0bf35c9df4dd313f9ecad793d565 (diff)
Add time64 support for sparc.
By some reason sparc ld.so cannot work properly with statx() system call, so fallback to regular stat() family in ld.so. Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
-rw-r--r--extra/Configs/Config.in1
-rw-r--r--ldso/include/dl-syscall.h10
-rw-r--r--libc/sysdeps/linux/sparc/bits/kernel_stat.h16
-rw-r--r--libc/sysdeps/linux/sparc/bits/sem.h18
-rw-r--r--libc/sysdeps/linux/sparc/bits/typesizes.h12
-rw-r--r--libc/sysdeps/linux/sparc/bits/uClibc_arch_features.h3
6 files changed, 50 insertions, 10 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index ded1f72c9..bae7b4885 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1030,6 +1030,7 @@ config UCLIBC_USE_TIME64
(TARGET_mips && !CONFIG_MIPS_N64_ABI) || \
TARGET_or1k || \
TARGET_powerpc || \
+ TARGET_sparc || \
TARGET_xtensa
# TODO: add support for other architectures
default n
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 666a7c693..b40f58b10 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -20,7 +20,7 @@ extern int _dl_errno;
#define _SYS_MMAN_H 1
#include <bits/mman.h>
-#if defined(__ARCH_HAS_DEPRECATED_SYSCALLS__) && !defined(__UCLIBC_USE_TIME64__)
+#if defined(__ARCH_HAS_DEPRECATED_SYSCALLS__) && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
/* Pull in whatever this particular arch's kernel thinks the kernel version of
* struct stat should look like. It turns out that each arch has a different
* opinion on the subject, and different kernel revs use different names... */
@@ -116,7 +116,7 @@ static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
unsigned long, len, int, prot)
-#if defined __NR_fstatat64 && !defined __NR_stat && !defined(__UCLIBC_USE_TIME64__)
+#if defined __NR_fstatat64 && !defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_fstatat64 __NR_fstatat64
static __always_inline _syscall4(int, _dl_fstatat64, int, fd, const char *,
fn, struct stat *, stat, int, flags)
@@ -126,7 +126,7 @@ static __always_inline int _dl_stat(const char *file_name,
{
return _dl_fstatat64(AT_FDCWD, file_name, buf, 0);
}
-#elif defined __NR_newfstatat && !defined __NR_stat && !defined(__UCLIBC_USE_TIME64__)
+#elif defined __NR_newfstatat && !defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_newfstatat __NR_newfstatat
static __always_inline _syscall4(int, _dl_newfstatat, int, fd, const char *,
fn, struct stat *, stat, int, flags)
@@ -136,7 +136,7 @@ static __always_inline int _dl_stat(const char *file_name,
{
return _dl_newfstatat(AT_FDCWD, file_name, buf, 0);
}
-#elif defined __NR_stat && !defined(__UCLIBC_USE_TIME64__)
+#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_stat __NR_stat
static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
struct stat *, buf)
@@ -160,7 +160,7 @@ static __always_inline int _dl_stat(const char *file_name,
}
#endif
-#if defined __NR_fstat64 && !defined __NR_fstat && !defined(__UCLIBC_USE_TIME64__)
+#if defined __NR_fstat64 && !defined __NR_fstat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_fstat __NR_fstat64
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
#elif defined __NR_fstat
diff --git a/libc/sysdeps/linux/sparc/bits/kernel_stat.h b/libc/sysdeps/linux/sparc/bits/kernel_stat.h
index e960857fe..5e214c72f 100644
--- a/libc/sysdeps/linux/sparc/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/sparc/bits/kernel_stat.h
@@ -5,6 +5,10 @@
* struct kernel_stat should look like... It turns out each arch has a
* different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__)
+#include "internal/time64_helpers.h"
+#endif
+
struct kernel_stat {
unsigned short st_dev;
unsigned long st_ino;
@@ -14,9 +18,15 @@ struct kernel_stat {
unsigned short st_gid;
unsigned short st_rdev;
long st_size;
+#if defined(__UCLIBC_USE_TIME64__)
+ struct __ts32_struct __st_atim32;
+ struct __ts32_struct __st_mtim32;
+ struct __ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif
long st_blksize;
long st_blocks;
unsigned long __unused4[2];
@@ -35,9 +45,15 @@ struct kernel_stat64 {
unsigned int st_blksize;
unsigned char __pad4[8];
unsigned int st_blocks;
+#if defined(__UCLIBC_USE_TIME64__)
+ struct __ts32_struct __st_atim32;
+ struct __ts32_struct __st_mtim32;
+ struct __ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif
unsigned int __unused4;
unsigned int __unused5;
};
diff --git a/libc/sysdeps/linux/sparc/bits/sem.h b/libc/sysdeps/linux/sparc/bits/sem.h
index 04c579fc6..23fd7c2eb 100644
--- a/libc/sysdeps/linux/sparc/bits/sem.h
+++ b/libc/sysdeps/linux/sparc/bits/sem.h
@@ -38,10 +38,24 @@ struct semid_ds
{
struct ipc_perm sem_perm; /* operation permission struct */
unsigned int __pad1;
- __time_t sem_otime; /* last semop() time */
+#if defined(__UCLIBC_USE_TIME64__)
+ unsigned long int __sem_otime_internal_1; /* last semop() time */
+ unsigned long int __sem_otime_internal_2;
+#else
+ __time_t sem_otime; /* last semop() time */
+#endif
unsigned int __pad2;
- __time_t sem_ctime; /* last time changed by semctl() */
+#if defined(__UCLIBC_USE_TIME64__)
+ unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */
+ unsigned long int __sem_ctime_internal_2;
+#else
+ __time_t sem_ctime; /* last time changed by semctl() */
+#endif
unsigned long int sem_nsems; /* number of semaphores in set */
+#if defined(__UCLIBC_USE_TIME64__)
+ __time_t sem_otime;
+ __time_t sem_ctime;
+#endif
unsigned long int __uclibc_unused1;
unsigned long int __uclibc_unused2;
};
diff --git a/libc/sysdeps/linux/sparc/bits/typesizes.h b/libc/sysdeps/linux/sparc/bits/typesizes.h
index 37b7656aa..c7b7f5576 100644
--- a/libc/sysdeps/linux/sparc/bits/typesizes.h
+++ b/libc/sysdeps/linux/sparc/bits/typesizes.h
@@ -46,9 +46,21 @@
#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+
+#ifdef __UCLIBC_USE_TIME64__
+#define __TIME_T_TYPE __S64_TYPE
+#else
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#endif
+
#define __USECONDS_T_TYPE __U32_TYPE
+
+#ifdef __UCLIBC_USE_TIME64__
+#define __SUSECONDS_T_TYPE __S64_TYPE
+#else
#define __SUSECONDS_T_TYPE __S32_TYPE
+#endif
+
#define __DADDR_T_TYPE __S32_TYPE
#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
diff --git a/libc/sysdeps/linux/sparc/bits/uClibc_arch_features.h b/libc/sysdeps/linux/sparc/bits/uClibc_arch_features.h
index 76f5084ff..283a250bb 100644
--- a/libc/sysdeps/linux/sparc/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/sparc/bits/uClibc_arch_features.h
@@ -11,9 +11,6 @@
/* can your target use syscall6() for mmap ? */
#define __UCLIBC_MMAP_HAS_6_ARGS__
-/* does your target use statx */
-#undef __UCLIBC_HAVE_STATX__
-
/* does your target align 64bit values in register pairs ? (32bit arches only) */
#undef __UCLIBC_SYSCALL_ALIGN_64BIT__