1//===-- sanitizer_signal_interceptors.inc -----------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Signal interceptors for sanitizers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "interception/interception.h"
15#include "sanitizer_common.h"
16#include "sanitizer_internal_defs.h"
17#include "sanitizer_platform_interceptors.h"
18
19using namespace __sanitizer;
20
21#if SANITIZER_NETBSD
22// XXX: Do we need to handle the old __sigaction14 name here too?
23#define sigaction_symname __sigaction_siginfo
24#else
25#define sigaction_symname sigaction
26#endif
27
28#ifndef SIGNAL_INTERCEPTOR_SIGNAL_IMPL
29#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signum, handler) \
30  { return REAL(func)(signum, handler); }
31#endif
32
33#ifndef SIGNAL_INTERCEPTOR_SIGACTION_IMPL
34#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact) \
35  { return REAL(sigaction_symname)(signum, act, oldact); }
36#endif
37
38#if SANITIZER_INTERCEPT_BSD_SIGNAL
39INTERCEPTOR(uptr, bsd_signal, int signum, uptr handler) {
40  if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0;
41  SIGNAL_INTERCEPTOR_SIGNAL_IMPL(bsd_signal, signum, handler);
42}
43#define INIT_BSD_SIGNAL COMMON_INTERCEPT_FUNCTION(bsd_signal)
44#else  // SANITIZER_INTERCEPT_BSD_SIGNAL
45#define INIT_BSD_SIGNAL
46#endif  // SANITIZER_INTERCEPT_BSD_SIGNAL
47
48#if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION
49INTERCEPTOR(uptr, signal, int signum, uptr handler) {
50  if (GetHandleSignalMode(signum) == kHandleSignalExclusive)
51    return (uptr) nullptr;
52  SIGNAL_INTERCEPTOR_SIGNAL_IMPL(signal, signum, handler);
53}
54#define INIT_SIGNAL COMMON_INTERCEPT_FUNCTION(signal)
55
56INTERCEPTOR(int, sigaction_symname, int signum,
57            const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) {
58  if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0;
59  SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact);
60}
61#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction_symname)
62
63namespace __sanitizer {
64int real_sigaction(int signum, const void *act, void *oldact) {
65  return REAL(sigaction_symname)(signum, (const __sanitizer_sigaction *)act,
66                         (__sanitizer_sigaction *)oldact);
67}
68}  // namespace __sanitizer
69#else  // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION
70#define INIT_SIGNAL
71#define INIT_SIGACTION
72// We need to have defined REAL(sigaction) on other systems.
73namespace __sanitizer {
74struct __sanitizer_sigaction;
75}
76DEFINE_REAL(int, sigaction, int signum, const __sanitizer_sigaction *act,
77            __sanitizer_sigaction *oldact)
78#endif  // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION
79
80static void InitializeSignalInterceptors() {
81  static bool was_called_once;
82  CHECK(!was_called_once);
83  was_called_once = true;
84
85  INIT_BSD_SIGNAL;
86  INIT_SIGNAL;
87  INIT_SIGACTION;
88}
89