Add 32bit time64 syscalls for arm, mips32, ppc32 and x86.

This patch adds sycall wrappers for the following syscalls which
use a 64bit time_t on 32bit arches: gettime64, settime64,
clock_getres_time64, clock_nanosleep_time64, timer_gettime64,
timer_settime64, timerfd_gettime64, timerfd_settime64,
utimensat_time64, pselect6_time64, ppoll_time64, recvmmsg_time64,
mq_timedsend_time64, mq_timedreceive_time64, semtimedop_time64,
rt_sigtimedwait_time64, futex_time64 and sched_rr_get_interval_time64.

Still missing are clock_adjtime64 and io_pgetevents_time64.

For the more complicated syscalls futex[_time64], pselect6[_time64]
and ppoll[_time64] there are shared pre and/or post helper functions.
Other functions just have their own PRE and POST handler.

Note that the vki_timespec64 struct really is the struct as used by
by glibc (it internally translates a 32bit timespec struct to a 64bit
timespec64 struct before passing it to any of the time64 syscalls).
The kernel uses a 64-bit signed int, but is ignoring the upper 32 bits
of the tv_nsec field. It does always write the full struct though.
So avoid checking the padding is only needed for PRE_MEM_READ.
There are two helper pre_read_timespec64 and pre_read_itimerspec64
to check the new structs.

https://bugs.kde.org/show_bug.cgi?id=416753
This commit is contained in:
Mark Wielaard 2020-02-28 13:36:31 +01:00
parent 28371e73db
commit 3d6a8157d5
8 changed files with 631 additions and 41 deletions

1
NEWS
View File

@ -123,6 +123,7 @@ n-i-bz Add support for the Linux io_uring system calls
n-i-bz sys_statx: don't complain if both |filename| and |buf| are NULL.
n-i-bz Fix non-glibc build of test suite with s390x_features
416667 gcc10 ppc64le impossible constraint in 'asm' in test_isa.
416753 new 32bit time syscalls for 2038+
417427 commit to fix vki_siginfo_t definition created numerous regression
errors on ppc64
417452 s390_insn_store_emit: dst->tag for HRcVec128

View File

