summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-09-21 20:59:04 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-09-21 20:59:04 +0000
commit1da6b4d5c8167fde7a74c0cf9245de088a1f059d (patch)
treefcaece7691cc499db70b2b3cd1f7b7a56572ac58 /compiler-rt
parent90901a35cef379a65abff58e8b373fc21298a692 (diff)
downloadbcm5719-llvm-1da6b4d5c8167fde7a74c0cf9245de088a1f059d.tar.gz
bcm5719-llvm-1da6b4d5c8167fde7a74c0cf9245de088a1f059d.zip
tsan: intercept fork syscall
llvm-svn: 191144
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/include/sanitizer/linux_syscall_hooks.h16
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc28
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc62
3 files changed, 84 insertions, 22 deletions
diff --git a/compiler-rt/include/sanitizer/linux_syscall_hooks.h b/compiler-rt/include/sanitizer/linux_syscall_hooks.h
index d5dc00b6e48..9a38070afc1 100644
--- a/compiler-rt/include/sanitizer/linux_syscall_hooks.h
+++ b/compiler-rt/include/sanitizer/linux_syscall_hooks.h
@@ -1826,6 +1826,14 @@
__sanitizer_syscall_post_impl_process_vm_writev( \
res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec), \
(long)(riovcnt), (long)(flags))
+#define __sanitizer_syscall_pre_fork() \
+ __sanitizer_syscall_pre_impl_fork()
+#define __sanitizer_syscall_post_fork(res) \
+ __sanitizer_syscall_post_impl_fork(res)
+#define __sanitizer_syscall_pre_vfork() \
+ __sanitizer_syscall_pre_impl_vfork()
+#define __sanitizer_syscall_post_vfork(res) \
+ __sanitizer_syscall_post_impl_vfork(res)
// And now a few syscalls we don't handle yet.
#define __sanitizer_syscall_pre_afs_syscall(...)
@@ -1843,7 +1851,6 @@
#define __sanitizer_syscall_pre_fanotify_init(...)
#define __sanitizer_syscall_pre_fanotify_mark(...)
#define __sanitizer_syscall_pre_fchown32(...)
-#define __sanitizer_syscall_pre_fork(...)
#define __sanitizer_syscall_pre_ftime(...)
#define __sanitizer_syscall_pre_ftruncate64(...)
#define __sanitizer_syscall_pre_futex(...)
@@ -1907,7 +1914,6 @@
#define __sanitizer_syscall_pre_ugetrlimit(...)
#define __sanitizer_syscall_pre_ulimit(...)
#define __sanitizer_syscall_pre_umount2(...)
-#define __sanitizer_syscall_pre_vfork(...)
#define __sanitizer_syscall_pre_vm86(...)
#define __sanitizer_syscall_pre_vm86old(...)
#define __sanitizer_syscall_pre_vserver(...)
@@ -1927,7 +1933,6 @@
#define __sanitizer_syscall_post_fanotify_init(res, ...)
#define __sanitizer_syscall_post_fanotify_mark(res, ...)
#define __sanitizer_syscall_post_fchown32(res, ...)
-#define __sanitizer_syscall_post_fork(res, ...)
#define __sanitizer_syscall_post_ftime(res, ...)
#define __sanitizer_syscall_post_ftruncate64(res, ...)
#define __sanitizer_syscall_post_futex(res, ...)
@@ -1991,7 +1996,6 @@
#define __sanitizer_syscall_post_ugetrlimit(res, ...)
#define __sanitizer_syscall_post_ulimit(res, ...)
#define __sanitizer_syscall_post_umount2(res, ...)
-#define __sanitizer_syscall_post_vfork(res, ...)
#define __sanitizer_syscall_post_vm86old(res, ...)
#define __sanitizer_syscall_post_vm86(res, ...)
#define __sanitizer_syscall_post_vserver(res, ...)
@@ -3053,6 +3057,10 @@ void __sanitizer_syscall_post_impl_process_vm_writev(long res, long pid,
long lvec, long liovcnt,
long rvec, long riovcnt,
long flags);
+void __sanitizer_syscall_pre_impl_fork();
+void __sanitizer_syscall_post_impl_fork(long res);
+void __sanitizer_syscall_pre_impl_vfork();
+void __sanitizer_syscall_post_impl_vfork(long res);
#ifdef __cplusplus
} // extern "C"
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
index 6aa2ecf0025..942ffc4c9c2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -27,6 +27,10 @@
// and are now initialized.
// COMMON_SYSCALL_FD_CLOSE(fd)
// Called before closing file descriptor fd.
+// COMMON_SYSCALL_PRE_FORK()
+// Called before fork syscall.
+// COMMON_SYSCALL_POST_FORK(long res)
+// Called after fork syscall.
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
@@ -48,6 +52,14 @@
# define COMMON_SYSCALL_FD_CLOSE(fd)
#endif
+#ifndef COMMON_SYSCALL_PRE_FORK
+# define COMMON_SYSCALL_PRE_FORK()
+#endif
+
+#ifndef COMMON_SYSCALL_POST_FORK
+# define COMMON_SYSCALL_POST_FORK(res)
+#endif
+
// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
extern "C" {
@@ -2694,6 +2706,22 @@ POST_SYSCALL(process_vm_writev)(long res, long pid,
if (lvec) kernel_read_iovec(lvec, liovcnt, res);
}
}
+
+PRE_SYSCALL(fork)() {
+ COMMON_SYSCALL_PRE_FORK();
+}
+
+POST_SYSCALL(fork)(long res) {
+ COMMON_SYSCALL_POST_FORK(res);
+}
+
+PRE_SYSCALL(vfork)() {
+ COMMON_SYSCALL_PRE_FORK();
+}
+
+POST_SYSCALL(vfork)(long res) {
+ COMMON_SYSCALL_POST_FORK(res);
+}
} // extern "C"
#undef PRE_SYSCALL
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
index 34178fd722f..0338f5a7734 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
@@ -1792,7 +1792,6 @@ TSAN_INTERCEPTOR(int, munlockall, void) {
TSAN_INTERCEPTOR(int, fork, int fake) {
SCOPED_TSAN_INTERCEPTOR(fork, fake);
- // It's intercepted merely to process pending signals.
int pid = REAL(fork)(fake);
if (pid == 0) {
// child
@@ -1846,28 +1845,51 @@ struct TsanInterceptorContext {
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)
#include "sanitizer_common/sanitizer_common_interceptors.inc"
+#define TSAN_SYSCALL() \
+ ThreadState *thr = cur_thread(); \
+ ScopedSyscall scoped_syscall(thr) \
+/**/
+
+struct ScopedSyscall {
+ ThreadState *thr;
+
+ explicit ScopedSyscall(ThreadState *thr)
+ : thr(thr) {
+ if (thr->in_rtl == 0)
+ Initialize(thr);
+ thr->in_rtl++;
+ }
+
+ ~ScopedSyscall() {
+ thr->in_rtl--;
+ if (thr->in_rtl == 0)
+ ProcessPendingSignals(thr);
+ }
+};
+
static void syscall_access_range(uptr pc, uptr p, uptr s, bool write) {
- ThreadState *thr = cur_thread();
- if (thr->in_rtl == 0)
- Initialize(thr);
- thr->in_rtl++;
+ TSAN_SYSCALL();
MemoryAccessRange(thr, pc, p, s, write);
- thr->in_rtl--;
- if (thr->in_rtl == 0)
- ProcessPendingSignals(thr);
}
static void syscall_fd_close(uptr pc, int fd) {
- if (fd < 0)
- return;
- ThreadState *thr = cur_thread();
- if (thr->in_rtl == 0)
- Initialize(thr);
- thr->in_rtl++;
- FdClose(thr, pc, fd);
- thr->in_rtl--;
- if (thr->in_rtl == 0)
- ProcessPendingSignals(thr);
+ TSAN_SYSCALL();
+ if (fd >= 0)
+ FdClose(thr, pc, fd);
+}
+
+static void syscall_pre_fork(uptr pc) {
+ TSAN_SYSCALL();
+}
+
+static void syscall_post_fork(uptr pc, int res) {
+ TSAN_SYSCALL();
+ if (res == 0) {
+ // child
+ FdOnFork(thr, pc);
+ } else if (res > 0) {
+ // parent
+ }
}
#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) \
@@ -1880,6 +1902,10 @@ static void syscall_fd_close(uptr pc, int fd) {
do { } while (false)
#define COMMON_SYSCALL_FD_CLOSE(fd) \
syscall_fd_close(GET_CALLER_PC(), fd)
+#define COMMON_SYSCALL_PRE_FORK() \
+ syscall_pre_fork(GET_CALLER_PC())
+#define COMMON_SYSCALL_POST_FORK(res) \
+ syscall_post_fork(GET_CALLER_PC(), res)
#include "sanitizer_common/sanitizer_common_syscalls.inc"
namespace __tsan {
OpenPOWER on IntegriCloud