diff options
| author | Alexey Samsonov <vonosmas@gmail.com> | 2014-07-25 22:24:34 +0000 |
|---|---|---|
| committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-07-25 22:24:34 +0000 |
| commit | 6eb53d6460183b51a2cde13b30031572af65d3fe (patch) | |
| tree | e324c3a92b6405f0d49bd9bcf6bcd0d1809a0c3f /compiler-rt/lib/ubsan/ubsan_init.cc | |
| parent | ac4b69e40bfebe502c8bee936539b352b0c14fa2 (diff) | |
| download | bcm5719-llvm-6eb53d6460183b51a2cde13b30031572af65d3fe.tar.gz bcm5719-llvm-6eb53d6460183b51a2cde13b30031572af65d3fe.zip | |
[UBSan] Call UBSan initialization as early as possible.
Specifically, use .preinit_array initialization on Linux and dynamic global
initializer on another platforms. Historically UBSan didn't have any
initialization code and its runtime was stateless. This is no longer the
case - UBSan relies on some non-trivial functionality from sanitizer_common
(e.g. online symbolization) and is now configurable by runtime flags.
Additionally, we've dropped support for enabling UBSan only for a few shared
objects, so UBSan is now always linked into the main executable, so now
we can use similar initialization as all the rest sanitizers.
llvm-svn: 213983
Diffstat (limited to 'compiler-rt/lib/ubsan/ubsan_init.cc')
| -rw-r--r-- | compiler-rt/lib/ubsan/ubsan_init.cc | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_init.cc b/compiler-rt/lib/ubsan/ubsan_init.cc new file mode 100644 index 00000000000..9cfd42f3d0d --- /dev/null +++ b/compiler-rt/lib/ubsan/ubsan_init.cc @@ -0,0 +1,63 @@ +//===-- ubsan_init.cc -----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Initialization of UBSan runtime. +// +//===----------------------------------------------------------------------===// + +#include "ubsan_init.h" +#include "ubsan_flags.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_mutex.h" + +using namespace __ubsan; + +static bool ubsan_inited; + +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"; + CommonFlags *cf = common_flags(); + SetCommonFlagsDefaults(cf); + cf->print_summary = false; + // Common flags may only be modified via UBSAN_OPTIONS. + ParseCommonFlagsFromString(cf, GetEnv("UBSAN_OPTIONS")); + } + // Initialize UBSan-specific flags. + InitializeFlags(); + ubsan_inited = true; +} + +#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(); + } +}; +static UbsanInitializer ubsan_initializer; +#endif // SANITIZER_CAN_USE_PREINIT_ARRAY |

