diff --git a/compiler-rt/include/sanitizer/linux_syscall_hooks.h b/compiler-rt/include/sanitizer/linux_syscall_hooks.h new file mode 100644 index 000000000000..84783050b83d --- /dev/null +++ b/compiler-rt/include/sanitizer/linux_syscall_hooks.h @@ -0,0 +1,275 @@ +//===-- linux_syscall_hooks.h ---------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of public sanitizer interface. +// +// System call handlers. +// +// Interface methods declared in this header implement pre- and post- syscall +// actions for the active sanitizer. +// Usage: +// __sanitizer_syscall_pre_getfoo(...args...); +// int res = syscall(__NR_getfoo, ...args...); +// __sanitizer_syscall_post_getfoo(res, ...args...); +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_LINUX_SYSCALL_HOOKS_H +#define SANITIZER_LINUX_SYSCALL_HOOKS_H + +#ifdef __cplusplus +extern "C" { +#endif + +void __sanitizer_syscall_pre_rt_sigpending(void *p, size_t s); +void __sanitizer_syscall_pre_getdents(int fd, void *dirp, int count); +void __sanitizer_syscall_pre_getdents64(int fd, void *dirp, int count); +void __sanitizer_syscall_pre_recvmsg(int sockfd, void *msg, int flags); + +void __sanitizer_syscall_post_rt_sigpending(int res, void *p, size_t s); +void __sanitizer_syscall_post_getdents(int res, int fd, void *dirp, int count); +void __sanitizer_syscall_post_getdents64(int res, int fd, void *dirp, int count); +void __sanitizer_syscall_post_recvmsg(int res, int sockfd, void *msg, int flags); + +// And now a few syscalls we don't handle yet. + +#define __sanitizer_syscall_pre__gettid() +#define __sanitizer_syscall_pre_fork() +#define __sanitizer_syscall_pre_getegid() +#define __sanitizer_syscall_pre_geteuid() +#define __sanitizer_syscall_pre_getpgrp() +#define __sanitizer_syscall_pre_getpid() +#define __sanitizer_syscall_pre_getppid() +#define __sanitizer_syscall_pre_sched_yield() +#define __sanitizer_syscall_pre_setsid() + +#define __sanitizer_syscall_pre__exit(a) +#define __sanitizer_syscall_pre_brk(a) +#define __sanitizer_syscall_pre_chdir(a) +#define __sanitizer_syscall_pre_chroot(a) +#define __sanitizer_syscall_pre_close(a) +#define __sanitizer_syscall_pre_dup(a) +#define __sanitizer_syscall_pre_exit_group(a) +#define __sanitizer_syscall_pre_getsid(a) +#define __sanitizer_syscall_pre_io_destroy(a) +#define __sanitizer_syscall_pre_pipe(a) +#define __sanitizer_syscall_pre_rt_sigreturn(a) +#define __sanitizer_syscall_pre_set_tid_address(a) +#define __sanitizer_syscall_pre_setfsgid(a) +#define __sanitizer_syscall_pre_setfsuid(a) +#define __sanitizer_syscall_pre_setgid(a) +#define __sanitizer_syscall_pre_setuid(a) +#define __sanitizer_syscall_pre_umask(a) +#define __sanitizer_syscall_pre_unlink(a) +#define __sanitizer_syscall_pre_unshare(a) + +#define __sanitizer_syscall_pre_arch_prctl(a, b) +#define __sanitizer_syscall_pre_capset(a, b) +#define __sanitizer_syscall_pre_clock_getres(a, b) +#define __sanitizer_syscall_pre_clock_gettime(a, b) +#define __sanitizer_syscall_pre_dup2(a, b) +#define __sanitizer_syscall_pre_fstat(a, b) +#define __sanitizer_syscall_pre_fstatfs(a, b) +#define __sanitizer_syscall_pre_ftruncate(a, b) +#define __sanitizer_syscall_pre_getpriority(a, b) +#define __sanitizer_syscall_pre_getrlimit(a, b) +#define __sanitizer_syscall_pre_gettimeofday(a, b) +#define __sanitizer_syscall_pre_io_setup(a, b) +#define __sanitizer_syscall_pre_ioprio_get(a, b) +#define __sanitizer_syscall_pre_kill(a, b) +#define __sanitizer_syscall_pre_munmap(a, b) +#define __sanitizer_syscall_pre_prctl(a, b) +#define __sanitizer_syscall_pre_rt_sigsuspend(a, b) +#define __sanitizer_syscall_pre_setgroups(a, b) +#define __sanitizer_syscall_pre_setns(a, b) +#define __sanitizer_syscall_pre_setpgid(a, b) +#define __sanitizer_syscall_pre_setrlimit(a, b) +#define __sanitizer_syscall_pre_shutdown(a, b) +#define __sanitizer_syscall_pre_sigaltstack(a, b) +#define __sanitizer_syscall_pre_stat(a, b) +#define __sanitizer_syscall_pre_statfs(a, b) +#define __sanitizer_syscall_pre_tkill(a, b) + +#define __sanitizer_syscall_pre_execve(a, b, c) +#define __sanitizer_syscall_pre_fcntl(a, b, c) +#define __sanitizer_syscall_pre_getcpu(a, b, c) +#define __sanitizer_syscall_pre_getresgid(a, b, c) +#define __sanitizer_syscall_pre_getresuid(a, b, c) +#define __sanitizer_syscall_pre_io_cancel(a, b, c) +#define __sanitizer_syscall_pre_io_submit(a, b, c) +#define __sanitizer_syscall_pre_ioctl(a, b, c) +#define __sanitizer_syscall_pre_ioprio_set(a, b, c) +#define __sanitizer_syscall_pre_listxattr(a, b, c) +#define __sanitizer_syscall_pre_llistxattr(a, b, c) +#define __sanitizer_syscall_pre_lseek(a, b, c) +#define __sanitizer_syscall_pre_mprotect(a, b, c) +#define __sanitizer_syscall_pre_open(a, b, c) +#define __sanitizer_syscall_pre_poll(a, b, c) +#define __sanitizer_syscall_pre_read(a, b, c) +#define __sanitizer_syscall_pre_readahead(a, b, c) +#define __sanitizer_syscall_pre_readlink(a, b, c) +#define __sanitizer_syscall_pre_sched_getaffinity(a, b, c) +#define __sanitizer_syscall_pre_sched_setaffinity(a, b, c) +#define __sanitizer_syscall_pre_sendmsg(a, b, c) +#define __sanitizer_syscall_pre_setpriority(a, b, c) +#define __sanitizer_syscall_pre_setresgid(a, b, c) +#define __sanitizer_syscall_pre_setresuid(a, b, c) +#define __sanitizer_syscall_pre_socket(a, b, c) +#define __sanitizer_syscall_pre_tgkill(a, b, c) +#define __sanitizer_syscall_pre_unlinkat(a, b, c) +#define __sanitizer_syscall_pre_write(a, b, c) +#define __sanitizer_syscall_pre_writev(a, b, c) + +#define __sanitizer_syscall_pre_fadvise64(a, b, c, d) +#define __sanitizer_syscall_pre_fallocate(a, b, c, d) +#define __sanitizer_syscall_pre_futex(a, b, c, d) +#define __sanitizer_syscall_pre_getxattr(a, b, c, d) +#define __sanitizer_syscall_pre_lgetxattr(a, b, c, d) +#define __sanitizer_syscall_pre_newfstatat(a, b, c, d) +#define __sanitizer_syscall_pre_openat(a, b, c, d) +#define __sanitizer_syscall_pre_pread64(a, b, c, d) +#define __sanitizer_syscall_pre_ptrace(a, b, c, d) +#define __sanitizer_syscall_pre_pwrite64(a, b, c, d) +#define __sanitizer_syscall_pre_quotactl(a, b, c, d) +#define __sanitizer_syscall_pre_rt_sigaction(a, b, c, d) +#define __sanitizer_syscall_pre_rt_sigprocmask(a, b, c, d) +#define __sanitizer_syscall_pre_socketpair(a, b, c, d) +#define __sanitizer_syscall_pre_wait4(a, b, c, d) + +#define __sanitizer_syscall_pre__mremap(a, b, c, d, e) +#define __sanitizer_syscall_pre_io_getevents(a, b, c, d, e) +#define __sanitizer_syscall_pre_lsetxattr(a, b, c, d, e) +#define __sanitizer_syscall_pre_mount(a, b, c, d, e) +#define __sanitizer_syscall_pre_preadv(a, b, c, d, e) +#define __sanitizer_syscall_pre_pwritev(a, b, c, d, e) +#define __sanitizer_syscall_pre_setxattr(a, b, c, d, e) + +#define __sanitizer_syscall_pre_mmap(a, b, c, d, e, f) +#define __sanitizer_syscall_pre_move_pages(a, b, c, d, e, f) +#define __sanitizer_syscall_pre_sendto(a, b, c, d, e, f) + + +#define __sanitizer_syscall_post__gettid(res) +#define __sanitizer_syscall_post_fork(res) +#define __sanitizer_syscall_post_getegid(res) +#define __sanitizer_syscall_post_geteuid(res) +#define __sanitizer_syscall_post_getpgrp(res) +#define __sanitizer_syscall_post_getpid(res) +#define __sanitizer_syscall_post_getppid(res) +#define __sanitizer_syscall_post_sched_yield(res) +#define __sanitizer_syscall_post_setsid(res) + +#define __sanitizer_syscall_post__exit(res, a) +#define __sanitizer_syscall_post_brk(res, a) +#define __sanitizer_syscall_post_chdir(res, a) +#define __sanitizer_syscall_post_chroot(res, a) +#define __sanitizer_syscall_post_close(res, a) +#define __sanitizer_syscall_post_dup(res, a) +#define __sanitizer_syscall_post_exit_group(res, a) +#define __sanitizer_syscall_post_getsid(res, a) +#define __sanitizer_syscall_post_io_destroy(res, a) +#define __sanitizer_syscall_post_pipe(res, a) +#define __sanitizer_syscall_post_rt_sigreturn(res, a) +#define __sanitizer_syscall_post_set_tid_address(res, a) +#define __sanitizer_syscall_post_setfsgid(res, a) +#define __sanitizer_syscall_post_setfsuid(res, a) +#define __sanitizer_syscall_post_setgid(res, a) +#define __sanitizer_syscall_post_setuid(res, a) +#define __sanitizer_syscall_post_umask(res, a) +#define __sanitizer_syscall_post_unlink(res, a) +#define __sanitizer_syscall_post_unshare(res, a) + +#define __sanitizer_syscall_post_arch_prctl(res, a, b) +#define __sanitizer_syscall_post_capset(res, a, b) +#define __sanitizer_syscall_post_clock_getres(res, a, b) +#define __sanitizer_syscall_post_clock_gettime(res, a, b) +#define __sanitizer_syscall_post_dup2(res, a, b) +#define __sanitizer_syscall_post_fstat(res, a, b) +#define __sanitizer_syscall_post_fstatfs(res, a, b) +#define __sanitizer_syscall_post_ftruncate(res, a, b) +#define __sanitizer_syscall_post_getpriority(res, a, b) +#define __sanitizer_syscall_post_getrlimit(res, a, b) +#define __sanitizer_syscall_post_gettimeofday(res, a, b) +#define __sanitizer_syscall_post_io_setup(res, a, b) +#define __sanitizer_syscall_post_ioprio_get(res, a, b) +#define __sanitizer_syscall_post_kill(res, a, b) +#define __sanitizer_syscall_post_munmap(res, a, b) +#define __sanitizer_syscall_post_prctl(res, a, b) +#define __sanitizer_syscall_post_rt_sigsuspend(res, a, b) +#define __sanitizer_syscall_post_setgroups(res, a, b) +#define __sanitizer_syscall_post_setns(res, a, b) +#define __sanitizer_syscall_post_setpgid(res, a, b) +#define __sanitizer_syscall_post_setrlimit(res, a, b) +#define __sanitizer_syscall_post_shutdown(res, a, b) +#define __sanitizer_syscall_post_sigaltstack(res, a, b) +#define __sanitizer_syscall_post_stat(res, a, b) +#define __sanitizer_syscall_post_statfs(res, a, b) +#define __sanitizer_syscall_post_tkill(res, a, b) + +#define __sanitizer_syscall_post_execve(res, a, b, c) +#define __sanitizer_syscall_post_fcntl(res, a, b, c) +#define __sanitizer_syscall_post_getcpu(res, a, b, c) +#define __sanitizer_syscall_post_getresgid(res, a, b, c) +#define __sanitizer_syscall_post_getresuid(res, a, b, c) +#define __sanitizer_syscall_post_io_cancel(res, a, b, c) +#define __sanitizer_syscall_post_io_submit(res, a, b, c) +#define __sanitizer_syscall_post_ioctl(res, a, b, c) +#define __sanitizer_syscall_post_ioprio_set(res, a, b, c) +#define __sanitizer_syscall_post_listxattr(res, a, b, c) +#define __sanitizer_syscall_post_llistxattr(res, a, b, c) +#define __sanitizer_syscall_post_lseek(res, a, b, c) +#define __sanitizer_syscall_post_mprotect(res, a, b, c) +#define __sanitizer_syscall_post_open(res, a, b, c) +#define __sanitizer_syscall_post_poll(res, a, b, c) +#define __sanitizer_syscall_post_read(res, a, b, c) +#define __sanitizer_syscall_post_readahead(res, a, b, c) +#define __sanitizer_syscall_post_readlink(res, a, b, c) +#define __sanitizer_syscall_post_sched_getaffinity(res, a, b, c) +#define __sanitizer_syscall_post_sched_setaffinity(res, a, b, c) +#define __sanitizer_syscall_post_sendmsg(res, a, b, c) +#define __sanitizer_syscall_post_setpriority(res, a, b, c) +#define __sanitizer_syscall_post_setresgid(res, a, b, c) +#define __sanitizer_syscall_post_setresuid(res, a, b, c) +#define __sanitizer_syscall_post_socket(res, a, b, c) +#define __sanitizer_syscall_post_tgkill(res, a, b, c) +#define __sanitizer_syscall_post_unlinkat(res, a, b, c) +#define __sanitizer_syscall_post_write(res, a, b, c) +#define __sanitizer_syscall_post_writev(res, a, b, c) + +#define __sanitizer_syscall_post_fadvise64(res, a, b, c, d) +#define __sanitizer_syscall_post_fallocate(res, a, b, c, d) +#define __sanitizer_syscall_post_futex(res, a, b, c, d) +#define __sanitizer_syscall_post_getxattr(res, a, b, c, d) +#define __sanitizer_syscall_post_lgetxattr(res, a, b, c, d) +#define __sanitizer_syscall_post_newfstatat(res, a, b, c, d) +#define __sanitizer_syscall_post_openat(res, a, b, c, d) +#define __sanitizer_syscall_post_pread64(res, a, b, c, d) +#define __sanitizer_syscall_post_ptrace(res, a, b, c, d) +#define __sanitizer_syscall_post_pwrite64(res, a, b, c, d) +#define __sanitizer_syscall_post_quotactl(res, a, b, c, d) +#define __sanitizer_syscall_post_rt_sigaction(res, a, b, c, d) +#define __sanitizer_syscall_post_rt_sigprocmask(res, a, b, c, d) +#define __sanitizer_syscall_post_socketpair(res, a, b, c, d) +#define __sanitizer_syscall_post_wait4(res, a, b, c, d) + +#define __sanitizer_syscall_post__mremap(res, a, b, c, d, e) +#define __sanitizer_syscall_post_io_getevents(res, a, b, c, d, e) +#define __sanitizer_syscall_post_lsetxattr(res, a, b, c, d, e) +#define __sanitizer_syscall_post_mount(res, a, b, c, d, e) +#define __sanitizer_syscall_post_preadv(res, a, b, c, d, e) +#define __sanitizer_syscall_post_pwritev(res, a, b, c, d, e) +#define __sanitizer_syscall_post_setxattr(res, a, b, c, d, e) + +#define __sanitizer_syscall_post_mmap(res, a, b, c, d, e, f) +#define __sanitizer_syscall_post_move_pages(res, a, b, c, d, e, f) +#define __sanitizer_syscall_post_sendto(res, a, b, c, d, e, f) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // SANITIZER_LINUX_SYSCALL_HOOKS_H diff --git a/compiler-rt/lib/msan/lit_tests/Linux/syscalls.cc b/compiler-rt/lib/msan/lit_tests/Linux/syscalls.cc new file mode 100644 index 000000000000..c12eda39189e --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/Linux/syscalls.cc @@ -0,0 +1,50 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t 2>&1 +// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t 2>&1 + +#include +#include +#include +#include +#include + +#include +#include + +/* Test the presence of __sanitizer_syscall_ in the tool runtime, and general + sanity of their behaviour. */ + +int main(int argc, char *argv[]) { + char buf[1000]; + const int kTen = 10; + memset(buf, 0, sizeof(buf)); + __msan_unpoison(buf, sizeof(buf)); + __sanitizer_syscall_pre_recvmsg(0, buf, 0); + __sanitizer_syscall_pre_rt_sigpending(buf, kTen); + __sanitizer_syscall_pre_getdents(0, buf, kTen); + __sanitizer_syscall_pre_getdents64(0, buf, kTen); + + __msan_unpoison(buf, sizeof(buf)); + __sanitizer_syscall_post_recvmsg(0, 0, buf, 0); + __sanitizer_syscall_post_rt_sigpending(-1, buf, kTen); + __sanitizer_syscall_post_getdents(0, 0, buf, kTen); + __sanitizer_syscall_post_getdents64(0, 0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == -1); + + __msan_unpoison(buf, sizeof(buf)); + __sanitizer_syscall_post_recvmsg(kTen, 0, buf, 0); + + // Tell the kernel that the output struct size is 10 bytes, verify that those + // bytes are unpoisoned, and the next byte is not. + __msan_poison(buf, kTen + 1); + __sanitizer_syscall_post_rt_sigpending(0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); + + __msan_poison(buf, kTen + 1); + __sanitizer_syscall_post_getdents(kTen, 0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); + + __msan_poison(buf, kTen + 1); + __sanitizer_syscall_post_getdents64(kTen, 0, buf, kTen); + assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); + return 0; +} diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index ef1e2d406c00..279c51a1f21b 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -43,7 +43,7 @@ using namespace __msan; do { \ sptr offset = __msan_test_shadow(x, n); \ if (__msan::IsInSymbolizer()) break; \ - if (offset >= 0 && flags()->report_umrs) { \ + if (offset >= 0 && __msan::flags()->report_umrs) { \ GET_CALLER_PC_BP_SP; \ (void)sp; \ Printf("UMR in %s at offset %d inside [%p, +%d) \n", \ @@ -938,6 +938,12 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), do { } while (false) // FIXME #include "sanitizer_common/sanitizer_common_interceptors.inc" +#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s) +#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) +#define COMMON_SYSCALL_POST_READ_RANGE(p, s) +#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s) +#include "sanitizer_common/sanitizer_common_syscalls.inc" + // static void *fast_memset(void *ptr, int c, SIZE_T n) { // hack until we have a really fast internal_memset diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index 4ef258f1c7d2..fb01dba1ec78 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -34,6 +34,7 @@ set(SANITIZER_HEADERS sanitizer_common.h sanitizer_common_interceptors.inc sanitizer_common_interceptors_scanf.inc + sanitizer_common_syscalls.inc sanitizer_flags.h sanitizer_internal_defs.h sanitizer_lfstack.h diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc new file mode 100644 index 000000000000..40cffb47a6f1 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -0,0 +1,102 @@ +//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Common syscalls handlers for tools like AddressSanitizer, +// ThreadSanitizer, MemorySanitizer, etc. +// +// This file should be included into the tool's interceptor file, +// which has to define it's own macros: +// COMMON_SYSCALL_PRE_READ_RANGE +// Called in prehook for regions that will be read by the kernel and +// must be initialized. +// COMMON_SYSCALL_PRE_WRITE_RANGE +// Called in prehook for regions that will be written to by the kernel +// and must be addressable. The actual write range may be smaller than +// reported in the prehook. See POST_WRITE_RANGE. +// COMMON_SYSCALL_POST_READ_RANGE +// Called in posthook for regions that were read by the kernel. Does +// not make much sense. +// COMMON_SYSCALL_POST_WRITE_RANGE +// Called in posthook for regions that were written to by the kernel +// and are now initialized. +//===----------------------------------------------------------------------===// + +#define PRE_SYSCALL(name) \ + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_##name +#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s) +#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) + +#define POST_SYSCALL(name) \ + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_##name +#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s) +#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s) + +// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such). + +extern "C" { + +struct sanitizer_kernel_iovec { + void *iov_base; + unsigned long iov_len; +}; + +struct sanitizer_kernel_msghdr { + void *msg_name; + int msg_namelen; + struct sanitizer_kernel_iovec *msg_iov; + unsigned long msg_iovlen; + void *msg_control; + unsigned long msg_controllen; + unsigned msg_flags; +}; + +PRE_SYSCALL(recvmsg)(int sockfd, struct sanitizer_kernel_msghdr *msg, + int flags) { + PRE_READ(msg, sizeof(*msg)); +} + +POST_SYSCALL(recvmsg)(int res, int sockfd, struct sanitizer_kernel_msghdr *msg, + int flags) { + if (res > 0) + for (unsigned long i = 0; i < msg->msg_iovlen; ++i) + POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); + POST_WRITE(msg->msg_control, msg->msg_controllen); +} + +PRE_SYSCALL(rt_sigpending)(void *p, unsigned long s) { PRE_WRITE(p, s); } + +POST_SYSCALL(rt_sigpending)(int res, void *p, unsigned long s) { + if (res == 0) + POST_WRITE(p, s); +} + +PRE_SYSCALL(getdents)(int fd, void *dirp, int count) { PRE_WRITE(dirp, count); } + +POST_SYSCALL(getdents)(int res, int fd, void *dirp, int count) { + if (res > 0) + POST_WRITE(dirp, res); +} + +PRE_SYSCALL(getdents64)(int fd, void *dirp, int count) { + PRE_WRITE(dirp, count); +} + +POST_SYSCALL(getdents64)(int res, int fd, void *dirp, int count) { + if (res > 0) + POST_WRITE(dirp, res); +} + +} // extern "C" + +#undef PRE_SYSCALL +#undef PRE_READ +#undef PRE_WRITE +#undef POST_SYSCALL +#undef POST_READ +#undef POST_WRITE