diff options
Diffstat (limited to 'contrib/compiler-rt/lib/ubsan/ubsan_init.cc')
-rw-r--r-- | contrib/compiler-rt/lib/ubsan/ubsan_init.cc | 83 |
1 files changed, 49 insertions, 34 deletions
diff --git a/contrib/compiler-rt/lib/ubsan/ubsan_init.cc b/contrib/compiler-rt/lib/ubsan/ubsan_init.cc index 219273d..73398ce 100644 --- a/contrib/compiler-rt/lib/ubsan/ubsan_init.cc +++ b/contrib/compiler-rt/lib/ubsan/ubsan_init.cc @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "ubsan_platform.h" +#if CAN_SANITIZE_UB #include "ubsan_diag.h" #include "ubsan_init.h" #include "ubsan_flags.h" @@ -21,43 +23,56 @@ 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; - bool standalone = false; - 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"; - standalone = true; - } - // Initialize UBSan-specific flags. - InitializeFlags(standalone); +static void CommonInit() { InitializeSuppressions(); +} + +static void CommonStandaloneInit() { + SanitizerToolName = "UndefinedBehaviorSanitizer"; + InitializeFlags(); + CacheBinaryName(); + __sanitizer_set_report_path(common_flags()->log_path); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); - ubsan_inited = true; + 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 |