| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 1 | //===-- ubsan_init.cc -----------------------------------------------------===// | 
|  | 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 | // Initialization of UBSan runtime. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "ubsan_init.h" | 
|  | 15 | #include "ubsan_flags.h" | 
|  | 16 | #include "sanitizer_common/sanitizer_common.h" | 
|  | 17 | #include "sanitizer_common/sanitizer_libc.h" | 
| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 18 | #include "sanitizer_common/sanitizer_mutex.h" | 
| Alexey Samsonov | ff24fd2 | 2014-08-05 01:24:22 +0000 | [diff] [blame] | 19 | #include "sanitizer_common/sanitizer_suppressions.h" | 
| Alexey Samsonov | e87e5ce | 2014-07-26 01:41:45 +0000 | [diff] [blame] | 20 | #include "sanitizer_common/sanitizer_symbolizer.h" | 
| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 21 |  | 
|  | 22 | using namespace __ubsan; | 
|  | 23 |  | 
|  | 24 | static bool ubsan_inited; | 
|  | 25 |  | 
|  | 26 | void __ubsan::InitIfNecessary() { | 
|  | 27 | #if !SANITIZER_CAN_USE_PREINIT_ARRAY | 
|  | 28 | // No need to lock mutex if we're initializing from preinit array. | 
|  | 29 | static StaticSpinMutex init_mu; | 
|  | 30 | SpinMutexLock l(&init_mu); | 
|  | 31 | #endif | 
|  | 32 | if (LIKELY(ubsan_inited)) | 
|  | 33 | return; | 
|  | 34 | if (0 == internal_strcmp(SanitizerToolName, "SanitizerTool")) { | 
| Alexey Samsonov | 74f07ed | 2014-09-12 01:26:57 +0000 | [diff] [blame^] | 35 | // WARNING: If this condition holds, then either UBSan runs in a standalone | 
|  | 36 | // mode, or initializer for another sanitizer hasn't run yet. In a latter | 
|  | 37 | // case, another sanitizer will overwrite "SanitizerToolName" and reparse | 
|  | 38 | // common flags. It means, that we are not allowed to *use* common flags | 
|  | 39 | // in this function. | 
| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 40 | SanitizerToolName = "UndefinedBehaviorSanitizer"; | 
| Alexey Samsonov | 74f07ed | 2014-09-12 01:26:57 +0000 | [diff] [blame^] | 41 | InitializeCommonFlags(); | 
| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 42 | } | 
| Alexey Samsonov | 74f07ed | 2014-09-12 01:26:57 +0000 | [diff] [blame^] | 43 | // Initialize UBSan-specific flags. | 
| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 44 | InitializeFlags(); | 
| Alexey Samsonov | ff24fd2 | 2014-08-05 01:24:22 +0000 | [diff] [blame] | 45 | SuppressionContext::InitIfNecessary(); | 
| Alexey Samsonov | 6eb53d6 | 2014-07-25 22:24:34 +0000 | [diff] [blame] | 46 | ubsan_inited = true; | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | #if SANITIZER_CAN_USE_PREINIT_ARRAY | 
|  | 50 | __attribute__((section(".preinit_array"), used)) | 
|  | 51 | void (*__local_ubsan_preinit)(void) = __ubsan::InitIfNecessary; | 
|  | 52 | #else | 
|  | 53 | // Use a dynamic initializer. | 
|  | 54 | class UbsanInitializer { | 
|  | 55 | public: | 
|  | 56 | UbsanInitializer() { | 
|  | 57 | InitIfNecessary(); | 
|  | 58 | } | 
|  | 59 | }; | 
|  | 60 | static UbsanInitializer ubsan_initializer; | 
|  | 61 | #endif  // SANITIZER_CAN_USE_PREINIT_ARRAY |