diff options
Diffstat (limited to 'libsanitizer/ubsan/ubsan_init.cc')
-rw-r--r-- | libsanitizer/ubsan/ubsan_init.cc | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/libsanitizer/ubsan/ubsan_init.cc b/libsanitizer/ubsan/ubsan_init.cc index f28fc811f50..5da4122c07a 100644 --- a/libsanitizer/ubsan/ubsan_init.cc +++ b/libsanitizer/ubsan/ubsan_init.cc @@ -9,51 +9,68 @@ // //===----------------------------------------------------------------------===// +#include "ubsan_platform.h" +#if CAN_SANITIZE_UB +#include "ubsan_diag.h" #include "ubsan_init.h" #include "ubsan_flags.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_mutex.h" -#include "sanitizer_common/sanitizer_suppressions.h" #include "sanitizer_common/sanitizer_symbolizer.h" using namespace __ubsan; -static bool ubsan_inited; +static enum { + UBSAN_MODE_UNKNOWN = 0, + UBSAN_MODE_STANDALONE, + UBSAN_MODE_PLUGIN +} ubsan_mode; +static StaticSpinMutex ubsan_init_mu; -void __ubsan::InitIfNecessary() { -#if !SANITIZER_CAN_USE_PREINIT_ARRAY - // No need to lock mutex if we're initializing from preinit array. - static StaticSpinMutex init_mu; - SpinMutexLock l(&init_mu); -#endif - if (LIKELY(ubsan_inited)) - return; - if (0 == internal_strcmp(SanitizerToolName, "SanitizerTool")) { - // WARNING: If this condition holds, then either UBSan runs in a standalone - // mode, or initializer for another sanitizer hasn't run yet. In a latter - // case, another sanitizer will overwrite "SanitizerToolName" and reparse - // common flags. It means, that we are not allowed to *use* common flags - // in this function. - SanitizerToolName = "UndefinedBehaviorSanitizer"; - InitializeCommonFlags(); - } - // Initialize UBSan-specific flags. +static void CommonInit() { + InitializeSuppressions(); +} + +static void CommonStandaloneInit() { + SanitizerToolName = "UndefinedBehaviorSanitizer"; InitializeFlags(); - SuppressionContext::InitIfNecessary(); - ubsan_inited = true; + CacheBinaryName(); + __sanitizer_set_report_path(common_flags()->log_path); + InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); + CommonInit(); + ubsan_mode = UBSAN_MODE_STANDALONE; +} + +void __ubsan::InitAsStandalone() { + if (SANITIZER_CAN_USE_PREINIT_ARRAY) { + CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode); + CommonStandaloneInit(); + return; + } + SpinMutexLock l(&ubsan_init_mu); + CHECK_NE(UBSAN_MODE_PLUGIN, ubsan_mode); + if (ubsan_mode == UBSAN_MODE_UNKNOWN) + CommonStandaloneInit(); } -#if SANITIZER_CAN_USE_PREINIT_ARRAY -__attribute__((section(".preinit_array"), used)) -void (*__local_ubsan_preinit)(void) = __ubsan::InitIfNecessary; -#else -// Use a dynamic initializer. -class UbsanInitializer { - public: - UbsanInitializer() { - InitIfNecessary(); +void __ubsan::InitAsStandaloneIfNecessary() { + if (SANITIZER_CAN_USE_PREINIT_ARRAY) { + CHECK_NE(UBSAN_MODE_UNKNOWN, ubsan_mode); + return; } -}; -static UbsanInitializer ubsan_initializer; -#endif // SANITIZER_CAN_USE_PREINIT_ARRAY + SpinMutexLock l(&ubsan_init_mu); + if (ubsan_mode == UBSAN_MODE_UNKNOWN) + CommonStandaloneInit(); +} + +void __ubsan::InitAsPlugin() { +#if !SANITIZER_CAN_USE_PREINIT_ARRAY + SpinMutexLock l(&ubsan_init_mu); +#endif + CHECK_EQ(UBSAN_MODE_UNKNOWN, ubsan_mode); + CommonInit(); + ubsan_mode = UBSAN_MODE_PLUGIN; +} + +#endif // CAN_SANITIZE_UB |