From 5f4984db88b7b67539f62d7653b928aeadf91b16 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 15 Oct 2013 12:57:59 +0000 Subject: [PATCH] tsan: move kernel struct definition from sanitizer_linux.h to sanitizer_platform_limits_posix.h git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192695 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_common_syscalls.inc | 5 +++- lib/sanitizer_common/sanitizer_linux.cc | 16 ++++++------- lib/sanitizer_common/sanitizer_linux.h | 28 ++++++---------------- .../sanitizer_platform_limits_posix.h | 14 +++++++++++ .../sanitizer_stoptheworld_linux_libcdep.cc | 23 +++++++++++++----- 5 files changed, 50 insertions(+), 36 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_common_syscalls.inc b/lib/sanitizer_common/sanitizer_common_syscalls.inc index eef79864f..942ffc4c9 100644 --- a/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -37,7 +37,6 @@ #if SANITIZER_LINUX #include "sanitizer_libc.h" -#include "sanitizer_linux.h" #define PRE_SYSCALL(name) \ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_impl_##name @@ -104,6 +103,10 @@ struct sanitizer_kernel_sockaddr { char sa_data[14]; }; +// Real sigset size is always passed as a syscall argument. +// Declare it "void" to catch sizeof(kernel_sigset_t). +typedef void kernel_sigset_t; + static void kernel_write_iovec(const __sanitizer_iovec *iovec, SIZE_T iovlen, SIZE_T maxlen) { for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 9b5620d66..a0600799c 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -602,23 +602,23 @@ uptr internal_sigaltstack(const struct sigaltstack *ss, return internal_syscall(__NR_sigaltstack, ss, oss); } -uptr internal_sigaction(int signum, const kernel_sigaction_t *act, - struct kernel_sigaction_t *oldact) { +uptr internal_sigaction(int signum, const __sanitizer_kernel_sigaction_t *act, + __sanitizer_kernel_sigaction_t *oldact) { return internal_syscall(__NR_rt_sigaction, signum, act, oldact, - sizeof(kernel_sigset_t)); + sizeof(__sanitizer_kernel_sigset_t)); } -uptr internal_sigprocmask(int how, kernel_sigset_t *set, - kernel_sigset_t *oldset) { +uptr internal_sigprocmask(int how, __sanitizer_kernel_sigset_t *set, + __sanitizer_kernel_sigset_t *oldset) { return internal_syscall(__NR_rt_sigprocmask, (uptr)how, &set->sig[0], - &oldset->sig[0], sizeof(kernel_sigset_t)); + &oldset->sig[0], sizeof(__sanitizer_kernel_sigset_t)); } -void internal_sigfillset(kernel_sigset_t *set) { +void internal_sigfillset(__sanitizer_kernel_sigset_t *set) { internal_memset(set, 0xff, sizeof(*set)); } -void internal_sigdelset(kernel_sigset_t *set, int signum) { +void internal_sigdelset(__sanitizer_kernel_sigset_t *set, int signum) { signum -= 1; CHECK_GE(signum, 0); CHECK_LT(signum, sizeof(*set) * 8); diff --git a/lib/sanitizer_common/sanitizer_linux.h b/lib/sanitizer_common/sanitizer_linux.h index 5a642c88f..fae2a337d 100644 --- a/lib/sanitizer_common/sanitizer_linux.h +++ b/lib/sanitizer_common/sanitizer_linux.h @@ -17,41 +17,27 @@ #if SANITIZER_LINUX #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_posix.h" struct link_map; // Opaque type returned by dlopen(). struct sigaltstack; -typedef struct siginfo siginfo_t; namespace __sanitizer { // Dirent structure for getdents(). Note that this structure is different from // the one in , which is used by readdir(). struct linux_dirent; -struct kernel_sigset_t { - u8 sig[FIRST_32_SECOND_64(16, 8)]; -}; - -struct kernel_sigaction_t { - union { - void (*sigaction)(int signo, siginfo_t *info, void *ctx); - void (*handler)(int signo); - }; - unsigned long sa_flags; - void (*sa_restorer)(void); - kernel_sigset_t sa_mask; -}; - // Syscall wrappers. uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5); uptr internal_sigaltstack(const struct sigaltstack* ss, struct sigaltstack* oss); -uptr internal_sigaction(int signum, const kernel_sigaction_t *act, - kernel_sigaction_t *oldact); -uptr internal_sigprocmask(int how, kernel_sigset_t *set, - kernel_sigset_t *oldset); -void internal_sigfillset(kernel_sigset_t *set); -void internal_sigdelset(kernel_sigset_t *set, int signum); +uptr internal_sigaction(int signum, const __sanitizer_kernel_sigaction_t *act, + __sanitizer_kernel_sigaction_t *oldact); +uptr internal_sigprocmask(int how, __sanitizer_kernel_sigset_t *set, + __sanitizer_kernel_sigset_t *oldset); +void internal_sigfillset(__sanitizer_kernel_sigset_t *set); +void internal_sigdelset(__sanitizer_kernel_sigset_t *set, int signum); #ifdef __x86_64__ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 731cab090..41cdefe2c 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -222,6 +222,20 @@ namespace __sanitizer { #endif }; + struct __sanitizer_kernel_sigset_t { + u8 sig[8]; + }; + + struct __sanitizer_kernel_sigaction_t { + union { + void (*sigaction)(int signo, void *info, void *ctx); + void (*handler)(int signo); + }; + unsigned long sa_flags; + void (*sa_restorer)(void); + __sanitizer_kernel_sigset_t sa_mask; + }; + extern uptr sig_ign; extern uptr sig_dfl; extern uptr sa_siginfo; diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index c5578096b..3fb2886e2 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -18,6 +18,8 @@ #include "sanitizer_stoptheworld.h" +#include "sanitizer_platform_limits_posix.h" + #include #include // for CLONE_* definitions #include @@ -31,6 +33,14 @@ #endif #include // for signal-related stuff +#ifdef sa_handler +# undef sa_handler +#endif + +#ifdef sa_sigaction +# undef sa_sigaction +#endif + #include "sanitizer_common.h" #include "sanitizer_libc.h" #include "sanitizer_linux.h" @@ -178,7 +188,7 @@ struct TracerThreadArgument { static DieCallbackType old_die_callback; // Signal handler to wake up suspended threads when the tracer thread dies. -void TracerThreadSignalHandler(int signum, siginfo_t *siginfo, void *) { +void TracerThreadSignalHandler(int signum, void *siginfo, void *) { if (thread_suspender_instance != NULL) { if (signum == SIGABRT) thread_suspender_instance->KillAllThreads(); @@ -236,7 +246,7 @@ static int TracerThread(void* argument) { // the mask we inherited from the caller thread. for (uptr signal_index = 0; signal_index < ARRAY_SIZE(kUnblockedSignals); signal_index++) { - kernel_sigaction_t new_sigaction; + __sanitizer_kernel_sigaction_t new_sigaction; internal_memset(&new_sigaction, 0, sizeof(new_sigaction)); new_sigaction.sigaction = TracerThreadSignalHandler; new_sigaction.sa_flags = SA_ONSTACK | SA_SIGINFO; @@ -286,9 +296,10 @@ class ScopedStackSpaceWithGuard { // We have a limitation on the stack frame size, so some stuff had to be moved // into globals. -static kernel_sigset_t blocked_sigset; -static kernel_sigset_t old_sigset; -static kernel_sigaction_t old_sigactions[ARRAY_SIZE(kUnblockedSignals)]; +static __sanitizer_kernel_sigset_t blocked_sigset; +static __sanitizer_kernel_sigset_t old_sigset; +static __sanitizer_kernel_sigaction_t old_sigactions + [ARRAY_SIZE(kUnblockedSignals)]; class StopTheWorldScope { public: @@ -304,7 +315,7 @@ class StopTheWorldScope { // Remove the signal from the set of blocked signals. internal_sigdelset(&blocked_sigset, kUnblockedSignals[signal_index]); // Install the default handler. - kernel_sigaction_t new_sigaction; + __sanitizer_kernel_sigaction_t new_sigaction; internal_memset(&new_sigaction, 0, sizeof(new_sigaction)); new_sigaction.handler = SIG_DFL; internal_sigfillset(&new_sigaction.sa_mask); -- 2.11.4.GIT