1276789Sdim//===-- ubsan_init.cc -----------------------------------------------------===//
2276789Sdim//
3276789Sdim//                     The LLVM Compiler Infrastructure
4276789Sdim//
5276789Sdim// This file is distributed under the University of Illinois Open Source
6276789Sdim// License. See LICENSE.TXT for details.
7276789Sdim//
8276789Sdim//===----------------------------------------------------------------------===//
9276789Sdim//
10276789Sdim// Initialization of UBSan runtime.
11276789Sdim//
12276789Sdim//===----------------------------------------------------------------------===//
13276789Sdim
14288943Sdim#include "ubsan_platform.h"
15288943Sdim#if CAN_SANITIZE_UB
16280031Sdim#include "ubsan_diag.h"
17276789Sdim#include "ubsan_init.h"
18276789Sdim#include "ubsan_flags.h"
19276789Sdim#include "sanitizer_common/sanitizer_common.h"
20276789Sdim#include "sanitizer_common/sanitizer_libc.h"
21276789Sdim#include "sanitizer_common/sanitizer_mutex.h"
22276789Sdim#include "sanitizer_common/sanitizer_symbolizer.h"
23276789Sdim
24276789Sdimusing namespace __ubsan;
25276789Sdim
26288943Sdimstatic enum {
27288943Sdim  UBSAN_MODE_UNKNOWN = 0,
28288943Sdim  UBSAN_MODE_STANDALONE,
29288943Sdim  UBSAN_MODE_PLUGIN
30288943Sdim} ubsan_mode;
31288943Sdimstatic StaticSpinMutex ubsan_init_mu;
32276789Sdim
33288943Sdimstatic void CommonInit() {
34280031Sdim  InitializeSuppressions();
35288943Sdim}
36288943Sdim
37288943Sdimstatic void CommonStandaloneInit() {
38288943Sdim  SanitizerToolName = "UndefinedBehaviorSanitizer";
39288943Sdim  InitializeFlags();
40288943Sdim  CacheBinaryName();
41288943Sdim  __sanitizer_set_report_path(common_flags()->log_path);
42280031Sdim  InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
43288943Sdim  CommonInit();
44288943Sdim  ubsan_mode = UBSAN_MODE_STANDALONE;
45276789Sdim}
46276789Sdim
47288943Sdimvoid __ubsan::InitAsStandalone() {
48288943Sdim  if (SANITIZER_CAN_USE_PREINIT_ARRAY) {
49288943Sdim    CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode);
50288943Sdim    CommonStandaloneInit();
51288943Sdim    return;
52276789Sdim  }
53288943Sdim  SpinMutexLock l(&ubsan_init_mu);
54288943Sdim  CHECK_NE(UBSAN_MODE_PLUGIN, ubsan_mode);
55288943Sdim  if (ubsan_mode == UBSAN_MODE_UNKNOWN)
56288943Sdim    CommonStandaloneInit();
57288943Sdim}
58288943Sdim
59288943Sdimvoid __ubsan::InitAsStandaloneIfNecessary() {
60288943Sdim  if (SANITIZER_CAN_USE_PREINIT_ARRAY) {
61288943Sdim    CHECK_NE(UBSAN_MODE_UNKNOWN, ubsan_mode);
62288943Sdim    return;
63288943Sdim  }
64288943Sdim  SpinMutexLock l(&ubsan_init_mu);
65288943Sdim  if (ubsan_mode == UBSAN_MODE_UNKNOWN)
66288943Sdim    CommonStandaloneInit();
67288943Sdim}
68288943Sdim
69288943Sdimvoid __ubsan::InitAsPlugin() {
70288943Sdim#if !SANITIZER_CAN_USE_PREINIT_ARRAY
71288943Sdim  SpinMutexLock l(&ubsan_init_mu);
72288943Sdim#endif
73288943Sdim  CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode);
74288943Sdim  CommonInit();
75288943Sdim  ubsan_mode = UBSAN_MODE_PLUGIN;
76288943Sdim}
77288943Sdim
78288943Sdim#endif  // CAN_SANITIZE_UB
79