From: Bart Van Assche Date: Sun, 27 Apr 2008 12:56:06 +0000 (+0000) Subject: Added support for timerfd_create(), timerfd_gettime() and timerfd_settime() system... X-Git-Tag: svn/VALGRIND_3_4_0~681 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c6d4c09e7cb99596242fa8d8fdbe145234e7cef6;p=thirdparty%2Fvalgrind.git Added support for timerfd_create(), timerfd_gettime() and timerfd_settime() system calls. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7942 --- diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 0033494fbf..c11c955c1e 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -126,7 +126,9 @@ DECL_TEMPLATE(linux, sys_timer_settime); DECL_TEMPLATE(linux, sys_timer_gettime); DECL_TEMPLATE(linux, sys_timer_getoverrun); DECL_TEMPLATE(linux, sys_timer_delete); -DECL_TEMPLATE(linux, sys_timerfd); +DECL_TEMPLATE(linux, sys_timerfd_create); +DECL_TEMPLATE(linux, sys_timerfd_gettime); +DECL_TEMPLATE(linux, sys_timerfd_settime); DECL_TEMPLATE(linux, sys_signalfd); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 173d01a9cf..06850b1896 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -1383,9 +1383,11 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINX_(__NR_utimensat, sys_utimensat), // 280 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 281 LINXY(__NR_signalfd, sys_signalfd), // 282 - LINXY(__NR_timerfd, sys_timerfd), // 283 + LINXY(__NR_timerfd_create, sys_timerfd_create), // 283 LINX_(__NR_eventfd, sys_eventfd), // 284 // LINX_(__NR_fallocate, sys_ni_syscall), // 285 + LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 286 + LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 287 }; const UInt ML_(syscall_table_size) = diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index a0cabc324f..235fb4e32c 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -1707,26 +1707,124 @@ PRE(sys_timer_delete) PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid); } -PRE(sys_timerfd) +/* --------------------------------------------------------------------- + timerfd* wrappers + See also http://lwn.net/Articles/260172/ for an overview. + See also /usr/src/linux/fs/timerfd.c for the implementation. + ------------------------------------------------------------------ */ + +static int linux_kernel_2_6_22(void) +{ + static int result = -1; + Int fd, read; + char release[64]; + SysRes res; + + if (result == -1) + { + res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0); + vg_assert(! res.isError); + fd = res.res; + read = VG_(read)(fd, release, sizeof(release) - 1); + vg_assert(read >= 0); + release[read] = 0; + VG_(close)(fd); + //VG_(printf)("kernel release = %s\n", release); + result = (VG_(strncmp)(release, "2.6.22", 6) == 0); + } + return result; +} + +PRE(sys_timerfd_create) +{ + if (linux_kernel_2_6_22()) + { + /* 2.6.22 kernel: timerfd system call. */ + PRINT("sys_timerfd ( %d, %d, %p )", ARG1, ARG2, ARG3); + PRE_REG_READ3(long, "sys_timerfd", + int, fd, int, clockid, const struct itimerspec *, tmr); + PRE_MEM_READ("timerfd(tmr)", ARG3, + sizeof(struct vki_itimerspec) ); + if (ARG1 != -1 && !ML_(fd_allowed)(ARG1, "timerfd", tid, False)) + SET_STATUS_Failure( VKI_EBADF ); + } + else + { + /* 2.6.24 and later kernels: timerfd_create system call. */ + PRINT("sys_timerfd_create (%d, %d )", ARG1, ARG2); + PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags); + } +} +POST(sys_timerfd_create) +{ + if (linux_kernel_2_6_22()) + { + /* 2.6.22 kernel: timerfd system call. */ + if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) + ML_(record_fd_open_nameless) (tid, RES); + } + } + else + { + /* 2.6.24 and later kernels: timerfd_create system call. */ + if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) + ML_(record_fd_open_nameless) (tid, RES); + } + } +} + +PRE(sys_timerfd_gettime) { - PRINT("sys_timerfd ( %d, %d, %p )", ARG1, ARG2, ARG3); - PRE_REG_READ3(long, "sys_timerfd", - int, fd, int, clockid, const struct itimerspec *, tmr); - PRE_MEM_READ( "timerfd(tmr)", ARG3, - sizeof(struct vki_itimerspec) ); - if (ARG1 != -1 && !ML_(fd_allowed)(ARG1, "timerfd", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + PRINT("sys_timerfd_gettime ( %d, %p )", ARG1, ARG2); + PRE_REG_READ2(long, "timerfd_gettime", + int, ufd, + struct vki_itimerspec*, otmr); + if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False)) + SET_STATUS_Failure(VKI_EBADF); + else + PRE_MEM_WRITE("timerfd_gettime(result)", + ARG2, sizeof(struct vki_itimerspec)); } -POST(sys_timerfd) +POST(sys_timerfd_gettime) { - if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) { - VG_(close)(RES); - SET_STATUS_Failure( VKI_EMFILE ); - } else { - if (VG_(clo_track_fds)) - ML_(record_fd_open_nameless) (tid, RES); + if (RES == 0) + POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec)); +} + +PRE(sys_timerfd_settime) +{ + PRINT("sys_timerfd_settime ( %d, %d, %p, %p )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(long, "timerfd_settime", + int, ufd, + int, flags, + const struct vki_itimerspec*, utmr, + struct vki_itimerspec*, otmr); + if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False)) + SET_STATUS_Failure(VKI_EBADF); + else + { + PRE_MEM_READ("timerfd_settime(result)", + ARG3, sizeof(struct vki_itimerspec)); + if (ARG4) + { + PRE_MEM_WRITE("timerfd_settime(result)", + ARG4, sizeof(struct vki_itimerspec)); + } } } +POST(sys_timerfd_settime) +{ + if (RES == 0 && ARG4 != 0) + POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec)); +} /* --------------------------------------------------------------------- capabilities wrappers diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index c29aa81476..8e19e1a6cb 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -1831,6 +1831,9 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINX_(__NR_eventfd, sys_eventfd), // 307 // LINX_(__NR_sync_file_range2, sys_ni_syscall), // 308 // LINX_(__NR_fallocate, sys_ni_syscall), // 309 +// LINXY(__NR_subpage_prot, sys_ni_syscall), // 310 + LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 311 + LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 312 }; const UInt ML_(syscall_table_size) = diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index fc18c2ba20..c6aa504efb 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -1487,6 +1487,9 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINX_(__NR_eventfd, sys_eventfd), // 307 // LINX_(__NR_sync_file_range2, sys_ni_syscall), // 308 // LINX_(__NR_fallocate, sys_ni_syscall), // 309 +// LINXY(__NR_subpage_prot, sys_ni_syscall), // 310 + LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 311 + LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 312 }; const UInt ML_(syscall_table_size) = diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index b96007cc28..3b69310093 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -2228,9 +2228,11 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINX_(__NR_utimensat, sys_utimensat), // 320 LINXY(__NR_signalfd, sys_signalfd), // 321 - LINXY(__NR_timerfd, sys_timerfd), // 322 + LINXY(__NR_timerfd_create, sys_timerfd_create), // 322 LINX_(__NR_eventfd, sys_eventfd), // 323 // LINX_(__NR_fallocate, sys_ni_syscall), // 324 + LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325 + LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326 }; const UInt ML_(syscall_table_size) = diff --git a/include/vki/vki-scnums-amd64-linux.h b/include/vki/vki-scnums-amd64-linux.h index d28d88b712..0f1ae01f79 100644 --- a/include/vki/vki-scnums-amd64-linux.h +++ b/include/vki/vki-scnums-amd64-linux.h @@ -364,9 +364,11 @@ #define __NR_utimensat 280 #define __NR_epoll_pwait 281 #define __NR_signalfd 282 -#define __NR_timerfd 283 +#define __NR_timerfd_create 283 #define __NR_eventfd 284 #define __NR_fallocate 285 +#define __NR_timerfd_settime 286 +#define __NR_timerfd_gettime 287 #endif /* __VKI_SCNUMS_AMD64_LINUX_H */ diff --git a/include/vki/vki-scnums-ppc32-linux.h b/include/vki/vki-scnums-ppc32-linux.h index 6d909bbc58..8441d820ba 100644 --- a/include/vki/vki-scnums-ppc32-linux.h +++ b/include/vki/vki-scnums-ppc32-linux.h @@ -348,12 +348,13 @@ #define __NR_epoll_pwait 303 #define __NR_utimensat 304 #define __NR_signalfd 305 -#define __NR_timerfd 306 +#define __NR_timerfd_create 306 #define __NR_eventfd 307 #define __NR_sync_file_range2 308 #define __NR_fallocate 309 - -#define __NR_syscalls 310 +#define __NR_subpage_prot 310 +#define __NR_timerfd_settime 311 +#define __NR_timerfd_gettime 312 #endif /* __VKI_SCNUMS_PPC32_LINUX_H */ diff --git a/include/vki/vki-scnums-ppc64-linux.h b/include/vki/vki-scnums-ppc64-linux.h index 783787a874..dba2012afa 100644 --- a/include/vki/vki-scnums-ppc64-linux.h +++ b/include/vki/vki-scnums-ppc64-linux.h @@ -340,10 +340,13 @@ #define __NR_epoll_pwait 303 #define __NR_utimensat 304 #define __NR_signalfd 305 -#define __NR_timerfd 306 +#define __NR_timerfd_create 306 #define __NR_eventfd 307 #define __NR_sync_file_range2 308 #define __NR_fallocate 309 +#define __NR_subpage_prot 310 +#define __NR_timerfd_settime 311 +#define __NR_timerfd_gettime 312 #endif /* __VKI_SCNUMS_PPC64_LINUX_H */ diff --git a/include/vki/vki-scnums-x86-linux.h b/include/vki/vki-scnums-x86-linux.h index a48d9200b8..95fee1008e 100644 --- a/include/vki/vki-scnums-x86-linux.h +++ b/include/vki/vki-scnums-x86-linux.h @@ -356,9 +356,11 @@ #define __NR_epoll_pwait 319 #define __NR_utimensat 320 #define __NR_signalfd 321 -#define __NR_timerfd 322 +#define __NR_timerfd_create 322 #define __NR_eventfd 323 #define __NR_fallocate 324 +#define __NR_timerfd_settime 325 +#define __NR_timerfd_gettime 326 #endif /* __VKI_SCNUMS_X86_LINUX_H */