Browse Source

Introduce time64 support.

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@gmail.com>
Dmitry Chestnykh 2 months ago
parent
commit
8ea0140d5f
47 changed files with 519 additions and 47 deletions
  1. 9 0
      extra/Configs/Config.in
  2. 3 1
      libc/inet/socketcalls.c
  3. 9 2
      libc/misc/sysvipc/sem.c
  4. 8 1
      libc/misc/time/time.c
  5. 23 1
      libc/sysdeps/linux/arm/bits/kernel_stat.h
  6. 10 0
      libc/sysdeps/linux/common/__rt_sigtimedwait.c
  7. 1 1
      libc/sysdeps/linux/common/alarm.c
  8. 13 8
      libc/sysdeps/linux/common/bits/sem.h
  9. 49 0
      libc/sysdeps/linux/common/bits/syscalls-common.h
  10. 12 0
      libc/sysdeps/linux/common/bits/typesizes.h
  11. 5 1
      libc/sysdeps/linux/common/clock_adjtime.c
  12. 4 1
      libc/sysdeps/linux/common/clock_getres.c
  13. 3 1
      libc/sysdeps/linux/common/clock_gettime.c
  14. 4 1
      libc/sysdeps/linux/common/clock_settime.c
  15. 8 0
      libc/sysdeps/linux/common/fstatat.c
  16. 9 2
      libc/sysdeps/linux/common/gettimeofday.c
  17. 13 3
      libc/sysdeps/linux/common/nanosleep.c
  18. 5 2
      libc/sysdeps/linux/common/ppoll.c
  19. 5 1
      libc/sysdeps/linux/common/pselect.c
  20. 5 0
      libc/sysdeps/linux/common/sched_rr_get_interval.c
  21. 32 0
      libc/sysdeps/linux/common/setitimer.c
  22. 16 5
      libc/sysdeps/linux/common/settimeofday.c
  23. 11 3
      libc/sysdeps/linux/common/timerfd.c
  24. 5 1
      libc/sysdeps/linux/common/utimensat.c
  25. 15 0
      libc/sysdeps/linux/common/wait4.c
  26. 27 0
      libc/sysdeps/linux/common/xstatconv.c
  27. 4 0
      libpthread/linuxthreads/condvar.c
  28. 13 0
      libpthread/nptl/init.c
  29. 5 1
      libpthread/nptl/pthread_condattr_setclock.c
  30. 5 0
      libpthread/nptl/pthread_mutex_init.c
  31. 13 0
      libpthread/nptl/pthread_mutex_lock.c
  32. 19 0
      libpthread/nptl/pthread_mutex_timedlock.c
  33. 13 0
      libpthread/nptl/pthread_mutex_trylock.c
  34. 5 0
      libpthread/nptl/pthread_mutex_unlock.c
  35. 8 0
      libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
  36. 57 1
      libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
  37. 9 3
      libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.c
  38. 5 0
      libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c
  39. 4 0
      libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
  40. 5 0
      libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
  41. 14 1
      librt/clock_getcpuclockid.c
  42. 6 1
      librt/clock_gettime.c
  43. 8 2
      librt/clock_nanosleep.c
  44. 6 0
      librt/mq_timedreceive.c
  45. 5 1
      librt/mq_timedsend.c
  46. 5 1
      librt/timer_gettime.c
  47. 6 1
      librt/timer_settime.c

+ 9 - 0
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"

+ 3 - 1
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];

+ 9 - 2
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

+ 8 - 1
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;
 	}

+ 23 - 1
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));

+ 10 - 0
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),

+ 1 - 1
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>

+ 13 - 8
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

+ 49 - 0
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__ */

+ 12 - 0
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

+ 5 - 1
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

+ 4 - 1
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>

+ 3 - 1
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>

+ 4 - 1
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>

+ 8 - 0
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;

+ 9 - 2
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
 }
 

+ 13 - 3
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)

+ 5 - 2
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

+ 5 - 1
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))

+ 5 - 0
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)
 

+ 32 - 0
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)

+ 16 - 5
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

+ 11 - 3
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

+ 5 - 1
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/ ... */

+ 15 - 0
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)

+ 27 - 0
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
 }

+ 4 - 0
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;
 	}
 

+ 13 - 0
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 ();

+ 5 - 1
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;
 	}
 

+ 5 - 0
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;
 	}

+ 13 - 0
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;

+ 19 - 0
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;

+ 13 - 0
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;

+ 5 - 0
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);

+ 8 - 0
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))
 	  {

+ 57 - 1
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)

+ 9 - 3
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,

+ 5 - 0
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);
 	    }

+ 4 - 0
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)

+ 5 - 0
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)

+ 14 - 1
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

+ 6 - 1
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							      \

+ 8 - 2
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
     }

+ 6 - 0
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)

+ 5 - 1
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)

+ 5 - 1
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);
 

+ 6 - 1
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);