@ -393,6 +393,28 @@ DECL_TEMPLATE(linux, sys_socketpair);
DECL_TEMPLATE(linux, sys_kcmp);
DECL_TEMPLATE(linux, sys_copy_file_range);
/* 64bit time_t syscalls for 32bit arches. */
DECL_TEMPLATE(linux, sys_clock_gettime64)
DECL_TEMPLATE(linux, sys_clock_settime64)
// clock_adjtime64
DECL_TEMPLATE(linux, sys_clock_getres_time64)
DECL_TEMPLATE(linux, sys_clock_nanosleep_time64);
DECL_TEMPLATE(linux, sys_timer_gettime64);
DECL_TEMPLATE(linux, sys_timer_settime64);
DECL_TEMPLATE(linux, sys_timerfd_gettime64);
DECL_TEMPLATE(linux, sys_timerfd_settime64);
DECL_TEMPLATE(linux, sys_utimensat_time64);
DECL_TEMPLATE(linux, sys_pselect6_time64);
DECL_TEMPLATE(linux, sys_ppoll_time64);
// io_pgetevents_time64
DECL_TEMPLATE(linux, sys_recvmmsg_time64);
DECL_TEMPLATE(linux, sys_mq_timedsend_time64);
DECL_TEMPLATE(linux, sys_mq_timedreceive_time64);
DECL_TEMPLATE(linux, sys_semtimedop_time64);
DECL_TEMPLATE(linux, sys_rt_sigtimedwait_time64);
DECL_TEMPLATE(linux, sys_futex_time64);
DECL_TEMPLATE(linux, sys_sched_rr_get_interval_time64);
// Some arch specific functions called from syswrap-linux.c
extern Int do_syscall_clone_x86_linux ( Word (*fn)(void *),
void* stack,

View File

@ -742,7 +742,7 @@ static SyscallTableEntry syscall_main_table[] = {
LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
//zz //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */*
LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161
GENXY(__NR_nanosleep, sys_nanosleep), // 162
GENX_(__NR_mremap, sys_mremap), // 163
LINX_(__NR_setresuid, sys_setresuid16), // 164
@ -1020,6 +1020,28 @@ static SyscallTableEntry syscall_main_table[] = {
LINX_(__NR_pwritev2, sys_pwritev2), // 393
LINXY(__NR_statx, sys_statx), // 397
LINXY(__NR_clock_gettime64, sys_clock_gettime64), // 403
LINX_(__NR_clock_settime64, sys_clock_settime64), // 404
LINXY(__NR_clock_getres_time64, sys_clock_getres_time64), // 406
LINXY(__NR_clock_nanosleep_time64, sys_clock_nanosleep_time64), // 407
LINXY(__NR_timer_gettime64, sys_timer_gettime64), // 408
LINXY(__NR_timer_settime64, sys_timer_settime64), // 409
LINXY(__NR_timerfd_gettime64, sys_timerfd_gettime64),// 410
LINXY(__NR_timerfd_settime64, sys_timerfd_settime64),// 411
LINX_(__NR_utimensat_time64, sys_utimensat_time64), // 412
LINXY(__NR_pselect6_time64, sys_pselect6_time64), // 413
LINXY(__NR_ppoll_time64, sys_ppoll_time64), // 414
LINXY(__NR_recvmmsg_time64, sys_recvmmsg_time64), // 417
LINX_(__NR_mq_timedsend_time64, sys_mq_timedsend_time64), // 418
LINXY(__NR_mq_timedreceive_time64, sys_mq_timedreceive_time64), // 419
LINX_(__NR_semtimedop_time64, sys_semtimedop_time64),// 420
LINXY(__NR_rt_sigtimedwait_time64, sys_rt_sigtimedwait_time64), // 421
LINXY(__NR_futex_time64, sys_futex_time64), // 422
LINXY(__NR_sched_rr_get_interval_time64,
sys_sched_rr_get_interval_time64), // 423
};

View File

@ -1622,7 +1622,23 @@ POST(sys_sendfile64)
}
}
PRE(sys_futex)
static void pre_read_timespec64 (ThreadId tid, const char *msg, UWord arg)
{
struct vki_timespec64 *ts64 = (void *)(Addr)arg;
PRE_MEM_READ (msg, (Addr) &ts64->tv_sec, sizeof(vki_time64_t));
PRE_MEM_READ (msg, (Addr) &ts64->tv_nsec, sizeof(vki_int32_t));
}
static void pre_read_itimerspec64 (ThreadId tid, const char *msg, UWord arg)
{
struct vki_itimerspec64 *its64 = (void *)(Addr)arg;
pre_read_timespec64 (tid, msg, (UWord) &its64->it_interval);
pre_read_timespec64 (tid, msg, (UWord) &its64->it_value);
}
static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
SyscallArgs* arrghs, SyscallStatus* status,
UWord* flags, Bool is_time64 )
{
/*
arg param used by ops
@ -1634,21 +1650,32 @@ PRE(sys_futex)
ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
ARG6 - int val3 CMP_REQUEUE
*/
PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
"x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
case VKI_FUTEX_CMP_REQUEUE:
case VKI_FUTEX_WAKE_OP:
case VKI_FUTEX_CMP_REQUEUE_PI:
PRE_REG_READ6(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
if (is_time64) {
PRE_REG_READ6(long, "futex_time64",
vki_u32 *, futex, int, op, int, val,
struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3);
} else {
PRE_REG_READ6(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
}
break;
case VKI_FUTEX_REQUEUE:
case VKI_FUTEX_WAIT_REQUEUE_PI:
PRE_REG_READ5(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime, vki_u32 *, uaddr2);
if (is_time64) {
PRE_REG_READ5(long, "futex_time64",
vki_u32 *, futex, int, op, int, val,
struct timespec64 *, utime, vki_u32 *, uaddr2);
} else {
PRE_REG_READ5(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime, vki_u32 *, uaddr2);
}
break;
case VKI_FUTEX_WAIT_BITSET:
/* Check that the address at least begins in client-accessible area. */
@ -1657,15 +1684,27 @@ PRE(sys_futex)
return;
}
if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
PRE_REG_READ4(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime);
if (is_time64) {
PRE_REG_READ4(long, "futex_time64",
vki_u32 *, futex, int, op, int, val,
struct timespec64 *, utime);
} else {
PRE_REG_READ4(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec64 *, utime);
}
} else {
/* Note argument 5 is unused, but argument 6 is used.
So we cannot just PRE_REG_READ6. Read argument 6 separately. */
PRE_REG_READ4(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime);
if (is_time64) {
PRE_REG_READ4(long, "futex_time64",
vki_u32 *, futex, int, op, int, val,
struct timespec64 *, utime);
} else {
PRE_REG_READ4(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime);
}
if (VG_(tdict).track_pre_reg_read)
PRA6("futex",int,val3);
}
@ -1679,9 +1718,15 @@ PRE(sys_futex)
break;
case VKI_FUTEX_WAIT:
case VKI_FUTEX_LOCK_PI:
PRE_REG_READ4(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime);
if (is_time64) {
PRE_REG_READ4(long, "futex_time64",
vki_u32 *, futex, int, op, int, val,
struct timespec64 *, utime);
} else {
PRE_REG_READ4(long, "futex",
vki_u32 *, futex, int, op, int, val,
struct timespec *, utime);
}
break;
case VKI_FUTEX_WAKE:
case VKI_FUTEX_FD:
@ -1703,8 +1748,14 @@ PRE(sys_futex)
case VKI_FUTEX_WAIT_BITSET:
case VKI_FUTEX_WAIT_REQUEUE_PI:
PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
if (ARG4 != 0)
PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
if (ARG4 != 0) {
if (is_time64) {
pre_read_timespec64 (tid, "futex_time64(timeout)", ARG4);
} else {
PRE_MEM_READ( "futex(timeout)", ARG4,
sizeof(struct vki_timespec) );
}
}
break;
case VKI_FUTEX_REQUEUE:
@ -1728,7 +1779,9 @@ PRE(sys_futex)
break;
}
}
POST(sys_futex)
static void futex_post_helper ( ThreadId tid, SyscallArgs* arrghs,
SyscallStatus* status )
{
vg_assert(SUCCESS);
POST_MEM_WRITE( ARG1, sizeof(int) );
@ -1743,6 +1796,30 @@ POST(sys_futex)
}
}
PRE(sys_futex)
{
PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
"x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
futex_pre_helper (tid, layout, arrghs, status, flags, False);
}
POST(sys_futex)
{
futex_post_helper (tid, arrghs, status);
}
PRE(sys_futex_time64)
{
PRINT("sys_futex_time64 ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
"x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
futex_pre_helper (tid, layout, arrghs, status, flags, True);
}
POST(sys_futex_time64)
{
futex_post_helper (tid, arrghs, status);
}
PRE(sys_set_robust_list)
{
PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
@ -1785,16 +1862,22 @@ struct pselect_adjusted_sigset {
vki_sigset_t adjusted_ss;
};
PRE(sys_pselect6)
static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
SyscallArgs* arrghs, SyscallStatus* status,
UWord* flags, Bool is_time64 )
{
*flags |= SfMayBlock | SfPostOnFail;
PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
PRE_REG_READ6(long, "pselect6",
int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
void *, sig);
if (is_time64) {
PRE_REG_READ6(long, "pselect6_time64",
int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
vki_fd_set *, exceptfds, struct vki_timespec64 *, timeout,
void *, sig);
} else {
PRE_REG_READ6(long, "pselect6",
int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
void *, sig);
}
// XXX: this possibly understates how much memory is read.
if (ARG2 != 0)
PRE_MEM_READ( "pselect6(readfds)",
@ -1805,8 +1888,14 @@ PRE(sys_pselect6)
if (ARG4 != 0)
PRE_MEM_READ( "pselect6(exceptfds)",
ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
if (ARG5 != 0)
PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
if (ARG5 != 0) {
if (is_time64) {
pre_read_timespec64(tid, "pselect6_time64(timeout)", ARG5);
} else {
PRE_MEM_READ( "pselect6(timeout)", ARG5,
sizeof(struct vki_timespec) );
}
}
if (ARG6 != 0) {
const struct pselect_sized_sigset *pss =
(struct pselect_sized_sigset *)(Addr)ARG6;
@ -1834,6 +1923,15 @@ PRE(sys_pselect6)
}
}
}
PRE(sys_pselect6)
{
PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
pselect6_pre_helper (tid, layout, arrghs, status, flags, False);
}
POST(sys_pselect6)
{
if (ARG6 != 0 && ARG6 != 1) {
@ -1841,7 +1939,24 @@ POST(sys_pselect6)
}
}
PRE(sys_ppoll)
PRE(sys_pselect6_time64)
{
PRINT("sys_pselect6_time64 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
pselect6_pre_helper (tid, layout, arrghs, status, flags, True);
}
POST(sys_pselect6_time64)
{
if (ARG6 != 0 && ARG6 != 1) {
VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
}
}
static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
SyscallArgs* arrghs, SyscallStatus* status,
UWord* flags, Bool is_time64 )
{
UInt i;
struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
@ -1849,10 +1964,17 @@ PRE(sys_ppoll)
PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
"x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
ARG1, ARG2, ARG3, ARG4, ARG5);
PRE_REG_READ5(long, "ppoll",
struct vki_pollfd *, ufds, unsigned int, nfds,
struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
vki_size_t, sigsetsize);
if (is_time64) {
PRE_REG_READ5(long, "ppoll_time64",
struct vki_pollfd *, ufds, unsigned int, nfds,
struct vki_timespec64 *, tsp, vki_sigset_t *, sigmask,
vki_size_t, sigsetsize);
} else {
PRE_REG_READ5(long, "ppoll",
struct vki_pollfd *, ufds, unsigned int, nfds,
struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
vki_size_t, sigsetsize);
}
for (i = 0; i < ARG2; i++) {
PRE_MEM_READ( "ppoll(ufds.fd)",
@ -1863,8 +1985,14 @@ PRE(sys_ppoll)
(Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
}
if (ARG3)
PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
if (ARG3) {
if (is_time64) {
pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
} else {
PRE_MEM_READ( "ppoll(tsp)", ARG3,
sizeof(struct vki_timespec) );
}
}
if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
@ -1880,7 +2008,8 @@ PRE(sys_ppoll)
}
}
POST(sys_ppoll)
static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
SyscallStatus* status )
{
vg_assert(SUCCESS || FAILURE);
if (SUCCESS && (RES >= 0)) {
@ -1894,6 +2023,32 @@ POST(sys_ppoll)
}
}
PRE(sys_ppoll)
{
PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
"x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
ARG1, ARG2, ARG3, ARG4, ARG5);
ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
}
POST(sys_ppoll)
{
ppoll_post_helper (tid, arrghs, status);
}
PRE(sys_ppoll_time64)
{
PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
"u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
ARG1, ARG2, ARG3, ARG4, ARG5);
ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
}
POST(sys_ppoll_time64)
{
ppoll_post_helper (tid, arrghs, status);
}
/* ---------------------------------------------------------------------
epoll_* wrappers
@ -2682,6 +2837,25 @@ PRE(sys_mq_timedsend)
}
}
PRE(sys_mq_timedsend_time64)
{
*flags |= SfMayBlock;
PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
"u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
SARG1,ARG2,ARG3,ARG4,ARG5);
PRE_REG_READ5(long, "mq_timedsend_time64",
vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
unsigned int, msg_prio,
const struct vki_timespec64 *, abs_timeout);
if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
SET_STATUS_Failure( VKI_EBADF );
} else {
PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
if (ARG5 != 0)
pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
}
}
PRE(sys_mq_timedreceive)
{
*flags |= SfMayBlock;
@ -2711,6 +2885,35 @@ POST(sys_mq_timedreceive)
POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
}
PRE(sys_mq_timedreceive_time64)
{
*flags |= SfMayBlock;
PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
SARG1,ARG2,ARG3,ARG4,ARG5);
PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
unsigned int *, msg_prio,
const struct vki_timespec64 *, abs_timeout);
if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
SET_STATUS_Failure( VKI_EBADF );
} else {
PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
if (ARG4 != 0)
PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
ARG4, sizeof(unsigned int) );
if (ARG5 != 0)
pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
}
}
POST(sys_mq_timedreceive_time64)
{
POST_MEM_WRITE( ARG2, RES );
if (ARG4 != 0)
POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
}
PRE(sys_mq_notify)
{
PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
@ -2761,6 +2964,14 @@ PRE(sys_clock_settime)
PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
}
PRE(sys_clock_settime64)
{
PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
PRE_REG_READ2(long, "clock_settime64",
vki_clockid_t, clk_id, const struct timespec64 *, tp);
pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
}
PRE(sys_clock_gettime)
{
PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
@ -2773,6 +2984,19 @@ POST(sys_clock_gettime)
POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
}
PRE(sys_clock_gettime64)
{
PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
PRE_REG_READ2(long, "clock_gettime64",
vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
sizeof(struct vki_timespec64) );
}
POST(sys_clock_gettime64)
{
POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
}
PRE(sys_clock_getres)
{
PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
@ -2789,6 +3013,23 @@ POST(sys_clock_getres)
POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
}
PRE(sys_clock_getres_time64)
{
PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
// Nb: we can't use "RES" as the param name because that's a macro
// defined above!
PRE_REG_READ2(long, "clock_getres_time64",
vki_clockid_t, clk_id, struct vki_timespec64 *, res);
if (ARG2 != 0)
PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
sizeof(struct vki_timespec64) );
}
POST(sys_clock_getres_time64)
{
if (ARG2 != 0)
POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
}
PRE(sys_clock_nanosleep)
{
*flags |= SfMayBlock|SfPostOnFail;
@ -2808,6 +3049,27 @@ POST(sys_clock_nanosleep)
POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
}
PRE(sys_clock_nanosleep_time64)
{
*flags |= SfMayBlock|SfPostOnFail;
PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x )",
SARG1, SARG2, ARG3, ARG4);
PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
vki_clockid_t, clkid, int, flags,
const struct vki_timespec64 *, rqtp,
struct vki_timespec64 *, rmtp);
pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
if (ARG4 != 0)
PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
sizeof(struct vki_timespec64) );
}
POST(sys_clock_nanosleep_time64)
{
if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
}
/* ---------------------------------------------------------------------
timer_* wrappers
------------------------------------------------------------------ */
@ -2859,6 +3121,26 @@ POST(sys_timer_settime)
POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
}
PRE(sys_timer_settime64)
{
PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
PRE_REG_READ4(long, "timer_settime64",
vki_timer_t, timerid, int, flags,
const struct vki_itimerspec64 *, value,
struct vki_itimerspec64 *, ovalue);
PRE_MEM_READ( "timer_settime64(value)", ARG3,
sizeof(struct vki_itimerspec64) );
if (ARG4 != 0)
PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
sizeof(struct vki_itimerspec64) );
}
POST(sys_timer_settime64)
{
if (ARG4 != 0)
POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
}
PRE(sys_timer_gettime)
{
PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
@ -2872,6 +3154,19 @@ POST(sys_timer_gettime)
POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
}
PRE(sys_timer_gettime64)
{
PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
PRE_REG_READ2(long, "timer_gettime64",
vki_timer_t, timerid, struct vki_itimerspec64 *, value);
PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
sizeof(struct vki_itimerspec64));
}
POST(sys_timer_gettime64)
{
POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
}
PRE(sys_timer_getoverrun)
{
PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
@ -2978,6 +3273,24 @@ POST(sys_timerfd_gettime)
POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
}
PRE(sys_timerfd_gettime64)
{
PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
PRE_REG_READ2(long, "timerfd_gettime64",
int, ufd,
struct vki_itimerspec64*, otmr);
if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
SET_STATUS_Failure(VKI_EBADF);
else
PRE_MEM_WRITE("timerfd_gettime64(result)",
ARG2, sizeof(struct vki_itimerspec64));
}
POST(sys_timerfd_gettime64)
{
if (RES == 0)
POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
}
PRE(sys_timerfd_settime)
{
PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
@ -3006,6 +3319,33 @@ POST(sys_timerfd_settime)
POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
}
PRE(sys_timerfd_settime64)
{
PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
PRE_REG_READ4(long, "timerfd_settime64",
int, ufd,
int, flags,
const struct vki_itimerspec64*, utmr,
struct vki_itimerspec64*, otmr);
if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
SET_STATUS_Failure(VKI_EBADF);
else
{
pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
if (ARG4)
{
PRE_MEM_WRITE("timerfd_settime64(result)",
ARG4, sizeof(struct vki_itimerspec64));
}
}
}
POST(sys_timerfd_settime64)
{
if (RES == 0 && ARG4 != 0)
POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
}
/* ---------------------------------------------------------------------
capabilities wrappers
------------------------------------------------------------------ */
@ -3388,6 +3728,22 @@ POST(sys_sched_rr_get_interval)
POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
}
PRE(sys_sched_rr_get_interval_time64)
{
PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
SARG1, ARG2);
PRE_REG_READ2(int, "sched_rr_get_interval_time64",
vki_pid_t, pid,
struct vki_timespec *, tp);
PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
ARG2, sizeof(struct vki_timespec64));
}
POST(sys_sched_rr_get_interval_time64)
{
POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
}
PRE(sys_sched_setaffinity)
{
PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
@ -4115,6 +4471,30 @@ POST(sys_rt_sigtimedwait)
POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
}
PRE(sys_rt_sigtimedwait_time64)
{
*flags |= SfMayBlock;
PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
ARG1, ARG2, ARG3, ARG4);
PRE_REG_READ4(long, "rt_sigtimedwait_time64",
const vki_sigset_t *, set, vki_siginfo_t *, info,
const struct vki_timespec64 *, timeout,
vki_size_t, sigsetsize);
if (ARG1 != 0)
PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
if (ARG2 != 0)
PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
sizeof(vki_siginfo_t) );
if (ARG3 != 0)
pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
}
POST(sys_rt_sigtimedwait_time64)
{
if (ARG2 != 0)
POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
}
PRE(sys_rt_sigqueueinfo)
{
PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
@ -4563,6 +4943,20 @@ PRE(sys_semtimedop)
ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
}
PRE(sys_semtimedop_time64)
{
*flags |= SfMayBlock;
PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
PRE_REG_READ4(long, "semtimedop_time64",
int, semid, struct sembuf *, sops, unsigned, nsoops,
struct vki_timespec64 *, timeout);
PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
ARG2 * sizeof(struct vki_sembuf) );
if (ARG3 != 0)
pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
}
PRE(sys_msgget)
{
PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
@ -5372,6 +5766,36 @@ PRE(sys_utimensat)
}
}
PRE(sys_utimensat_time64)
{
PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
PRE_REG_READ4(long, "utimensat_time64",
int, dfd, char *, filename, struct timespec *, utimes, int, flags);
if (ARG2 != 0)
PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
if (ARG3 != 0) {
/* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
then the tv_sec field is ignored. */
struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
(Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
(Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
if (times[0].tv_nsec != VKI_UTIME_NOW
&& times[0].tv_nsec != VKI_UTIME_OMIT)
PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
(Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
if (times[1].tv_nsec != VKI_UTIME_NOW
&& times[1].tv_nsec != VKI_UTIME_OMIT)
PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
(Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
}
}
}
#if !defined(VGP_nanomips_linux)
PRE(sys_newfstatat)
{
@ -5866,6 +6290,34 @@ POST(sys_recvmmsg)
ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
}
PRE(sys_recvmmsg_time64)
{
*flags |= SfMayBlock;
PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
FMT_REGWORD "x )",
SARG1, ARG2, SARG3, SARG4, ARG5);
PRE_REG_READ5(long, "recvmmsg_time64",
int, s, struct mmsghdr *, mmsg, int, vlen,
int, flags, struct vki_timespec64 *, timeout);
struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
HChar name[40]; // large enough
UInt i;
for (i = 0; i < ARG3; i++) {
VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
}
if (ARG5)
pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
}
POST(sys_recvmmsg_time64)
{
/* ARG5 isn't actually used, so just use the generic POST. */
ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
}
/* ---------------------------------------------------------------------
key retention service wrappers
------------------------------------------------------------------ */
@ -12679,3 +13131,4 @@ POST(sys_io_uring_register)
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/

View File

@ -1103,7 +1103,29 @@ static SyscallTableEntry syscall_main_table[] = {
LINXY (__NR_preadv2, sys_preadv2), // 361
LINX_ (__NR_pwritev2, sys_pwritev2), // 362
//..
LINXY(__NR_statx, sys_statx) // 366
LINXY(__NR_statx, sys_statx), // 366
LINXY(__NR_clock_gettime64, sys_clock_gettime64), // 403
LINX_(__NR_clock_settime64, sys_clock_settime64), // 404
LINXY(__NR_clock_getres_time64, sys_clock_getres_time64), // 406
LINXY(__NR_clock_nanosleep_time64, sys_clock_nanosleep_time64), // 407
LINXY(__NR_timer_gettime64, sys_timer_gettime64), // 408
LINXY(__NR_timer_settime64, sys_timer_settime64), // 409
LINXY(__NR_timerfd_gettime64, sys_timerfd_gettime64), // 410
LINXY(__NR_timerfd_settime64, sys_timerfd_settime64), // 411
LINX_(__NR_utimensat_time64, sys_utimensat_time64), // 412
LINXY(__NR_pselect6_time64, sys_pselect6_time64), // 413
LINXY(__NR_ppoll_time64, sys_ppoll_time64), // 414
LINXY(__NR_recvmmsg_time64, sys_recvmmsg_time64), // 417
LINX_(__NR_mq_timedsend_time64, sys_mq_timedsend_time64), // 418
LINXY(__NR_mq_timedreceive_time64, sys_mq_timedreceive_time64), // 419
LINX_(__NR_semtimedop_time64, sys_semtimedop_time64), // 420
LINXY(__NR_rt_sigtimedwait_time64, sys_rt_sigtimedwait_time64), // 421
LINXY(__NR_futex_time64, sys_futex_time64), // 422
LINXY(__NR_sched_rr_get_interval_time64,
sys_sched_rr_get_interval_time64), // 423
};
SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno)

View File

@ -1022,6 +1022,28 @@ static SyscallTableEntry syscall_table[] = {
LINX_(__NR_copy_file_range, sys_copy_file_range), // 379
LINXY(__NR_statx, sys_statx), // 383
LINXY(__NR_clock_gettime64, sys_clock_gettime64), // 403
LINX_(__NR_clock_settime64, sys_clock_settime64), // 404
LINXY(__NR_clock_getres_time64, sys_clock_getres_time64), // 406
LINXY(__NR_clock_nanosleep_time64, sys_clock_nanosleep_time64), // 407
LINXY(__NR_timer_gettime64, sys_timer_gettime64), // 408
LINXY(__NR_timer_settime64, sys_timer_settime64), // 409
LINXY(__NR_timerfd_gettime64, sys_timerfd_gettime64),// 410
LINXY(__NR_timerfd_settime64, sys_timerfd_settime64),// 411
LINX_(__NR_utimensat_time64, sys_utimensat_time64), // 412
LINXY(__NR_pselect6_time64, sys_pselect6_time64), // 413
LINXY(__NR_ppoll_time64, sys_ppoll_time64), // 414
LINXY(__NR_recvmmsg_time64, sys_recvmmsg_time64), // 417
LINX_(__NR_mq_timedsend_time64, sys_mq_timedsend_time64), // 418
LINXY(__NR_mq_timedreceive_time64, sys_mq_timedreceive_time64), // 419
LINX_(__NR_semtimedop_time64, sys_semtimedop_time64),// 420
LINXY(__NR_rt_sigtimedwait_time64, sys_rt_sigtimedwait_time64), // 421
LINXY(__NR_futex_time64, sys_futex_time64), // 422
LINXY(__NR_sched_rr_get_interval_time64,
sys_sched_rr_get_interval_time64), // 423
};
SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )

