devel
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- 1174 discussions
PowerPC is big-endian architecture, so there are some
significant differences in comparison with time64 support
for little-endian architectures like ARM and xtensa.
The main difference is that we strictly need to pass two 64bit
values to system calls because Linux Kernel internally uses
`struct __ketnel_timespec` and similar, which consists of two
64bit fields.
For this reason many files have been changed to convert
timespec-family structures (mixed of 64bit and 32bit values)
to the 64bit-only structures for using as system calls args.
Now time64 syscalls works properly both for LE (ARM, xtensa)
and BE (PPC) memory layouts.
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
extra/Configs/Config.in | 2 +-
libc/inet/socketcalls.c | 16 ++++++++-
libc/misc/sysvipc/sem.c | 16 ++++++++-
libc/signal/sigwait.c | 3 +-
libc/sysdeps/linux/common/__rt_sigtimedwait.c | 23 ++++++++++--
libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +-
libc/sysdeps/linux/common/alarm.c | 2 +-
libc/sysdeps/linux/common/clock_getres.c | 20 ++++++++++-
libc/sysdeps/linux/common/clock_gettime.c | 21 ++++++++++-
libc/sysdeps/linux/common/clock_settime.c | 17 ++++++++-
libc/sysdeps/linux/common/ppoll.c | 15 +++++++-
libc/sysdeps/linux/common/pselect.c | 15 +++++++-
libc/sysdeps/linux/common/select.c | 23 +++++++++---
libc/sysdeps/linux/common/time.c | 2 +-
libc/sysdeps/linux/common/timerfd.c | 23 +++++++++++-
libc/sysdeps/linux/common/utimensat.c | 23 +++++++++++-
libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++--
libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++
libpthread/nptl/pthread_mutex_timedlock.c | 20 +++++++++--
.../sysdeps/pthread/pthread_cond_timedwait.c | 5 +--
.../pthread/pthread_rwlock_timedrdlock.c | 5 +--
.../pthread/pthread_rwlock_timedwrlock.c | 5 +--
.../sysdeps/unix/sysv/linux/lowlevellock.c | 10 +++---
.../sysdeps/unix/sysv/linux/lowlevellock.h | 35 +++++++++++++++++--
.../unix/sysv/linux/lowlevelrobustlock.c | 6 ++--
.../sysdeps/unix/sysv/linux/sem_timedwait.c | 6 ++--
.../sysdeps/unix/sysv/linux/timer_settime.c | 19 +++++++++-
librt/clock_gettime.c | 20 +++++++++--
librt/clock_nanosleep.c | 23 ++++++++++--
librt/mq_timedreceive.c | 22 ++++++++++--
librt/mq_timedsend.c | 20 ++++++++++-
librt/timer_settime.c | 28 +++++++++++++--
32 files changed, 435 insertions(+), 56 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 9351dffc8..f11a63b79 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64
bool "Use *time64 syscalls instead of 32bit ones (if possible)"
- depends on TARGET_arm || TARGET_xtensa
+ depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa
# TODO: add support for other architectures
default n
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c
index eb0983698..7ec439887 100644
--- a/libc/inet/socketcalls.c
+++ b/libc/inet/socketcalls.c
@@ -268,12 +268,26 @@ lt_libc_hidden(recvmsg)
#endif
#ifdef L_recvmmsg
+
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
#ifdef __ASSUME_RECVMMSG_SYSCALL
static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen,
int flags, struct timespec *tmo)
{
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
- return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo);
+ struct ts64_struct __ts64 = {
+ .tv_sec = tmo ? tmo->tv_sec : 0,
+ .tv_nsec = tmo ? tmo->tv_nsec : 0
+ };
+ return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? &__ts64 : 0);
# elif defined(__NR_recvmmsg)
return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo);
# elif __NR_socketcall
diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c
index cd541761c..d0bd0ba28 100644
--- a/libc/misc/sysvipc/sem.c
+++ b/libc/misc/sysvipc/sem.c
@@ -96,7 +96,21 @@ int semop (int semid, struct sembuf *sops, size_t nsops)
#ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64)
-_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) {
+ struct ts64_struct __ts64 = {
+ .tv_sec = timeout ? timeout->tv_sec : 0,
+ .tv_nsec = timeout ? timeout->tv_nsec : 0
+ };
+
+ return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? &__ts64 : 0);
+}
+
#elif defined(__NR_semtimedop)
_syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c
index 3557a039e..b237534cd 100644
--- a/libc/signal/sigwait.c
+++ b/libc/signal/sigwait.c
@@ -24,7 +24,8 @@
#include <signal.h>
#include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__
+#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \
+ defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index bd82ca6d5..cd25fe177 100644
--- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
+++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait
+#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__))
# include <signal.h>
# include <cancel.h>
# ifdef __UCLIBC_HAS_THREADS_NATIVE__
@@ -21,6 +21,15 @@
# include <string.h>
# endif
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout)
{
@@ -53,8 +62,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
real size of the user-level sigset_t. */
/* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
+ struct ts64_struct __ts64 = {
+ .tv_sec = timeout ? timeout->tv_sec : 0,
+ .tv_nsec = timeout ? timeout->tv_nsec : 0
+ };
result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
- timeout, __SYSCALL_SIGSET_T_SIZE);
+ timeout ? &__ts64 : 0, __SYSCALL_SIGSET_T_SIZE);
# else
result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
@@ -71,8 +84,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
# else
/* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
+ struct ts64_struct __ts64 = {
+ .tv_sec = timeout ? timeout->tv_sec : 0,
+ .tv_nsec = timeout ? timeout->tv_nsec : 0
+ };
return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
- timeout, __SYSCALL_SIGSET_T_SIZE);
+ timeout ? &__ts64 : 0, __SYSCALL_SIGSET_T_SIZE);
# else
return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
index d2d176a64..7830b2e2c 100644
--- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
+++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait
+#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))
# define __need_NULL
# include <stddef.h>
# include <signal.h>
diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c
index 4e6e2215b..861f6ad8e 100644
--- a/libc/sysdeps/linux/common/alarm.c
+++ b/libc/sysdeps/linux/common/alarm.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__)
+#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__)
_syscall1(unsigned int, alarm, unsigned int, seconds)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c
index d4b989958..c72b0a21c 100644
--- a/libc/sysdeps/linux/common/clock_getres.c
+++ b/libc/sysdeps/linux/common/clock_getres.c
@@ -10,9 +10,27 @@
#include <sys/syscall.h>
#include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
-_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res)
+int clock_getres(clockid_t clock_id, struct timespec *res)
+{
+ struct ts64_struct __ts64;
+ int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64);
+ if (__ret == 0 && res) {
+ res->tv_sec = __ts64.tv_sec;
+ res->tv_nsec = __ts64.tv_nsec;
+ };
+
+ return __ret;
+}
#elif defined(__NR_clock_getres)
_syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res)
#else
diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c
index a595bd691..dbb767c94 100644
--- a/libc/sysdeps/linux/common/clock_gettime.c
+++ b/libc/sysdeps/linux/common/clock_gettime.c
@@ -11,8 +11,27 @@
#include <sys/syscall.h>
#include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
-_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp)
+int clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+ struct ts64_struct __ts64;
+ int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64);
+ if (tp) {
+ tp->tv_sec = __ts64.tv_sec;
+ tp->tv_nsec = __ts64.tv_nsec;
+ }
+
+ return __ret;
+}
#elif defined(__NR_clock_gettime)
_syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp)
#else
diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c
index 89550af5a..54bfa20e8 100644
--- a/libc/sysdeps/linux/common/clock_settime.c
+++ b/libc/sysdeps/linux/common/clock_settime.c
@@ -12,7 +12,22 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64)
-_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+int clock_settime(clockid_t clock_id, const struct timespec *tp)
+{
+ struct ts64_struct __ts64 = {
+ .tv_sec = tp->tv_sec,
+ .tv_nsec = tp->tv_nsec
+ };
+
+ return INLINE_SYSCALL(clock_settime64, 2, clock_id, &__ts64);
+}
+
#elif defined(__NR_clock_settime)
_syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
#else
diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c
index cb36149c5..16d836b6f 100644
--- a/libc/sysdeps/linux/common/ppoll.c
+++ b/libc/sysdeps/linux/common/ppoll.c
@@ -26,6 +26,15 @@
#include <sys/poll.h>
#include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
static int
__NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
const sigset_t *sigmask)
@@ -38,7 +47,11 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
timeout = &tval;
}
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
- return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
+ struct ts64_struct __ts64 = {
+ .tv_sec = timeout ? timeout->tv_sec : 0,
+ .tv_nsec = timeout ? timeout->tv_nsec : 0
+ };
+ return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? &__ts64 : 0, sigmask, __SYSCALL_SIGSET_T_SIZE);
#else
return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
#endif
diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index 23bdab5cf..a189624ec 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -26,6 +26,15 @@
#include <signal.h>
#include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask)
@@ -57,7 +66,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
sigmask = (void *)&data;
}
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
- return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
+ struct ts64_struct __ts64 = {
+ .tv_sec = timeout ? timeout->tv_sec : 0,
+ .tv_nsec = timeout ? timeout->tv_nsec : 0
+ };
+ return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? &__ts64 : 0, sigmask);
#else
return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
#endif
diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c
index 3132a109c..a55a61df1 100644
--- a/libc/sysdeps/linux/common/select.c
+++ b/libc/sysdeps/linux/common/select.c
@@ -15,17 +15,22 @@
# define __NR_select __NR__newselect
#endif
-#if !defined __NR_select && defined __NR_pselect6
+#if defined(__NR_pselect6) || defined(__NR_pselect6_time64)
# include <stdint.h>
# define USEC_PER_SEC 1000000L
#endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+#endif
+
int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
-#ifdef __NR_select
- return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout);
-#elif defined __NR_pselect6
+#if defined(__NR_pselect6) || defined(__NR_pselect6_time64)
struct timespec _ts, *ts = 0;
if (timeout) {
uint32_t usec;
@@ -47,8 +52,18 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts;
}
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
+ struct ts64_struct __ts64 = {
+ .tv_sec = ts ? ts->tv_sec : 0,
+ .tv_nsec = ts ? ts->tv_nsec : 0
+ };
+ return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, timeout ? &__ts64 : 0, 0);
+#else
return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0);
#endif
+#elif defined(__NR_select)
+ return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout);
+#endif
}
/* we should guard it, but we need it in other files, so let it fail
* if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c
index 22403f174..d084ffaad 100644
--- a/libc/sysdeps/linux/common/time.c
+++ b/libc/sysdeps/linux/common/time.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_time
+#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__)
_syscall_noerr1(time_t, time, time_t *, t)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c
index 0f19b44ed..04db6ed00 100644
--- a/libc/sysdeps/linux/common/timerfd.c
+++ b/libc/sysdeps/linux/common/timerfd.c
@@ -16,12 +16,33 @@
_syscall2(int, timerfd_create, int, clockid, int, flags)
#endif
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct its64_struct {
+ __S64_TYPE interval_tv_sec;
+ __S64_TYPE interval_tv_nsec;
+ __S64_TYPE value_tv_sec;
+ __S64_TYPE value_tv_nsec;
+};
+
+#endif
+
/*
* timerfd_settime()
*/
#if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64)
-_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr)
+int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr)
+{
+ struct its64_struct __its64 = {
+ .interval_tv_sec = utmr->it_interval.tv_sec,
+ .interval_tv_nsec = utmr->it_interval.tv_nsec,
+ .value_tv_sec = utmr->it_value.tv_sec,
+ .value_tv_nsec = utmr->it_value.tv_nsec,
+ };
+
+ return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, &__its64, otmr);
+}
#else
_syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr)
#endif
diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c
index 6a78ebb4f..0c87b5c45 100644
--- a/libc/sysdeps/linux/common/utimensat.c
+++ b/libc/sysdeps/linux/common/utimensat.c
@@ -9,9 +9,30 @@
#include <sys/syscall.h>
#include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct uts64_struct {
+ __S64_TYPE tv_sec1;
+ __S64_TYPE tv_nsec1;
+ __S64_TYPE tv_sec2;
+ __S64_TYPE tv_nsec2;
+};
+
+#endif
+
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64)
-_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
+int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
+{
+ struct uts64_struct __uts64 = {
+ .tv_sec1 = times ? times[0].tv_sec : 0,
+ .tv_nsec1 = times ? times[0].tv_nsec : 0,
+ .tv_sec2 = times ? times[1].tv_sec : 0,
+ .tv_nsec2 = times ? times[1].tv_nsec : 0
+ };
+
+ return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__uts64 : 0, flags);
+}
#else
_syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
#endif
diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
index ce62b2ba2..0e76120ab 100644
--- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
@@ -5,6 +5,16 @@
* struct kernel_stat should look like... It turns out each arch has a
* different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__)
+#include <bits/types.h>
+
+struct ts32_struct {
+ __S32_TYPE tv_sec;
+ __S32_TYPE tv_nsec;
+};
+
+#endif
+
#if __WORDSIZE == 64
#define kernel_stat kernel_stat64
#else
@@ -19,9 +29,15 @@ struct kernel_stat {
__kernel_off_t st_size;
unsigned long st_blksize;
unsigned long 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 long __unused4;
unsigned long __unused5;
};
@@ -39,9 +55,15 @@ struct kernel_stat64 {
long long st_size; /* Size of file, in bytes. */
long st_blksize; /* Optimal block size for I/O. */
long long st_blocks; /* Number 512-byte blocks allocated. */
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
+#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 long int __uclibc_unused4;
unsigned long int __uclibc_unused5;
};
diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h b/libc/sysdeps/linux/powerpc/bits/sem.h
index a9d895374..8d338eac0 100644
--- a/libc/sysdeps/linux/powerpc/bits/sem.h
+++ b/libc/sysdeps/linux/powerpc/bits/sem.h
@@ -35,6 +35,7 @@
#define SETALL 17 /* set all semval's */
+
/* Data structure describing a set of semaphores. */
struct semid_ds
{
@@ -42,16 +43,31 @@ struct semid_ds
#if __WORDSIZE == 32
unsigned int __uclibc_unused1;
#endif
+#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
#if __WORDSIZE == 32
unsigned int __uclibc_unused2;
#endif
+#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 __uclibc_unused3;
unsigned long __uclibc_unused4;
};
+
/* The user should define a union like the following to use it for arguments
for `semctl'.
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c
index 25f9ec3b2..d55495683 100644
--- a/libpthread/nptl/pthread_mutex_timedlock.c
+++ b/libpthread/nptl/pthread_mutex_timedlock.c
@@ -23,6 +23,15 @@
#include <lowlevellock.h>
#include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
/* We need to build this function with optimization to avoid
* lll_timedlock erroring out with
* error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
@@ -265,10 +274,14 @@ pthread_mutex_timedlock (
INTERNAL_SYSCALL_DECL (__err);
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ struct ts64_struct __ts64 = {
+ .tv_sec = abstime ? abstime->tv_sec : 0,
+ .tv_nsec = abstime ? abstime->tv_nsec : 0
+ };
int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
private), 1,
- abstime);
+ &__ts64);
#else
int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
@@ -454,7 +467,7 @@ pthread_mutex_timedlock (
}
struct timeval tv;
- struct timespec rt;
+ struct timespec rt, *rtp;
/* Get the current time. */
(void) gettimeofday (&tv, NULL);
@@ -475,8 +488,9 @@ pthread_mutex_timedlock (
goto failpp;
}
+ rtp = &rt;
lll_futex_timed_wait (&mutex->__data.__lock,
- ceilval | 2, &rt,
+ ceilval | 2, rtp,
PTHREAD_MUTEX_PSHARED (mutex));
}
}
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 49aab0293..1ea2a888a 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -95,7 +95,7 @@ __pthread_cond_timedwait (
while (1)
{
- struct timespec rt;
+ struct timespec rt, *rtp;
{
#ifdef __NR_clock_gettime
INTERNAL_SYSCALL_DECL (err);
@@ -164,8 +164,9 @@ __pthread_cond_timedwait (
cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
+ rtp = &rt;
err = lll_futex_timed_wait (&cond->__data.__futex,
- futex_val, &rt, pshared);
+ futex_val, rtp, pshared);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
index 596f5df51..379e92b43 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
+++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
@@ -81,7 +81,7 @@ pthread_rwlock_timedrdlock (
(void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
- struct timespec rt;
+ struct timespec rt, *rtp;
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
@@ -112,8 +112,9 @@ pthread_rwlock_timedrdlock (
lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer to finish. */
+ rtp = &rt;
err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
- waitval, &rt, rwlock->__data.__shared);
+ waitval, rtp, rwlock->__data.__shared);
/* Get the lock. */
lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
index 0b04b357a..3ce9f9b13 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
+++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
@@ -72,7 +72,7 @@ pthread_rwlock_timedwrlock (
(void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
- struct timespec rt;
+ struct timespec rt, *rtp;
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
@@ -102,8 +102,9 @@ pthread_rwlock_timedwrlock (
lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer or reader(s) to finish. */
+ rtp = &rt;
err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
- waitval, &rt, rwlock->__data.__shared);
+ waitval, rtp, rwlock->__data.__shared);
/* Get the lock. */
lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
index 4294a20b0..5f7301976 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
@@ -63,7 +63,7 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
(void) gettimeofday (&tv, NULL);
/* Compute relative timeout. */
- struct timespec rt;
+ struct timespec rt, *rtp;
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
@@ -76,7 +76,8 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
return ETIMEDOUT;
/* Wait. */
- lll_futex_timed_wait (futex, 2, &rt, private);
+ rtp = &rt;
+ lll_futex_timed_wait (futex, 2, rtp, private);
}
return 0;
@@ -95,7 +96,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
while ((tid = *tidp) != 0)
{
struct timeval tv;
- struct timespec rt;
+ struct timespec rt, *rtp;
/* Get the current time. */
(void) __gettimeofday (&tv, NULL);
@@ -115,7 +116,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use
the private futex operations for this. */
- if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
+ rtp = &rt;
+ if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT)
return ETIMEDOUT;
}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
index e72fe5234..4209a21d3 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
@@ -71,18 +71,49 @@
# endif
#endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), NULL); \
+ __ret; \
+ })
+
+#else
+
+#define lll_futex_wait(futexp, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), NULL); \
+ __ret; \
+ })
+
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+struct __ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#define ptr_timespec_to_ts64(ts) \
+ (&(struct __ts64_struct) {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec})
+
#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
__ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
- (val), (timespec)); \
+ (val), (ptr_timespec_to_ts64(timespec))); \
__ret; \
})
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 7b4e84343..5781359fb 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -73,7 +73,7 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
do
{
struct timeval tv;
- struct timespec rt;
+ struct timespec rt, *rtp;
/* Get the current time. */
(void) __gettimeofday (&tv, NULL);
@@ -99,8 +99,8 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
if (oldval != newval
&& atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
continue;
-
- lll_futex_timed_wait (futex, newval, &rt, private);
+ rtp = &rt;
+ lll_futex_timed_wait (futex, newval, rtp, private);
try:
;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
index 8c3ef47c5..05ba5bc13 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
@@ -51,7 +51,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
while (1)
{
struct timeval tv;
- struct timespec rt;
+ struct timespec rt, *rtp;
int sec, nsec;
/* Get the current time. */
@@ -79,10 +79,12 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
rt.tv_sec = sec;
rt.tv_nsec = nsec;
+ rtp = &rt;
+
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
- err = lll_futex_timed_wait (&isem->value, 0, &rt,
+ err = lll_futex_timed_wait (&isem->value, 0, rtp,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
index 80d242f21..d7c2aa804 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
@@ -38,6 +38,17 @@ static int compat_timer_settime (timer_t timerid, int flags,
# define timer_settime timer_settime_alias
# endif
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct its64_struct {
+ __S64_TYPE interval_tv_sec;
+ __S64_TYPE interval_tv_nsec;
+ __S64_TYPE value_tv_sec;
+ __S64_TYPE value_tv_nsec;
+};
+
+#endif
+
int
timer_settime (
@@ -55,8 +66,14 @@ timer_settime (
/* Delete the kernel timer object. */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
+ struct its64_struct __its64 = {
+ .interval_tv_sec = value->it_interval.tv_sec,
+ .interval_tv_nsec = value->it_interval.tv_nsec,
+ .value_tv_sec = value->it_value.tv_sec,
+ .value_tv_nsec = value->it_value.tv_nsec,
+ };
int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
- value, ovalue);
+ value ? &__its64 : 0, ovalue);
# else
int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
value, ovalue);
diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c
index b66b60231..eff40d68f 100644
--- a/librt/clock_gettime.c
+++ b/librt/clock_gettime.c
@@ -22,10 +22,26 @@
#include <sys/time.h>
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
#define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
+ { \
+ struct ts64_struct __ts64; \
+ retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
+ if (tp) { \
+ tp->tv_sec = __ts64.tv_sec; \
+ tp->tv_nsec = __ts64.tv_nsec; \
+ } \
+ break; \
+ }
#else
#define SYSCALL_GETTIME \
retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \
diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c
index eaae75720..786f7eede 100644
--- a/librt/clock_nanosleep.c
+++ b/librt/clock_nanosleep.c
@@ -21,6 +21,14 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
/* We can simply use the syscall. The CPU clocks are not supported
with this function. */
@@ -36,18 +44,27 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (clock_id == CLOCK_PROCESS_CPUTIME_ID)
clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
- if (SINGLE_THREAD_P)
+ if (SINGLE_THREAD_P) {
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
+ struct ts64_struct __ts64 = {
+ .tv_sec = req ? req->tv_sec : 0,
+ .tv_nsec = req ? req->tv_nsec : 0
+ };
+ r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? &__ts64 : 0, rem);
#else
r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem);
#endif
+ }
else
{
#ifdef __NEW_THREADS
int oldstate = LIBC_CANCEL_ASYNC ();
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
+ struct ts64_struct __ts64_2 = {
+ .tv_sec = req ? req->tv_sec : 0,
+ .tv_nsec = req ? req->tv_nsec : 0
+ };
+ r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? &__ts64_2 : 0, rem);
#else
r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req,
rem);
diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c
index db1ae1aa8..818f54faa 100644
--- a/librt/mq_timedreceive.c
+++ b/librt/mq_timedreceive.c
@@ -8,13 +8,29 @@
#include <unistd.h>
#include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64)
-#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64
+int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout)
+{
+ struct ts64_struct __ts64 = {
+ .tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
+ .tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
+ };
+
+ return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+}
#else
#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive
-#endif
-
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout)
+#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c
index 6afaf5157..e8deea9cb 100644
--- a/librt/mq_timedsend.c
+++ b/librt/mq_timedsend.c
@@ -8,13 +8,31 @@
#include <unistd.h>
#include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct ts64_struct {
+ __S64_TYPE tv_sec;
+ __S64_TYPE tv_nsec;
+};
+
+#endif
+
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64)
#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64
+int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout)
+{
+ struct ts64_struct __ts64 = {
+ .tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
+ .tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
+ };
+
+ return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+}
#else
#define __NR___mq_timedsend_nocancel __NR_mq_timedsend
+_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
#endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
lt_libc_hidden(mq_timedsend)
diff --git a/librt/timer_settime.c b/librt/timer_settime.c
index 022880297..31202b07a 100644
--- a/librt/timer_settime.c
+++ b/librt/timer_settime.c
@@ -9,13 +9,36 @@
#include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct its64_struct {
+ __S64_TYPE interval_tv_sec;
+ __S64_TYPE interval_tv_nsec;
+ __S64_TYPE value_tv_sec;
+ __S64_TYPE value_tv_nsec;
+};
+
+#endif
+
#if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
-#define __NR___syscall_timer_settime __NR_timer_settime64
+int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue)
+{
+ struct timer *kt = (struct timer *)timerid;
+
+ struct its64_struct __its64 = {
+ .interval_tv_sec = value->it_interval.tv_sec,
+ .interval_tv_nsec = value->it_interval.tv_nsec,
+ .value_tv_sec = value->it_value.tv_sec,
+ .value_tv_nsec = value->it_value.tv_nsec,
+ };
+
+ return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? &__its64: 0, ovalue);
+}
#else
+
#define __NR___syscall_timer_settime __NR_timer_settime
-#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid,
int, flags, const void *, value, void *, ovalue);
@@ -31,3 +54,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
}
#endif
+#endif
--
2.43.2
4
19
- xtensa is the second architecture that supports
time64 inside uClibc-ng.
- Linux Kernel always uses 32bit time variables
inside `stat` structures, so there is a need
to use `st_atime`, `st_mtime` and `st_ctime` structures with the same
32bit-wide `tv_sec` and `tv_nsec` variables even if time64 is enabled.
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
extra/Configs/Config.in | 2 +-
libc/sysdeps/linux/xtensa/bits/kernel_stat.h | 22 ++++++++++++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 831b9f689..9351dffc8 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64
bool "Use *time64 syscalls instead of 32bit ones (if possible)"
- depends on TARGET_arm
+ depends on TARGET_arm || TARGET_xtensa
# TODO: add support for other architectures
default n
diff --git a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h
index d884344d3..80ccdb76a 100644
--- a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h
@@ -5,6 +5,16 @@
* struct kernel_stat should look like... It turns out each arch has a
* different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__)
+#include <bits/types.h>
+
+struct ts32_struct {
+ __S32_TYPE tv_sec;
+ __S32_TYPE tv_nsec;
+};
+
+#endif
+
struct kernel_stat {
unsigned long st_dev;
unsigned long st_ino;
@@ -16,9 +26,15 @@ struct kernel_stat {
long st_size;
unsigned long st_blksize;
unsigned long 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 long __unused4;
unsigned long __unused5;
};
@@ -35,9 +51,15 @@ struct kernel_stat64 {
unsigned long st_blksize; /* Optimal block size for I/O. */
unsigned long __uclibc_unused2;
unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
+#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; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
+#endif
unsigned long __uclibc_unused4;
unsigned long __uclibc_unused5;
};
--
2.43.2
3
2
This patch introduces *time64 syscalls support for uClibc-ng.
Currently the redirection of syscalls to their *time64
analogs is fully supported for 32bit ARM (ARMv5, ARMv6, ARMv7).
The main changes that take effect when time64 feature is enabled are:
- sizeof(time_t) is 8.
- There is a possibility os setting date beyond year 2038.
- some syscalls are redirected:
clock_adjtime -> clock_adjtime64
clock_getres -> clock_getres_time64
clock_gettime -> clock_gettime64
clock_nanosleep -> clock_nanosleep_time64
clock_settime -> clock_settime64
futex -> futex_time64
mq_timedreceive -> mq_timedreceive_time64
mq_timedsend -> mq_timedsend_time64
ppoll -> ppoll_time64
pselect6 -> pselect6_time64
recvmmsg -> recvmmsg_time64
rt_sigtimedwait -> rt_sigtimedwait_time64
sched_rr_get_interval -> sched_rr_get_interval_time64
semtimedop -> semtimedop_time64
timer_gettime -> timer_gettime64
timer_settime -> timer_settime64
timerfd_gettime -> timerfd_gettime64
timerfd_settime -> timerfd_settime64
utimensat -> utimensat_time64.
- settimeofday uses clock_settime (like in glibc/musl).
- gettimeofday uses clock_gettime (like in glibc/musl).
- nanosleep uses clock_nanosleep (like in glibc/musl).
- There are some fixes in data structures used by libc and kernel
for correct data handling both with and without enabled time64 support.
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
extra/Configs/Config.in | 9 +++
libc/inet/socketcalls.c | 4 +-
libc/misc/sysvipc/sem.c | 11 +++-
libc/misc/time/time.c | 9 ++-
libc/sysdeps/linux/arm/bits/kernel_stat.h | 24 +++++++-
libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++
libc/sysdeps/linux/common/alarm.c | 2 +-
libc/sysdeps/linux/common/bits/sem.h | 21 ++++---
.../linux/common/bits/syscalls-common.h | 49 ++++++++++++++++
libc/sysdeps/linux/common/bits/typesizes.h | 12 ++++
libc/sysdeps/linux/common/clock_adjtime.c | 6 +-
libc/sysdeps/linux/common/clock_getres.c | 5 +-
libc/sysdeps/linux/common/clock_gettime.c | 4 +-
libc/sysdeps/linux/common/clock_settime.c | 5 +-
libc/sysdeps/linux/common/fstatat.c | 8 +++
libc/sysdeps/linux/common/gettimeofday.c | 11 +++-
libc/sysdeps/linux/common/nanosleep.c | 16 ++++-
libc/sysdeps/linux/common/ppoll.c | 7 ++-
libc/sysdeps/linux/common/pselect.c | 6 +-
.../linux/common/sched_rr_get_interval.c | 5 ++
libc/sysdeps/linux/common/setitimer.c | 32 ++++++++++
libc/sysdeps/linux/common/settimeofday.c | 21 +++++--
libc/sysdeps/linux/common/timerfd.c | 14 ++++-
libc/sysdeps/linux/common/utimensat.c | 6 +-
libc/sysdeps/linux/common/wait4.c | 15 +++++
libc/sysdeps/linux/common/xstatconv.c | 27 +++++++++
libpthread/linuxthreads/condvar.c | 4 ++
libpthread/nptl/init.c | 13 +++++
libpthread/nptl/pthread_condattr_setclock.c | 6 +-
libpthread/nptl/pthread_mutex_init.c | 5 ++
libpthread/nptl/pthread_mutex_lock.c | 13 +++++
libpthread/nptl/pthread_mutex_timedlock.c | 19 ++++++
libpthread/nptl/pthread_mutex_trylock.c | 13 +++++
libpthread/nptl/pthread_mutex_unlock.c | 5 ++
.../sysdeps/pthread/pthread_cond_timedwait.c | 8 +++
.../sysdeps/unix/sysv/linux/lowlevellock.h | 58 ++++++++++++++++++-
.../nptl/sysdeps/unix/sysv/linux/nanosleep.c | 12 +++-
.../sysdeps/unix/sysv/linux/timer_create.c | 5 ++
.../sysdeps/unix/sysv/linux/timer_gettime.c | 4 ++
.../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++
librt/clock_getcpuclockid.c | 15 ++++-
librt/clock_gettime.c | 7 ++-
librt/clock_nanosleep.c | 10 +++-
librt/mq_timedreceive.c | 6 ++
librt/mq_timedsend.c | 6 +-
librt/timer_gettime.c | 6 +-
librt/timer_settime.c | 7 ++-
47 files changed, 519 insertions(+), 47 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 18748d54b..831b9f689 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1024,6 +1024,15 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
Most people will answer Y.
+config UCLIBC_USE_TIME64
+ bool "Use *time64 syscalls instead of 32bit ones (if possible)"
+ depends on TARGET_arm
+ # TODO: add support for other architectures
+ default n
+
+ help
+ Replace 32bit syscalls to their 64/time64 analog if possible.
+
endmenu
menu "Advanced Library Settings"
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c
index edb5ab87e..eb0983698 100644
--- a/libc/inet/socketcalls.c
+++ b/libc/inet/socketcalls.c
@@ -272,7 +272,9 @@ lt_libc_hidden(recvmsg)
static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen,
int flags, struct timespec *tmo)
{
-# ifdef __NR_recvmmsg
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
+ return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo);
+# elif defined(__NR_recvmmsg)
return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo);
# elif __NR_socketcall
unsigned long args[5];
diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c
index 64be1cae0..cd541761c 100644
--- a/libc/misc/sysvipc/sem.c
+++ b/libc/misc/sysvipc/sem.c
@@ -53,7 +53,12 @@ int semctl(int semid, int semnum, int cmd, ...)
arg = va_arg (ap, union semun);
va_end (ap);
#ifdef __NR_semctl
- return __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
+ int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
+#if defined(__UCLIBC_USE_TIME64__)
+ arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
+ arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+#endif
+ return __ret;
#else
return __syscall_ipc(IPCOP_semctl, semid, semnum, cmd|__IPC_64, &arg, NULL);
#endif
@@ -90,7 +95,9 @@ int semop (int semid, struct sembuf *sops, size_t nsops)
#ifdef L_semtimedop
-#ifdef __NR_semtimedop
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64)
+_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
+#elif defined(__NR_semtimedop)
_syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
#else
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
index cd189169a..ed79e7192 100644
--- a/libc/misc/time/time.c
+++ b/libc/misc/time/time.c
@@ -2478,9 +2478,16 @@ DST_CORRECT:
+ p[3]) + p[7])));
DST_CORRECT:
+#if defined(__UCLIBC_USE_TIME64__)
+ if (((unsigned long long)(secs - LLONG_MIN))
+ > (((unsigned long long)LLONG_MAX) - LLONG_MIN)
+ )
+#else
if (((unsigned long long)(secs - LONG_MIN))
> (((unsigned long long)LONG_MAX) - LONG_MIN)
- ) {
+ )
+#endif
+ {
t = ((time_t)(-1));
goto DONE;
}
diff --git a/libc/sysdeps/linux/arm/bits/kernel_stat.h b/libc/sysdeps/linux/arm/bits/kernel_stat.h
index b293dfc05..8bddb4085 100644
--- a/libc/sysdeps/linux/arm/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/arm/bits/kernel_stat.h
@@ -5,6 +5,17 @@
* struct kernel_stat should look like... It turns out each arch has a
* different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__)
+
+#include <bits/types.h>
+
+struct ts32_struct {
+ __S32_TYPE tv_sec;
+ __S32_TYPE tv_nsec;
+};
+
+#endif
+
struct kernel_stat {
#if defined(__ARMEB__)
unsigned short st_dev;
@@ -26,9 +37,15 @@ struct kernel_stat {
unsigned long st_size;
unsigned long st_blksize;
unsigned long 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 long __uclibc_unused4;
unsigned long __uclibc_unused5;
};
@@ -50,10 +67,15 @@ struct kernel_stat64 {
long long st_size;
unsigned long st_blksize;
unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
-
+#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 long long st_ino;
#ifndef __ARM_EABI__
} __attribute__((packed));
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index f4244148d..bd82ca6d5 100644
--- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
+++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
@@ -52,8 +52,13 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
/* on uClibc we use the kernel sigset_t size */
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
+ result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
+ timeout, __SYSCALL_SIGSET_T_SIZE);
+# else
result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
+# endif
/* The kernel generates a SI_TKILL code in si_code in case tkill is
used. tkill is transparently used in raise(). Since having
@@ -65,9 +70,14 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
return result;
# else
/* on uClibc we use the kernel sigset_t size */
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
+ return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
+ timeout, __SYSCALL_SIGSET_T_SIZE);
+# else
return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
# endif
+# endif
}
CANCELLABLE_SYSCALL(int, sigtimedwait,
(const sigset_t *set, siginfo_t *info, const struct timespec *timeout),
diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c
index dc43fe732..4e6e2215b 100644
--- a/libc/sysdeps/linux/common/alarm.c
+++ b/libc/sysdeps/linux/common/alarm.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <unistd.h>
-#ifdef __NR_alarm
+#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__)
_syscall1(unsigned int, alarm, unsigned int, seconds)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h
index 910c4b714..06a256259 100644
--- a/libc/sysdeps/linux/common/bits/sem.h
+++ b/libc/sysdeps/linux/common/bits/sem.h
@@ -39,17 +39,22 @@
struct semid_ds
{
struct ipc_perm sem_perm; /* operation permission struct */
- __time_t sem_otime; /* last semop() time */
-#if __WORDSIZE == 32
- unsigned long int __uclibc_unused1;
-#endif
- __time_t sem_ctime; /* last time changed by semctl() */
-#if __WORDSIZE == 32
- unsigned long int __uclibc_unused2;
+
+ unsigned long int __sem_otime_internal_1;
+ unsigned long int __sem_otime_internal_2;
+ unsigned long int __sem_ctime_internal_1;
+ unsigned long int __sem_ctime_internal_2;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ unsigned short int sem_nsems; /* number of semaphores in set */
+ char __paddind[sizeof(long int) - sizeof(short int)];
+#else
+ char __padding[sizeof(long int) - sizeof(short int)];
+ unsigned short int sem_nsems; /* number of semaphores in set */
#endif
- unsigned long int sem_nsems; /* number of semaphores in set */
unsigned long int __uclibc_unused3;
unsigned long int __uclibc_unused4;
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
};
/* The user should define a union like the following to use it for arguments
diff --git a/libc/sysdeps/linux/common/bits/syscalls-common.h b/libc/sysdeps/linux/common/bits/syscalls-common.h
index adae45aac..c3b193e6f 100755
--- a/libc/sysdeps/linux/common/bits/syscalls-common.h
+++ b/libc/sysdeps/linux/common/bits/syscalls-common.h
@@ -99,14 +99,40 @@ type name(C_DECL_ARGS_##nargs(args)) { \
return (type)INLINE_SYSCALL(name, nargs, C_ARGS_##nargs(args)); \
}
+#define SYSCALL_FUNC_TIME64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL(name##_time64, nargs, C_ARGS_##nargs(args)); \
+}
+
+#define SYSCALL_FUNC_64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL(name##64, nargs, C_ARGS_##nargs(args)); \
+}
+
+
#define SYSCALL_NOERR_FUNC(nargs, type, name, args...) \
type name(C_DECL_ARGS_##nargs(args)) { \
return (type)INLINE_SYSCALL_NOERR(name, nargs, C_ARGS_##nargs(args)); \
}
+#define SYSCALL_NOERR_FUNC_TIME64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL_NOERR(name##_time64, nargs, C_ARGS_##nargs(args)); \
+}
+
+#define SYSCALL_NOERR_FUNC_64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL_NOERR(name##64, nargs, C_ARGS_##nargs(args)); \
+}
+
#define SYSCALL_FUNC_BODY(nargs, type, name, args...) \
return (type)INLINE_SYSCALL(name, nargs, C_ARGS_##nargs(args));
+#define SYSCALL_FUNC_BODY_TIME64(nargs, type, name, args...) \
+ return (type)INLINE_SYSCALL(name##_time64, nargs, C_ARGS_##nargs(args));
+
+#define SYSCALL_FUNC_BODY_64(nargs, type, name, args...) \
+ return (type)INLINE_SYSCALL(name##64, nargs, C_ARGS_##nargs(args));
#define _syscall0(args...) SYSCALL_FUNC(0, args)
#define _syscall_noerr0(args...) SYSCALL_NOERR_FUNC(0, args)
@@ -119,6 +145,29 @@ type name(C_DECL_ARGS_##nargs(args)) { \
#define _syscall5(args...) SYSCALL_FUNC(5, args)
#define _syscall6(args...) SYSCALL_FUNC(6, args)
+#define _syscall0_time64(args...) SYSCALL_FUNC_TIME64(0, args)
+#define _syscall_noerr0_time64(args...) SYSCALL_NOERR_FUNC_TIME64(0, args)
+#define _syscall1_time64(args...) SYSCALL_FUNC_TIME64(1, args)
+#define _syscall_noerr1_time64(args...) SYSCALL_NOERR_FUNC_TIME64(1, args)
+#define _syscall2_time64(args...) SYSCALL_FUNC_TIME64(2, args)
+#define _syscall2_body_time64(args...) SYSCALL_FUNC_BODY_TIME64(2, args)
+#define _syscall3_time64(args...) SYSCALL_FUNC_TIME64(3, args)
+#define _syscall4_time64(args...) SYSCALL_FUNC_TIME64(4, args)
+#define _syscall5_time64(args...) SYSCALL_FUNC_TIME64(5, args)
+#define _syscall6_time64(args...) SYSCALL_FUNC_TIME64(6, args)
+
+#define _syscall0_64(args...) SYSCALL_FUNC_64(0, args)
+#define _syscall_noerr0_64(args...) SYSCALL_NOERR_FUNC_64(0, args)
+#define _syscall1_64(args...) SYSCALL_FUNC_64(1, args)
+#define _syscall_noerr1_64(args...) SYSCALL_NOERR_FUNC_64(1, args)
+#define _syscall2_64(args...) SYSCALL_FUNC_64(2, args)
+#define _syscall2_body_64(args...) SYSCALL_FUNC_BODY_64(2, args)
+#define _syscall3_64(args...) SYSCALL_FUNC_64(3, args)
+#define _syscall4_64(args...) SYSCALL_FUNC_64(4, args)
+#define _syscall5_64(args...) SYSCALL_FUNC_64(5, args)
+#define _syscall6_64(args...) SYSCALL_FUNC_64(6, args)
+
+
#endif /* _syscall0 */
#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/linux/common/bits/typesizes.h b/libc/sysdeps/linux/common/bits/typesizes.h
index e1c5a27bb..dcb2c3b0a 100644
--- a/libc/sysdeps/linux/common/bits/typesizes.h
+++ b/libc/sysdeps/linux/common/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 /* __UCLIBC_USE_TIME64__ */
+
#define __USECONDS_T_TYPE __U32_TYPE
+
+#ifdef __UCLIBC_USE_TIME64__
+#define __SUSECONDS_T_TYPE __S64_TYPE
+#else
#define __SUSECONDS_T_TYPE __SLONGWORD_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/common/clock_adjtime.c b/libc/sysdeps/linux/common/clock_adjtime.c
index 9f55d4527..53f64e9d5 100644
--- a/libc/sysdeps/linux/common/clock_adjtime.c
+++ b/libc/sysdeps/linux/common/clock_adjtime.c
@@ -10,6 +10,10 @@
#include <sys/syscall.h>
#include <sys/timex.h>
-#ifdef __NR_clock_adjtime
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_adjtime64)
+_syscall2_64(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx)
+#elif defined(__NR_clock_adjtime)
_syscall2(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx)
+#else
+#error "clock_adjtime syscall is not defined!"
#endif
diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c
index 532047ede..d4b989958 100644
--- a/libc/sysdeps/linux/common/clock_getres.c
+++ b/libc/sysdeps/linux/common/clock_getres.c
@@ -10,7 +10,10 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_clock_getres
+
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res)
+#elif defined(__NR_clock_getres)
_syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res)
#else
# include <unistd.h>
diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c
index 95d398239..a595bd691 100644
--- a/libc/sysdeps/linux/common/clock_gettime.c
+++ b/libc/sysdeps/linux/common/clock_gettime.c
@@ -11,7 +11,9 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_clock_gettime
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
+_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp)
+#elif defined(__NR_clock_gettime)
_syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c
index 636f18417..89550af5a 100644
--- a/libc/sysdeps/linux/common/clock_settime.c
+++ b/libc/sysdeps/linux/common/clock_settime.c
@@ -10,7 +10,10 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_clock_settime
+
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64)
+_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
+#elif defined(__NR_clock_settime)
_syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c
index 13611e9d0..8064722d2 100644
--- a/libc/sysdeps/linux/common/fstatat.c
+++ b/libc/sysdeps/linux/common/fstatat.c
@@ -62,6 +62,14 @@ int fstatat(int fd, const char *file, struct stat *buf, int flag)
.st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec,
.st_ctim.tv_sec = tmp.stx_ctime.tv_sec,
.st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec,
+#if defined(__UCLIBC_USE_TIME64__)
+ .__st_atim32.tv_sec = stx.stx_atime.tv_sec,
+ .__st_atim32.tv_nsec = stx.stx_atime.tv_nsec,
+ .__st_mtim32.tv_sec = stx.stx_mtime.tv_sec,
+ .__st_mtim32.tv_nsec = stx.stx_mtime.tv_nsec,
+ .__st_ctim32.tv_sec = stx.stx_ctime.tv_sec,
+ .__st_ctim32.tv_nsec = stx.stx_ctime.tv_nsec,
+#endif
};
return ret;
diff --git a/libc/sysdeps/linux/common/gettimeofday.c b/libc/sysdeps/linux/common/gettimeofday.c
index d9cf3bb84..ed18b2be5 100755
--- a/libc/sysdeps/linux/common/gettimeofday.c
+++ b/libc/sysdeps/linux/common/gettimeofday.c
@@ -8,12 +8,12 @@
#include <sys/syscall.h>
#include <sys/time.h>
+#include <time.h>
#ifdef __VDSO_SUPPORT__
#include "ldso.h"
#endif
-
#ifdef __VDSO_SUPPORT__
typedef int (*gettimeofday_func)(struct timeval * tv, __timezone_ptr_t tz);
#endif
@@ -29,7 +29,14 @@ int gettimeofday(struct timeval * tv, __timezone_ptr_t tz) {
_syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
}
#else
- _syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
+ if (!tv)
+ return 0;
+
+ struct timespec __ts;
+ int __ret = clock_gettime(CLOCK_REALTIME, &__ts);
+ tv->tv_sec = __ts.tv_sec;
+ tv->tv_usec = (suseconds_t)__ts.tv_nsec / 1000;
+ return __ret;
#endif
}
diff --git a/libc/sysdeps/linux/common/nanosleep.c b/libc/sysdeps/linux/common/nanosleep.c
index 4463e108a..2b59fefef 100644
--- a/libc/sysdeps/linux/common/nanosleep.c
+++ b/libc/sysdeps/linux/common/nanosleep.c
@@ -10,11 +10,21 @@
#include <time.h>
#include <cancel.h>
-#define __NR___nanosleep_nocancel __NR_nanosleep
-static _syscall2(int, __NC(nanosleep), const struct timespec *, req,
- struct timespec *, rem);
+
+int _NC(nanosleep)(const struct timespec *req, struct timespec *rem)
+{
+ int __ret = clock_nanosleep(CLOCK_REALTIME, 0, req, rem);
+
+ if (__ret != 0) {
+ __set_errno(__ret);
+ return -1;
+ }
+
+ return __ret;
+};
CANCELLABLE_SYSCALL(int, nanosleep,
(const struct timespec *req, struct timespec *rem),
(req, rem))
+
lt_libc_hidden(nanosleep)
diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c
index 781f1ff1c..cb36149c5 100644
--- a/libc/sysdeps/linux/common/ppoll.c
+++ b/libc/sysdeps/linux/common/ppoll.c
@@ -18,7 +18,7 @@
#include <sys/syscall.h>
-#if defined __NR_ppoll && defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU
+#if (defined __NR_ppoll || defined(__NR_ppoll_time64)) && defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU
#define __need_NULL
#include <stddef.h>
@@ -37,11 +37,14 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
tval = *timeout;
timeout = &tval;
}
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
+ return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
+#else
return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
+#endif
}
CANCELLABLE_SYSCALL(int, ppoll, (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
const sigset_t *sigmask),
(fds, nfds, timeout, sigmask))
-
#endif
diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index bf2c08375..23bdab5cf 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -56,8 +56,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
sigmask = (void *)&data;
}
-
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
+ return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
+#else
return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
+#endif
#else
struct timeval tval;
int retval;
@@ -88,6 +91,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
return retval;
#endif
}
+
CANCELLABLE_SYSCALL(int, pselect, (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask),
(nfds, readfds, writefds, exceptfds, timeout, sigmask))
diff --git a/libc/sysdeps/linux/common/sched_rr_get_interval.c b/libc/sysdeps/linux/common/sched_rr_get_interval.c
index 7a7de2bc5..c9be134cb 100644
--- a/libc/sysdeps/linux/common/sched_rr_get_interval.c
+++ b/libc/sysdeps/linux/common/sched_rr_get_interval.c
@@ -10,7 +10,12 @@
#include <sys/types.h>
#include <sys/syscall.h>
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_sched_rr_get_interval_time64)
+#define __NR___syscall_sched_rr_get_interval __NR_sched_rr_get_interval_time64
+#else
#define __NR___syscall_sched_rr_get_interval __NR_sched_rr_get_interval
+#endif
+
static __inline__ _syscall2(int, __syscall_sched_rr_get_interval,
__kernel_pid_t, pid, struct timespec *, tp)
diff --git a/libc/sysdeps/linux/common/setitimer.c b/libc/sysdeps/linux/common/setitimer.c
index 2febabbc8..eab541329 100644
--- a/libc/sysdeps/linux/common/setitimer.c
+++ b/libc/sysdeps/linux/common/setitimer.c
@@ -10,6 +10,38 @@
#include <sys/time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+
+struct itimerval32_struct {
+ __S32_TYPE __interval_sec;
+ __S32_TYPE __interval_usec;
+ __S32_TYPE __value_sec;
+ __S32_TYPE __value_usec;
+};
+
+int setitimer(__itimer_which_t which, const struct itimerval *restrict new, struct itimerval *restrict old)
+{
+ struct itimerval32_struct __itv32 = {
+ .__interval_sec = new->it_interval.tv_sec,
+ .__interval_usec = new->it_interval.tv_usec,
+ .__value_sec = new->it_value.tv_sec,
+ .__value_usec = new->it_value.tv_usec
+ };
+ struct itimerval32_struct __itv32_old;
+
+ int __ret = INLINE_SYSCALL(setitimer, 3, which, &__itv32, &__itv32_old);
+ if (__ret == 0 && old) {
+ old->it_interval.tv_sec = __itv32_old.__interval_sec;
+ old->it_interval.tv_usec = __itv32_old.__interval_usec;
+ old->it_value.tv_sec = __itv32_old.__value_sec;
+ old->it_value.tv_usec = __itv32_old.__value_usec;
+ }
+
+ return __ret;
+}
+#else
_syscall3(int, setitimer, __itimer_which_t, which,
const struct itimerval *, new, struct itimerval *, old)
+
+#endif
libc_hidden_def(setitimer)
diff --git a/libc/sysdeps/linux/common/settimeofday.c b/libc/sysdeps/linux/common/settimeofday.c
index 14a261794..75d18ffc2 100644
--- a/libc/sysdeps/linux/common/settimeofday.c
+++ b/libc/sysdeps/linux/common/settimeofday.c
@@ -10,9 +10,21 @@
#ifdef __USE_BSD
# include <sys/time.h>
-# ifdef __NR_settimeofday
-_syscall2(int, settimeofday, const struct timeval *, tv,
- const struct timezone *, tz)
+# include <time.h>
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+ if (!tv)
+ return 0;
+
+ struct timespec __ts = {
+ .tv_sec = tv->tv_sec,
+ .tv_nsec = tv->tv_usec * 1000
+ };
+
+ return clock_settime(CLOCK_REALTIME, &__ts);
+}
+
# elif defined __USE_SVID && defined __NR_stime
# define __need_NULL
# include <stddef.h>
@@ -36,7 +48,6 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
return stime(&when);
}
# endif
-# if defined __NR_settimeofday || (defined __USE_SVID && defined __NR_stime)
+# if defined __NR_settimeofday || defined(__UCLIBC_USE_TIME64__) || (defined __USE_SVID && defined __NR_stime)
libc_hidden_def(settimeofday)
# endif
-#endif
diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c
index f4854ac90..0f19b44ed 100644
--- a/libc/sysdeps/linux/common/timerfd.c
+++ b/libc/sysdeps/linux/common/timerfd.c
@@ -19,13 +19,21 @@ _syscall2(int, timerfd_create, int, clockid, int, flags)
/*
* timerfd_settime()
*/
-#ifdef __NR_timerfd_settime
-_syscall4(int,timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr)
+#if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64)
+_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr)
+#else
+_syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr)
+#endif
#endif
/*
* timerfd_gettime()
*/
-#ifdef __NR_timerfd_gettime
+#if defined(__NR_timerfd_gettime) || defined(__NR_timerfd_gettime64)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_gettime64)
+_syscall2_64(int, timerfd_gettime, int, ufd, struct itimerspec *, otmr)
+#else
_syscall2(int, timerfd_gettime, int, ufd, struct itimerspec *, otmr)
#endif
+#endif
diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c
index 2cfb8247d..6a78ebb4f 100644
--- a/libc/sysdeps/linux/common/utimensat.c
+++ b/libc/sysdeps/linux/common/utimensat.c
@@ -9,8 +9,12 @@
#include <sys/syscall.h>
#include <sys/stat.h>
-#ifdef __NR_utimensat
+#if defined(__NR_utimensat) || defined(__NR_utimensat_time64)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64)
+_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
+#else
_syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
+#endif
libc_hidden_def(utimensat)
#else
/* should add emulation with utimens() and /proc/self/fd/ ... */
diff --git a/libc/sysdeps/linux/common/wait4.c b/libc/sysdeps/linux/common/wait4.c
index 19f02ae22..cd042d5e7 100644
--- a/libc/sysdeps/linux/common/wait4.c
+++ b/libc/sysdeps/linux/common/wait4.c
@@ -8,6 +8,7 @@
#include <sys/syscall.h>
#include <sys/wait.h>
+#include <sys/resource.h>
# define __NR___syscall_wait4 __NR_wait4
static __always_inline _syscall4(int, __syscall_wait4, __kernel_pid_t, pid,
@@ -15,7 +16,21 @@ static __always_inline _syscall4(int, __syscall_wait4, __kernel_pid_t, pid,
pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage)
{
+#if defined(__UCLIBC_USE_TIME64__)
+ char *arg_rusage = rusage ? (char *)&rusage->ru_maxrss - 4 * sizeof(__S32_TYPE) : 0;
+ int __ret = __syscall_wait4(pid, status, opts, (struct rusage *)arg_rusage);
+ if (__ret > 0 && rusage) {
+ __S32_TYPE __rusage[4];
+ memcpy(__rusage, arg_rusage, 4 * sizeof(__S32_TYPE));
+ struct timeval tv_utime = {.tv_sec = __rusage[0], .tv_usec = __rusage[1]};
+ struct timeval tv_stime = {.tv_sec = __rusage[2], .tv_usec = __rusage[2]};
+ rusage->ru_utime = tv_utime;
+ rusage->ru_stime = tv_stime;
+ }
+ return __ret;
+#else
return __syscall_wait4(pid, status, opts, rusage);
+#endif
}
#ifdef __USE_BSD
strong_alias(__wait4_nocancel,wait4)
diff --git a/libc/sysdeps/linux/common/xstatconv.c b/libc/sysdeps/linux/common/xstatconv.c
index d50fbf9c3..4b0a7424e 100644
--- a/libc/sysdeps/linux/common/xstatconv.c
+++ b/libc/sysdeps/linux/common/xstatconv.c
@@ -37,12 +37,21 @@ void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf)
buf->st_size = kbuf->st_size;
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
+#if defined(__UCLIBC_USE_TIME64__)
+ buf->st_atim.tv_sec = kbuf->__st_atim32.tv_sec;
+ buf->st_atim.tv_nsec = kbuf->__st_atim32.tv_nsec;
+ buf->st_mtim.tv_sec = kbuf->__st_mtim32.tv_sec;
+ buf->st_mtim.tv_nsec = kbuf->__st_mtim32.tv_nsec;
+ buf->st_ctim.tv_sec = kbuf->__st_ctim32.tv_sec;
+ buf->st_ctim.tv_nsec = kbuf->__st_ctim32.tv_nsec;
+#else
buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
+#endif
}
void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf)
@@ -59,12 +68,21 @@ void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf)
buf->st_size = kbuf->st_size;
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
+#if defined(__UCLIBC_USE_TIME64__)
+ buf->st_atim.tv_sec = kbuf->__st_atim32.tv_sec;
+ buf->st_atim.tv_nsec = kbuf->__st_atim32.tv_nsec;
+ buf->st_mtim.tv_sec = kbuf->__st_mtim32.tv_sec;
+ buf->st_mtim.tv_nsec = kbuf->__st_mtim32.tv_nsec;
+ buf->st_ctim.tv_sec = kbuf->__st_ctim32.tv_sec;
+ buf->st_ctim.tv_nsec = kbuf->__st_ctim32.tv_nsec;
+#else
buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
+#endif
}
void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf)
@@ -84,10 +102,19 @@ void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf)
buf->st_size = kbuf->st_size;
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
+#if defined(__UCLIBC_USE_TIME64__)
+ buf->st_atim.tv_sec = kbuf->__st_atim32.tv_sec;
+ buf->st_atim.tv_nsec = kbuf->__st_atim32.tv_nsec;
+ buf->st_mtim.tv_sec = kbuf->__st_mtim32.tv_sec;
+ buf->st_mtim.tv_nsec = kbuf->__st_mtim32.tv_nsec;
+ buf->st_ctim.tv_sec = kbuf->__st_ctim32.tv_sec;
+ buf->st_ctim.tv_nsec = kbuf->__st_ctim32.tv_nsec;
+#else
buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
+#endif
}
diff --git a/libpthread/linuxthreads/condvar.c b/libpthread/linuxthreads/condvar.c
index 6ac1622da..949991ad7 100644
--- a/libpthread/linuxthreads/condvar.c
+++ b/libpthread/linuxthreads/condvar.c
@@ -328,7 +328,11 @@ int pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
INTERNAL_SYSCALL_DECL (err);
int val;
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+ val = INTERNAL_SYSCALL (clock_getres_time64, err, 2, CLOCK_MONOTONIC, &ts);
+#else
val = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
+#endif
avail = INTERNAL_SYSCALL_ERROR_P (val, err) ? -1 : 1;
}
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index ddc552f2e..a6c0ec6af 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -195,8 +195,14 @@ __pthread_initialize_minimal_internal (void)
doing the test once this early is beneficial. */
{
int word = 0;
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ word = INTERNAL_SYSCALL (futex_time64, err, 3, &word,
+ FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
+#else
word = INTERNAL_SYSCALL (futex, err, 3, &word,
FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
+#endif
+
if (!INTERNAL_SYSCALL_ERROR_P (word, err))
THREAD_SETMEM (pd, header.private_futex, FUTEX_PRIVATE_FLAG);
}
@@ -215,9 +221,16 @@ __pthread_initialize_minimal_internal (void)
is irrelevant. Given that passing six parameters is difficult
on some architectures we just pass whatever random value the
calling convention calls for to the kernel. It causes no harm. */
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ word = INTERNAL_SYSCALL (futex_time64, err, 5, &word,
+ FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME
+ | FUTEX_PRIVATE_FLAG, 1, NULL, 0);
+#else
word = INTERNAL_SYSCALL (futex, err, 5, &word,
FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME
| FUTEX_PRIVATE_FLAG, 1, NULL, 0);
+#endif
+
assert (INTERNAL_SYSCALL_ERROR_P (word, err));
if (INTERNAL_SYSCALL_ERRNO (word, err) != ENOSYS)
__set_futex_clock_realtime ();
diff --git a/libpthread/nptl/pthread_condattr_setclock.c b/libpthread/nptl/pthread_condattr_setclock.c
index b2f4aaf29..e7f3539d6 100644
--- a/libpthread/nptl/pthread_condattr_setclock.c
+++ b/libpthread/nptl/pthread_condattr_setclock.c
@@ -35,7 +35,7 @@ pthread_condattr_setclock (
if (clock_id == CLOCK_MONOTONIC)
{
#ifndef __ASSUME_POSIX_TIMERS
-# ifdef __NR_clock_getres
+# if defined(__NR_clock_getres) || defined(__NR_clock_getres_time64)
/* Check whether the clock is available. */
static int avail;
@@ -45,7 +45,11 @@ pthread_condattr_setclock (
INTERNAL_SYSCALL_DECL (err);
int val;
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+ val = INTERNAL_SYSCALL (clock_getres_time64, err, 2, CLOCK_MONOTONIC, &ts);
+#else
val = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
+#endif
avail = INTERNAL_SYSCALL_ERROR_P (val, err) ? -1 : 1;
}
diff --git a/libpthread/nptl/pthread_mutex_init.c b/libpthread/nptl/pthread_mutex_init.c
index bf4c4d151..ba5c916eb 100644
--- a/libpthread/nptl/pthread_mutex_init.c
+++ b/libpthread/nptl/pthread_mutex_init.c
@@ -62,8 +62,13 @@ __pthread_mutex_init (
{
int lock = 0;
INTERNAL_SYSCALL_DECL (err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ int ret = INTERNAL_SYSCALL (futex_time64, err, 4, &lock, FUTEX_UNLOCK_PI,
+ 0, 0);
+#else
int ret = INTERNAL_SYSCALL (futex, err, 4, &lock, FUTEX_UNLOCK_PI,
0, 0);
+#endif
assert (INTERNAL_SYSCALL_ERROR_P (ret, err));
tpi_supported = INTERNAL_SYSCALL_ERRNO (ret, err) == ENOSYS ? -1 : 1;
}
diff --git a/libpthread/nptl/pthread_mutex_lock.c b/libpthread/nptl/pthread_mutex_lock.c
index 8353e8cd3..6e98a9760 100644
--- a/libpthread/nptl/pthread_mutex_lock.c
+++ b/libpthread/nptl/pthread_mutex_lock.c
@@ -300,9 +300,15 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
: PTHREAD_MUTEX_PSHARED (mutex));
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_LOCK_PI,
+ private), 1, 0);
+#else
int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
private), 1, 0);
+#endif
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
&& (INTERNAL_SYSCALL_ERRNO (e, __err) == ESRCH
@@ -357,10 +363,17 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
mutex->__data.__count = 0;
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_UNLOCK_PI,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+ 0, 0);
+#else
INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_UNLOCK_PI,
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
0, 0);
+#endif
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c
index f56f6c55e..25f9ec3b2 100644
--- a/libpthread/nptl/pthread_mutex_timedlock.c
+++ b/libpthread/nptl/pthread_mutex_timedlock.c
@@ -264,10 +264,17 @@ pthread_mutex_timedlock (
: PTHREAD_MUTEX_PSHARED (mutex));
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_LOCK_PI,
+ private), 1,
+ abstime);
+#else
int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
private), 1,
abstime);
+#endif
if (INTERNAL_SYSCALL_ERROR_P (e, __err))
{
if (INTERNAL_SYSCALL_ERRNO (e, __err) == ETIMEDOUT)
@@ -289,8 +296,13 @@ pthread_mutex_timedlock (
struct timespec reltime;
struct timespec now;
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
+ INTERNAL_SYSCALL (clock_gettime64, __err, 2, CLOCK_REALTIME,
+ &now);
+#else
INTERNAL_SYSCALL (clock_gettime, __err, 2, CLOCK_REALTIME,
&now);
+#endif
reltime.tv_sec = abstime->tv_sec - now.tv_sec;
reltime.tv_nsec = abstime->tv_nsec - now.tv_nsec;
if (reltime.tv_nsec < 0)
@@ -340,10 +352,17 @@ pthread_mutex_timedlock (
mutex->__data.__count = 0;
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_UNLOCK_PI,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+ 0, 0);
+#else
INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_UNLOCK_PI,
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
0, 0);
+#endif
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
diff --git a/libpthread/nptl/pthread_mutex_trylock.c b/libpthread/nptl/pthread_mutex_trylock.c
index e0d54bda7..ca02109ee 100644
--- a/libpthread/nptl/pthread_mutex_trylock.c
+++ b/libpthread/nptl/pthread_mutex_trylock.c
@@ -234,9 +234,15 @@ __pthread_mutex_trylock (
? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
: PTHREAD_MUTEX_PSHARED (mutex));
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_TRYLOCK_PI,
+ private), 0, 0);
+#else
int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_TRYLOCK_PI,
private), 0, 0);
+#endif
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
@@ -276,10 +282,17 @@ __pthread_mutex_trylock (
mutex->__data.__count = 0;
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_UNLOCK_PI,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+ 0, 0);
+#else
INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
__lll_private_flag (FUTEX_UNLOCK_PI,
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
0, 0);
+#endif
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
diff --git a/libpthread/nptl/pthread_mutex_unlock.c b/libpthread/nptl/pthread_mutex_unlock.c
index 1123e3c42..6f3ed8c44 100644
--- a/libpthread/nptl/pthread_mutex_unlock.c
+++ b/libpthread/nptl/pthread_mutex_unlock.c
@@ -222,8 +222,13 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
: PTHREAD_MUTEX_PSHARED (mutex));
INTERNAL_SYSCALL_DECL (__err);
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+ INTERNAL_SYSCALL (futex_time64, __err, 2, &mutex->__data.__lock,
+ __lll_private_flag (FUTEX_UNLOCK_PI, private));
+#else
INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
__lll_private_flag (FUTEX_UNLOCK_PI, private));
+#endif
}
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index f06b69e2f..49aab0293 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -102,10 +102,18 @@ __pthread_cond_timedwait (
# ifndef __ASSUME_POSIX_TIMERS
int ret =
# endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
+ INTERNAL_SYSCALL (clock_gettime64, err, 2,
+ (cond->__data.__nwaiters
+ & ((1 << COND_NWAITERS_SHIFT) - 1)),
+ &rt);
+#else
INTERNAL_SYSCALL (clock_gettime, err, 2,
(cond->__data.__nwaiters
& ((1 << COND_NWAITERS_SHIFT) - 1)),
&rt);
+#endif
+
# ifndef __ASSUME_POSIX_TIMERS
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
{
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
index b5b0afdf8..e72fe5234 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
@@ -71,10 +71,33 @@
# endif
#endif
-
#define lll_futex_wait(futexp, val, private) \
lll_futex_timed_wait(futexp, val, NULL, private)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ __ret; \
+ })
+
+#else
+
#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
@@ -95,6 +118,8 @@
__ret; \
})
+#endif
+
#define lll_robust_dead(futexv, private) \
do \
{ \
@@ -105,6 +130,35 @@
while (0)
/* Returns non-zero if error happened, zero if success. */
+
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+#else
+
+
#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
@@ -128,6 +182,8 @@
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
+#endif
+
#define lll_trylock(lock) \
atomic_compare_and_exchange_val_acq(&(lock), 1, 0)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.c b/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.c
index 73fae44bc..9c7230934 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.c
@@ -8,11 +8,17 @@
/* Pause execution for a number of nanoseconds. */
int
-nanosleep (const struct timespec *requested_time,
+_NC(nanosleep) (const struct timespec *requested_time,
struct timespec *remaining)
{
- return _syscall2(int, __NC(nanosleep), const struct timespec*,
- requested_time, struct timespec* remaining)
+ int __ret = clock_nanosleep(CLOCK_REALTIME, 0, requested_time, remaining);
+
+ if (__ret != 0) {
+ __set_errno(__ret);
+ return -1;
+ }
+
+ return __ret;
}
CANCELLABLE_SYSCALL(int, nanosleep, (const struct timespec *requested_time,
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c
index 93e4e6070..cd8d2f84f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c
@@ -140,8 +140,13 @@ timer_create (
INTERNAL_SYSCALL_DECL (err);
struct timespec ts;
int res;
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+ res = INTERNAL_SYSCALL (clock_getres_time64, err, 2,
+ CLOCK_REALTIME, &ts);
+#else
res = INTERNAL_SYSCALL (clock_getres, err, 2,
CLOCK_REALTIME, &ts);
+#endif
__no_posix_timers = (INTERNAL_SYSCALL_ERROR_P (res, err)
? -1 : 1);
}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
index 699874f3f..220df0c37 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
@@ -50,7 +50,11 @@ timer_gettime (
struct timer *kt = (struct timer *) timerid;
/* Delete the kernel timer object. */
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_gettime64)
+ int res = INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value);
+# else
int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value);
+# endif
# ifndef __ASSUME_POSIX_TIMERS
if (res != -1 || errno != ENOSYS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
index 81a0fa568..80d242f21 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
@@ -54,8 +54,13 @@ timer_settime (
struct timer *kt = (struct timer *) timerid;
/* Delete the kernel timer object. */
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
+ int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
+ value, ovalue);
+# else
int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
value, ovalue);
+# endif
# ifndef __ASSUME_POSIX_TIMERS
if (res != -1 || errno != ENOSYS)
diff --git a/librt/clock_getcpuclockid.c b/librt/clock_getcpuclockid.c
index b6142a78a..a402e56d7 100644
--- a/librt/clock_getcpuclockid.c
+++ b/librt/clock_getcpuclockid.c
@@ -30,7 +30,7 @@
int
clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
{
-#ifdef __NR_clock_getres
+#if defined(__NR_clock_getres) || defined(__NR_clock_getres_time64)
/* The clockid_t value is a simple computation from the PID.
But we do a clock_getres call to validate it. */
@@ -47,7 +47,11 @@ clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
# endif
{
INTERNAL_SYSCALL_DECL (err);
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+ int r = INTERNAL_SYSCALL (clock_getres_time64, err, 2, pidclock, NULL);
+# else
int r = INTERNAL_SYSCALL (clock_getres, err, 2, pidclock, NULL);
+# endif
if (!INTERNAL_SYSCALL_ERROR_P (r, err))
{
*clock_id = pidclock;
@@ -66,12 +70,21 @@ clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
{
# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+ if (pidclock == MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
+ || INTERNAL_SYSCALL_ERROR_P (INTERNAL_SYSCALL
+ (clock_getres_time64, err, 2,
+ MAKE_PROCESS_CPUCLOCK
+ (0, CPUCLOCK_SCHED), NULL),
+ err))
+# else
if (pidclock == MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
|| INTERNAL_SYSCALL_ERROR_P (INTERNAL_SYSCALL
(clock_getres, err, 2,
MAKE_PROCESS_CPUCLOCK
(0, CPUCLOCK_SCHED), NULL),
err))
+# endif
/* The kernel doesn't support these clocks at all. */
__libc_missing_posix_cpu_timers = 1;
else
diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c
index e65d39d44..b66b60231 100644
--- a/librt/clock_gettime.c
+++ b/librt/clock_gettime.c
@@ -22,10 +22,15 @@
#include <sys/time.h>
#include "kernel-posix-cpu-timers.h"
-
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
+#define SYSCALL_GETTIME \
+ retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
+ break
+#else
#define SYSCALL_GETTIME \
retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \
break
+#endif
/* The REALTIME and MONOTONIC clock are definitely supported in the kernel. */
#define SYSDEP_GETTIME \
diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c
index 85db72fb3..eaae75720 100644
--- a/librt/clock_nanosleep.c
+++ b/librt/clock_nanosleep.c
@@ -37,15 +37,21 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
if (SINGLE_THREAD_P)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
+ r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
+#else
r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem);
+#endif
else
{
#ifdef __NEW_THREADS
int oldstate = LIBC_CANCEL_ASYNC ();
-
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
+ r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
+#else
r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req,
rem);
-
+#endif
LIBC_CANCEL_RESET (oldstate);
#endif
}
diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c
index 9f5efc4fa..db1ae1aa8 100644
--- a/librt/mq_timedreceive.c
+++ b/librt/mq_timedreceive.c
@@ -8,9 +8,15 @@
#include <unistd.h>
#include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64)
+#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64
+#else
#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive
+#endif
+
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout)
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
+
lt_libc_hidden(mq_timedreceive)
diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c
index 7c2e97ee3..6afaf5157 100644
--- a/librt/mq_timedsend.c
+++ b/librt/mq_timedsend.c
@@ -8,9 +8,13 @@
#include <unistd.h>
#include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64)
+#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64
+#else
#define __NR___mq_timedsend_nocancel __NR_mq_timedsend
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
+#endif
+_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
lt_libc_hidden(mq_timedsend)
diff --git a/librt/timer_gettime.c b/librt/timer_gettime.c
index e13f44642..9495c802d 100644
--- a/librt/timer_gettime.c
+++ b/librt/timer_gettime.c
@@ -9,9 +9,13 @@
#include "kernel-posix-timers.h"
-#ifdef __NR_timer_gettime
+#if defined(__NR_timer_gettime) || defined(__NR_timer_gettime64)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_gettime64)
+#define __NR___syscall_timer_gettime __NR_timer_gettime64
+#else
#define __NR___syscall_timer_gettime __NR_timer_gettime
+#endif
static __inline__ _syscall2(int, __syscall_timer_gettime, kernel_timer_t, ktimerid,
void *, value);
diff --git a/librt/timer_settime.c b/librt/timer_settime.c
index 2703fa913..022880297 100644
--- a/librt/timer_settime.c
+++ b/librt/timer_settime.c
@@ -9,9 +9,14 @@
#include "kernel-posix-timers.h"
-#ifdef __NR_timer_settime
+#if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
+#define __NR___syscall_timer_settime __NR_timer_settime64
+#else
#define __NR___syscall_timer_settime __NR_timer_settime
+#endif
+
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid,
int, flags, const void *, value, void *, ovalue);
--
2.43.2
2
1
Hi,
static analysis tools complain that the following code lacks a null-pointer
check:
ldso/ldso/dl-elf.c:
/*
* Add this object into the symbol chain
*/
if (*rpnt
#ifdef __LDSO_STANDALONE_SUPPORT__
/* Do not create a new chain entry for the main executable */
&& (*rpnt)->dyn
#endif
) {
(*rpnt)->next = _dl_malloc(sizeof(struct dyn_elf));
_dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
(*rpnt)->next->prev = (*rpnt);
*rpnt = (*rpnt)->next;
}
#ifndef SHARED
/* When statically linked, the first time we dlopen a DSO
* the *rpnt is NULL, so we need to allocate memory for it,
* and initialize the _dl_symbol_table.
*/
else {
*rpnt = _dl_symbol_tables = _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(*rpnt, 0, sizeof(struct dyn_elf));
}
#endif
(*rpnt)->dyn = tpnt;
^^^^^^^^^^^^^^^^^^^^
There is a check for (*rpnt == NULL) right after the first comment but the
"else" case which performs an allocation does only exist if SHARED is not
defined. Otherwise it may happen (at least in theory) that *rpnt=NULL when
executing
(*rpnt)->dyn = tpnt;
Proposed fix:
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 8210a012e..3ba3144e2 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -900,7 +900,8 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned int rflags,
_dl_memset(*rpnt, 0, sizeof(struct dyn_elf));
}
#endif
- (*rpnt)->dyn = tpnt;
+ if (*rpnt)
+ (*rpnt)->dyn = tpnt;
tpnt->usage_count++;
if (tpnt->rtld_flags & RTLD_NODELETE)
tpnt->usage_count++;
Kind regards
Frank
3
3
While they are not a problem per-se they cause issues with some tooling
(such as clang coverage) and are confusing to the reader.
---
extra/locale/programs/locale.c | 2 +-
ldso/include/dl-string.h | 2 +-
libc/misc/time/time.c | 2 +-
libc/string/strcasestr.c | 2 +-
libc/string/strstr.c | 2 +-
libc/unistd/sysconf.c | 4 ++--
6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/extra/locale/programs/locale.c b/extra/locale/programs/locale.c
index 5d16d1276..4157c4a8e 100644
--- a/extra/locale/programs/locale.c
+++ b/extra/locale/programs/locale.c
@@ -231,7 +231,7 @@ static void find_locale_string(locale_entry * loc_rec, char *loc)
*loc = '\0';
} else {
dotcs = (uint16_t) loc_rec->dot_cs;
- cs = (uint16_t) loc_rec->cs;;
+ cs = (uint16_t) loc_rec->cs;
loc = strncpy(loc, GET_LOCALE_NAME(idx), 5);
if (loc[2] == '_') {
diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
index 6cc76dbf9..4a66161e0 100644
--- a/ldso/include/dl-string.h
+++ b/ldso/include/dl-string.h
@@ -103,7 +103,7 @@ static __always_inline char * _dl_strstr(const char *s1, const char *s2)
do {
if (!*p)
- return (char *) s1;;
+ return (char *) s1;
if (*p == *s) {
++p;
++s;
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
index cd189169a..0f7c6a33f 100644
--- a/libc/misc/time/time.c
+++ b/libc/misc/time/time.c
@@ -1311,7 +1311,7 @@ ISO_LOOP:
j = (i & 128) ? 100: 12;
if (i & 64) {
- field_val /= j;;
+ field_val /= j;
}
if (i & 32) {
field_val %= j;
diff --git a/libc/string/strcasestr.c b/libc/string/strcasestr.c
index 3334086bf..8f57cc0a3 100644
--- a/libc/string/strcasestr.c
+++ b/libc/string/strcasestr.c
@@ -16,7 +16,7 @@ char *strcasestr(const char *s1, const char *s2)
#if 1
do {
if (!*p) {
- return (char *) s1;;
+ return (char *) s1;
}
if ((*p == *s)
|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
diff --git a/libc/string/strstr.c b/libc/string/strstr.c
index 7e2a64e7d..bf56b9c12 100644
--- a/libc/string/strstr.c
+++ b/libc/string/strstr.c
@@ -22,7 +22,7 @@ Wchar *Wstrstr(const Wchar *s1, const Wchar *s2)
do {
if (!*p) {
- return (Wchar *) s1;;
+ return (Wchar *) s1;
}
if (*p == *s) {
++p;
diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c
index 172794e9c..d04705abb 100644
--- a/libc/unistd/sysconf.c
+++ b/libc/unistd/sysconf.c
@@ -46,7 +46,7 @@
long int get_phys_pages(void)
{
struct sysinfo si;
- int ps = getpagesize();;
+ int ps = getpagesize();
sysinfo(&si);
@@ -59,7 +59,7 @@ long int get_phys_pages(void)
long int get_avphys_pages(void)
{
struct sysinfo si;
- int ps = getpagesize();;
+ int ps = getpagesize();
sysinfo(&si);
--
2.43.0
2
1
Clang warns about null-pointer subtractions, which are undefined
behavior per the C standards. Replace the subtractions with
explicit casts to `uintptr_t`.
---
libcrypt/sha256-crypt.c | 12 ++++++------
libcrypt/sha512-crypt.c | 10 +++++-----
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/libcrypt/sha256-crypt.c b/libcrypt/sha256-crypt.c
index 81bbe6ae6..b2ab62e48 100644
--- a/libcrypt/sha256-crypt.c
+++ b/libcrypt/sha256-crypt.c
@@ -104,24 +104,24 @@ __sha256_crypt_r (const char *key,
salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
key_len = strlen (key);
- if ((key - (char *) 0) % __alignof__ (uint32_t) != 0)
+ if ((uintptr_t)key % __alignof__ (uint32_t) != 0)
{
char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t));
key = copied_key =
memcpy (tmp + __alignof__ (uint32_t)
- - (tmp - (char *) 0) % __alignof__ (uint32_t),
+ - (uintptr_t)tmp % __alignof__ (uint32_t),
key, key_len);
- assert ((key - (char *) 0) % __alignof__ (uint32_t) == 0);
+ assert ((uintptr_t)key % __alignof__ (uint32_t) == 0);
}
- if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0)
+ if ((uintptr_t)salt % __alignof__ (uint32_t) != 0)
{
char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
salt = copied_salt =
memcpy (tmp + __alignof__ (uint32_t)
- - (tmp - (char *) 0) % __alignof__ (uint32_t),
+ - (uintptr_t)tmp % __alignof__ (uint32_t),
salt, salt_len);
- assert ((salt - (char *) 0) % __alignof__ (uint32_t) == 0);
+ assert ((uintptr_t)salt % __alignof__ (uint32_t) == 0);
}
struct sha256_ctx ctx;
diff --git a/libcrypt/sha512-crypt.c b/libcrypt/sha512-crypt.c
index 9d17255aa..b8984d4ab 100644
--- a/libcrypt/sha512-crypt.c
+++ b/libcrypt/sha512-crypt.c
@@ -104,24 +104,24 @@ __sha512_crypt_r (const char *key,
salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
key_len = strlen (key);
- if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
+ if ((uintptr_t)key % __alignof__ (uint64_t) != 0)
{
char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
key = copied_key =
memcpy (tmp + __alignof__ (uint64_t)
- - (tmp - (char *) 0) % __alignof__ (uint64_t),
+ - (uintptr_t)tmp % __alignof__ (uint64_t),
key, key_len);
assert ((key - (char *) 0) % __alignof__ (uint64_t) == 0);
}
- if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0)
+ if ((uintptr_t)salt % __alignof__ (uint64_t) != 0)
{
char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
salt = copied_salt =
memcpy (tmp + __alignof__ (uint64_t)
- - (tmp - (char *) 0) % __alignof__ (uint64_t),
+ - (uintptr_t)tmp % __alignof__ (uint64_t),
salt, salt_len);
- assert ((salt - (char *) 0) % __alignof__ (uint64_t) == 0);
+ assert ((uintptr_t)salt % __alignof__ (uint64_t) == 0);
}
struct sha512_ctx ctx;
--
2.43.0
2
1
---
libc/inet/getnet.c | 3 +++
libc/misc/internals/__uClibc_main.c | 3 ++-
libc/misc/wchar/wchar.c | 1 +
libc/stdlib/malloc-standard/malloc.c | 1 +
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/libc/inet/getnet.c b/libc/inet/getnet.c
index d90fa701e..8743fb9a5 100644
--- a/libc/inet/getnet.c
+++ b/libc/inet/getnet.c
@@ -69,6 +69,7 @@ int getnetent_r(struct netent *result_buf,
char **tok = NULL;
const size_t aliaslen = sizeof(char *) * MAXTOKENS;
int ret = ERANGE;
+ (void)h_errnop;
*result = NULL;
if (buflen < aliaslen
@@ -147,6 +148,7 @@ int getnetbyname_r(const char *name,
{
register char **cp;
int ret, herrnop;
+ (void)h_errnop;
__UCLIBC_MUTEX_LOCK(mylock);
setnetent(net_stayopen);
@@ -181,6 +183,7 @@ int getnetbyaddr_r(uint32_t net, int type,
int *h_errnop)
{
int ret, herrnop;
+ (void)h_errnop;
__UCLIBC_MUTEX_LOCK(mylock);
setnetent(net_stayopen);
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index affa0ce0a..64a9c8214 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -109,7 +109,7 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av);
* in or linker will disregard these weaks.
*/
-static int __pthread_return_0 (pthread_mutex_t *unused) { return 0; }
+static int __pthread_return_0 (pthread_mutex_t *unused) { (void)unused; return 0; }
weak_alias (__pthread_return_0, __pthread_mutex_lock)
weak_alias (__pthread_return_0, __pthread_mutex_trylock)
weak_alias (__pthread_return_0, __pthread_mutex_unlock)
@@ -117,6 +117,7 @@ weak_alias (__pthread_return_0, __pthread_mutex_unlock)
int weak_function
__pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
+ (void)mutex; (void)attr;
return 0;
}
diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c
index 201f30772..2714d47d7 100644
--- a/libc/misc/wchar/wchar.c
+++ b/libc/misc/wchar/wchar.c
@@ -781,6 +781,7 @@ size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
size_t count;
int incr;
char buf[MB_LEN_MAX];
+ (void)ps;
#ifdef __CTYPE_HAS_UTF_8_LOCALES
if (ENCODING == __ctype_encoding_utf8) {
diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
index 1f898eb29..cecea87ec 100644
--- a/libc/stdlib/malloc-standard/malloc.c
+++ b/libc/stdlib/malloc-standard/malloc.c
@@ -176,6 +176,7 @@ void __do_check_remalloced_chunk(mchunkptr p, size_t s)
size_t sz = p->size & ~PREV_INUSE;
#endif
+ (void)s;
__do_check_inuse_chunk(p);
/* Legal size ... */
--
2.43.0
2
1
20 Feb '24
Here is the warning:
ldso/ldso/dl-elf.c: In function '_dl_fixup':
./ldso/include/dl-elf.h:259:37: warning: declaration of 'reloc_addr' shadows a previous local [-Wshadow]
259 | ElfW(Addr) *reloc_addr = 0; \
| ^~~~~~~~~~
./ldso/include/dl-elf.h:290:33: note: in expansion of macro 'DL_DO_RELOCATE_RELR'
290 | DL_DO_RELOCATE_RELR(dyn->loadaddr, relr_start, relr_end); \
| ^~~~~~~~~~~~~~~~~~~
ldso/ldso/dl-elf.c:1032:9: note: in expansion of macro 'DL_RELOCATE_RELR'
1032 | DL_RELOCATE_RELR(tpnt);
| ^~~~~~~~~~~~~~~~
In file included from ldso/ldso/ldso.c:1462:
ldso/ldso/dl-elf.c:1012:20: note: shadowed declaration is here
1012 | ElfW(Addr) reloc_addr
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
ldso/include/dl-elf.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 7d514c0f5..7143b572c 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -256,22 +256,22 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info
#define DL_DO_RELOCATE_RELR(load_addr, relr_start, relr_end) \
do { \
const ElfW(Relr) *relr = 0; \
- ElfW(Addr) *reloc_addr = 0; \
+ ElfW(Addr) *relr_reloc_addr = 0; \
for (relr = relr_start; relr < relr_end; relr++) { \
ElfW(Relr) relr_entry = *relr; \
if (!(relr_entry & 1)) \
{ \
- reloc_addr = (ElfW(Addr) *)DL_RELOC_ADDR(load_addr, relr_entry); \
- *reloc_addr = (ElfW(Addr))DL_RELOC_ADDR(load_addr, reloc_addr); \
- reloc_addr++; \
+ relr_reloc_addr = (ElfW(Addr) *)DL_RELOC_ADDR(load_addr, relr_entry); \
+ *relr_reloc_addr = (ElfW(Addr))DL_RELOC_ADDR(load_addr, relr_reloc_addr); \
+ relr_reloc_addr++; \
} \
else \
{ \
for (long int i = 0; (relr_entry >>= 1) != 0; ++i) { \
if ((relr_entry & 1) != 0) \
- reloc_addr[i] = (ElfW(Addr))DL_RELOC_ADDR(load_addr, reloc_addr[i]); \
+ relr_reloc_addr[i] = (ElfW(Addr))DL_RELOC_ADDR(load_addr, relr_reloc_addr[i]); \
} \
- reloc_addr += CHAR_BIT * sizeof(ElfW(Relr)) - 1; \
+ relr_reloc_addr += CHAR_BIT * sizeof(ElfW(Relr)) - 1; \
} \
} \
} while (0);
--
2.43.2
2
1
Hi,
I stumbled upon the following code in tempname.c:
switch (kind) {
case __GT_NOCREATE:
{
struct stat st;
if (stat (tmpl, &st) < 0) {
if (errno == ENOENT) {
fd = 0;
goto restore_and_ret;
} else
/* Give up now. */
return -1;
} else
fd = 0;
}
case __GT_FILE:
fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | flags,
mode);
break;
I am baffled by the 'else' branch of the check of 'stat (tmpl, &st) <
0'.
If I understand the whole thing correctly, this is an error case,
where
a file with the temporary name already exists. But instead, the whole
execution falls through to the __GT_FILE branch, and actually opens the
file.
If this happens, this file never seems to be closed again (see for
example
the usage in tmpnam_r.c:30:
char * tmpnam_r (char *s)
{
if (s == NULL)
return NULL;
if (__path_search (s, L_tmpnam, NULL, NULL, 0))
return NULL;
if (__gen_tempname (s, __GT_NOCREATE, 0, 0, 0))
return NULL;
return s;
}
I would suppose that instead of falling to the next switch-case, we
should return with a non-zero value (maybe '1' to distinguish it from
the general error case?).
Am I missing something basic?
Cheers,
Sven
--
Sven Linker
Tel.: +49 351 41883243
Kernkonzept GmbH at Dresden, Germany,
HRB 31129, CEO Dr.-Ing. Michael Hohmuth
4
6
During buildroot compilation with latest uClibc
I've encoutered linking error due to multiple definition
of some symbols from DNS code.
The error happens because the same file resolv.c
is included inside many other .c files:
res_comp.c:(.text+0x0): multiple definition of `__GI___dn_expand'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x8a0): first defined here
res_comp.c:(.text+0x0): multiple definition of `__dn_expand'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x8a0): first defined here
res_comp.c:(.text+0x34): multiple definition of `__GI___dn_comp'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xc68): first defined here
res_comp.c:(.text+0x34): multiple definition of `__dn_comp'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xc68): first defined here
ns_name.c:(.text+0x4c): multiple definition of `__GI___ns_name_ntop'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x4c): first defined here
ns_name.c:(.text+0x4c): multiple definition of `__ns_name_ntop'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x4c): first defined here
ns_name.c:(.text+0x1f8): multiple definition of `__GI___ns_name_pton'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x1f8): first defined here
ns_name.c:(.text+0x1f8): multiple definition of `__ns_name_pton'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x1f8): first defined here
ns_name.c:(.text+0x624): multiple definition of `__hnbad'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x624): first defined here
ns_name.c:(.text+0x718): multiple definition of `__GI___ns_name_unpack'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x718): first defined here
ns_name.c:(.text+0x718): multiple definition of `__ns_name_unpack'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x718): first defined here
ns_name.c:(.text+0x84c): multiple definition of `__GI___ns_name_uncompress'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x84c): first defined here
ns_name.c:(.text+0x84c): multiple definition of `__ns_name_uncompress'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x84c): first defined here
ns_name.c:(.text+0x8a0): multiple definition of `__GI___ns_name_pack'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x8d4): first defined here
ns_name.c:(.text+0x8a0): multiple definition of `__ns_name_pack'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0x8d4): first defined here
ns_name.c:(.text+0xbe4): multiple definition of `__GI___ns_name_compress'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xc18): first defined here
ns_name.c:(.text+0xbe4): multiple definition of `__ns_name_compress'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xc18): first defined here
ns_name.c:(.text+0xc34): multiple definition of `__GI___ns_name_skip'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xcdc): first defined here
ns_name.c:(.text+0xc34): multiple definition of `__ns_name_skip'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xcdc): first defined here
ns_name.c:(.text+0xcd4): multiple definition of `__GI___dn_skipname'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xd7c): first defined here
ns_name.c:(.text+0xcd4): multiple definition of `__dn_skipname'; libc/libc_so.a(encodeq.os):encodeq.c:(.text+0xd7c): first defined here
My previous commit that fixes build error of DNS code is okay,
but there are some 'bottlenecks' in uClibc-ng code, so if
we don't want to completely rewrite resolv.c we need to make some
symbols weak to prevent linking errors.
---
libc/inet/resolv.c | 42 +++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 37842021c..d7a659a8c 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -2809,7 +2809,7 @@ libc_hidden_def(gethostbyaddr)
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
* Return size of compressed name or -1 if there was an error.
*/
-int dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+int weak_function dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
char *dst, int dstsiz)
{
int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
@@ -2818,14 +2818,14 @@ int dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
dst[0] = '\0';
return n;
}
-libc_hidden_def(dn_expand)
+libc_hidden_weak(dn_expand)
/*
* Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
* Return the size of the compressed name or -1.
* 'length' is the size of the array pointed to by 'comp_dn'.
*/
-int
+int weak_function
dn_comp(const char *src, u_char *dst, int dstsiz,
u_char **dnptrs, u_char **lastdnptr)
{
@@ -2833,7 +2833,7 @@ dn_comp(const char *src, u_char *dst, int dstsiz,
(const u_char **) dnptrs,
(const u_char **) lastdnptr);
}
-libc_hidden_def(dn_comp)
+libc_hidden_weak(dn_comp)
#endif /* L_res_comp */
@@ -2873,7 +2873,7 @@ static int special(int ch)
* note:
* Root domain returns as "." not "".
*/
-int ns_name_uncompress(const u_char *msg, const u_char *eom,
+int weak_function ns_name_uncompress(const u_char *msg, const u_char *eom,
const u_char *src, char *dst, size_t dstsiz)
{
u_char tmp[NS_MAXCDNAME];
@@ -2886,7 +2886,7 @@ int ns_name_uncompress(const u_char *msg, const u_char *eom,
return -1;
return n;
}
-libc_hidden_def(ns_name_uncompress)
+libc_hidden_weak(ns_name_uncompress)
/*
* ns_name_ntop(src, dst, dstsiz)
@@ -2897,7 +2897,7 @@ libc_hidden_def(ns_name_uncompress)
* The root is returned as "."
* All other domains are returned in non absolute form
*/
-int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
+int weak_function ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
{
const u_char *cp;
char *dn, *eom;
@@ -2967,7 +2967,7 @@ int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
*dn++ = '\0';
return (dn - dst);
}
-libc_hidden_def(ns_name_ntop)
+libc_hidden_weak(ns_name_ntop)
static int encode_bitstring(const char **bp, const char *end,
unsigned char **labelp,
@@ -3081,7 +3081,7 @@ static int encode_bitstring(const char **bp, const char *end,
return 0;
}
-int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
+int weak_function ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
{
static const char digits[] = "0123456789";
u_char *label, *bp, *eom;
@@ -3202,7 +3202,7 @@ int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
-libc_hidden_def(ns_name_pton)
+libc_hidden_weak(ns_name_pton)
/*
* __hnbad(dotted)
@@ -3218,7 +3218,7 @@ libc_hidden_def(ns_name_pton)
* return:
* 0 if the name is ok
*/
-int __hnbad(const char *dotted)
+int weak_function __hnbad(const char *dotted)
{
unsigned char c, n, *cp;
unsigned char buf[NS_MAXCDNAME];
@@ -3255,7 +3255,7 @@ int __hnbad(const char *dotted)
* return:
* -1 if it fails, or consumed octets if it succeeds.
*/
-int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+int weak_function ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
u_char *dst, size_t dstsiz)
{
const u_char *srcp, *dstlim;
@@ -3322,7 +3322,7 @@ int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
len = srcp - src;
return len;
}
-libc_hidden_def(ns_name_unpack)
+libc_hidden_weak(ns_name_unpack)
static int labellen(const unsigned char *lp)
{
@@ -3416,7 +3416,7 @@ next:
return -1;
}
-int ns_name_pack(const unsigned char *src,
+int weak_function ns_name_pack(const unsigned char *src,
unsigned char *dst, int dstsiz,
const unsigned char **dnptrs,
const unsigned char **lastdnptr)
@@ -3525,9 +3525,9 @@ cleanup:
return dstp - dst;
}
-libc_hidden_def(ns_name_pack)
+libc_hidden_weak(ns_name_pack)
-int ns_name_compress(const char *src,
+int weak_function ns_name_compress(const char *src,
unsigned char *dst, size_t dstsiz,
const unsigned char **dnptrs,
const unsigned char **lastdnptr)
@@ -3539,9 +3539,9 @@ int ns_name_compress(const char *src,
return ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr);
}
-libc_hidden_def(ns_name_compress)
+libc_hidden_weak(ns_name_compress)
-int ns_name_skip(const unsigned char **ptrptr,
+int weak_function ns_name_skip(const unsigned char **ptrptr,
const unsigned char *eom)
{
const unsigned char *cp;
@@ -3583,9 +3583,9 @@ int ns_name_skip(const unsigned char **ptrptr,
return 0;
}
-libc_hidden_def(ns_name_skip)
+libc_hidden_weak(ns_name_skip)
-int dn_skipname(const unsigned char *ptr, const unsigned char *eom)
+int weak_function dn_skipname(const unsigned char *ptr, const unsigned char *eom)
{
const unsigned char *saveptr = ptr;
@@ -3594,7 +3594,7 @@ int dn_skipname(const unsigned char *ptr, const unsigned char *eom)
return ptr - saveptr;
}
-libc_hidden_def(dn_skipname)
+libc_hidden_weak(dn_skipname)
#endif /* L_ns_name */
--
2.43.2
3
2