1353944Sdim//=-- ubsan_signals_standalone.cpp ----------------------------------------===//
2353944Sdim//
3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353944Sdim// See https://llvm.org/LICENSE.txt for license information.
5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353944Sdim//
7353944Sdim//===----------------------------------------------------------------------===//
8353944Sdim//
9353944Sdim// Installs signal handlers and related interceptors for UBSan standalone.
10353944Sdim//
11353944Sdim//===----------------------------------------------------------------------===//
12353944Sdim
13353944Sdim#include "ubsan_platform.h"
14353944Sdim#include "sanitizer_common/sanitizer_platform.h"
15353944Sdim#if CAN_SANITIZE_UB
16353944Sdim#include "interception/interception.h"
17353944Sdim#include "sanitizer_common/sanitizer_stacktrace.h"
18353944Sdim#include "ubsan_diag.h"
19353944Sdim#include "ubsan_init.h"
20353944Sdim
21353944Sdim// Interception of signals breaks too many things on Android.
22353944Sdim// * It requires that ubsan is the first dependency of the main executable for
23353944Sdim// the interceptors to work correctly. This complicates deployment, as it
24353944Sdim// prevents us from enabling ubsan on random platform modules independently.
25353944Sdim// * For this to work with ART VM, ubsan signal handler has to be set after the
26353944Sdim// debuggerd handler, but before the ART handler.
27353944Sdim// * Interceptors don't work at all when ubsan runtime is loaded late, ex. when
28353944Sdim// it is part of an APK that does not use wrap.sh method.
29353944Sdim#if SANITIZER_FUCHSIA || SANITIZER_ANDROID
30353944Sdim
31353944Sdimnamespace __ubsan {
32353944Sdimvoid InitializeDeadlySignals() {}
33353944Sdim}
34353944Sdim
35353944Sdim#else
36353944Sdim
37353944Sdim#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
38353944Sdim#include "sanitizer_common/sanitizer_signal_interceptors.inc"
39353944Sdim
40353944Sdim// TODO(yln): Temporary workaround. Will be removed.
41353944Sdimvoid ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
42353944Sdim                         uptr pc, uptr bp, void *context, bool fast);
43353944Sdim
44353944Sdimnamespace __ubsan {
45353944Sdim
46353944Sdimstatic void OnStackUnwind(const SignalContext &sig, const void *,
47353944Sdim                          BufferedStackTrace *stack) {
48353944Sdim  ubsan_GetStackTrace(stack, kStackTraceMax,
49353944Sdim                      StackTrace::GetNextInstructionPc(sig.pc), sig.bp,
50353944Sdim                      sig.context, common_flags()->fast_unwind_on_fatal);
51353944Sdim}
52353944Sdim
53353944Sdimstatic void UBsanOnDeadlySignal(int signo, void *siginfo, void *context) {
54353944Sdim  HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
55353944Sdim}
56353944Sdim
57353944Sdimstatic bool is_initialized = false;
58353944Sdim
59353944Sdimvoid InitializeDeadlySignals() {
60353944Sdim  if (is_initialized)
61353944Sdim    return;
62353944Sdim  is_initialized = true;
63353944Sdim  InitializeSignalInterceptors();
64353944Sdim  InstallDeadlySignalHandlers(&UBsanOnDeadlySignal);
65353944Sdim}
66353944Sdim
67353944Sdim} // namespace __ubsan
68353944Sdim
69353944Sdim#endif
70353944Sdim
71353944Sdim#endif // CAN_SANITIZE_UB
72