View File

@ -1618,6 +1618,28 @@ static SyscallTableEntry syscall_table[] = {
/* Explicitly not supported on i386 yet. */
GENX_(__NR_arch_prctl, sys_ni_syscall), // 384
LINXY(__NR_clock_gettime64, sys_clock_gettime64), // 403
LINX_(__NR_clock_settime64, sys_clock_settime64), // 404
LINXY(__NR_clock_getres_time64, sys_clock_getres_time64), // 406
LINXY(__NR_clock_nanosleep_time64, sys_clock_nanosleep_time64), // 407
LINXY(__NR_timer_gettime64, sys_timer_gettime64), // 408
LINXY(__NR_timer_settime64, sys_timer_settime64), // 409
LINXY(__NR_timerfd_gettime64, sys_timerfd_gettime64),// 410
LINXY(__NR_timerfd_settime64, sys_timerfd_settime64),// 411
LINX_(__NR_utimensat_time64, sys_utimensat_time64), // 412
LINXY(__NR_pselect6_time64, sys_pselect6_time64), // 413
LINXY(__NR_ppoll_time64, sys_ppoll_time64), // 414
LINXY(__NR_recvmmsg_time64, sys_recvmmsg_time64), // 417
LINX_(__NR_mq_timedsend_time64, sys_mq_timedsend_time64), // 418
LINXY(__NR_mq_timedreceive_time64, sys_mq_timedreceive_time64), // 419
LINX_(__NR_semtimedop_time64, sys_semtimedop_time64),// 420
LINXY(__NR_rt_sigtimedwait_time64, sys_rt_sigtimedwait_time64), // 421
LINXY(__NR_futex_time64, sys_futex_time64), // 422
LINXY(__NR_sched_rr_get_interval_time64,
sys_sched_rr_get_interval_time64), // 423
LINXY(__NR_io_uring_setup, sys_io_uring_setup), // 425
LINXY(__NR_io_uring_enter, sys_io_uring_enter), // 426
LINXY(__NR_io_uring_register, sys_io_uring_register),// 427

View File

@ -5313,6 +5313,32 @@ struct vki_ptp_pin_desc {
#define VKI_PTP_SYS_OFFSET_EXTENDED \
_VKI_IOWR('=', 9, struct vki_ptp_sys_offset_extended)
/* Needed for 64bit time_t on 32bit arches. */
typedef vki_int64_t vki_time64_t;
/* Note that this is the padding used by glibc, the kernel uses
a 64-bit signed int, but is ignoring the upper 32 bits of the
tv_nsec field. It does always write the full struct though.
So this is only needed for PRE_MEM_READ. See pre_read_timespec64. */
struct vki_timespec64 {
vki_time64_t tv_sec;
#if defined(VKI_BIG_ENDIAN)
vki_int32_t tv_pad;
vki_int32_t tv_nsec;
#elif defined(VKI_LITTLE_ENDIAN)
vki_int32_t tv_nsec;
vki_int32_t tv_pad;
#else
#error edit for your odd byteorder.
#endif
};
struct vki_itimerspec64 {
struct vki_timespec it_interval;
struct vki_timespec it_value;
};
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/