ubsan_init.cc 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. //===-- ubsan_init.cc -----------------------------------------------------===//
  2. //
  3. // This file is distributed under the University of Illinois Open Source
  4. // License. See LICENSE.TXT for details.
  5. //
  6. //===----------------------------------------------------------------------===//
  7. //
  8. // Initialization of UBSan runtime.
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #include "ubsan_init.h"
  12. #include "ubsan_flags.h"
  13. #include "sanitizer_common/sanitizer_common.h"
  14. #include "sanitizer_common/sanitizer_libc.h"
  15. #include "sanitizer_common/sanitizer_mutex.h"
  16. #include "sanitizer_common/sanitizer_suppressions.h"
  17. #include "sanitizer_common/sanitizer_symbolizer.h"
  18. using namespace __ubsan;
  19. static bool ubsan_inited;
  20. void __ubsan::InitIfNecessary() {
  21. #if !SANITIZER_CAN_USE_PREINIT_ARRAY
  22. // No need to lock mutex if we're initializing from preinit array.
  23. static StaticSpinMutex init_mu;
  24. SpinMutexLock l(&init_mu);
  25. #endif
  26. if (LIKELY(ubsan_inited))
  27. return;
  28. if (0 == internal_strcmp(SanitizerToolName, "SanitizerTool")) {
  29. // WARNING: If this condition holds, then either UBSan runs in a standalone
  30. // mode, or initializer for another sanitizer hasn't run yet. In a latter
  31. // case, another sanitizer will overwrite "SanitizerToolName" and reparse
  32. // common flags. It means, that we are not allowed to *use* common flags
  33. // in this function.
  34. SanitizerToolName = "UndefinedBehaviorSanitizer";
  35. InitializeCommonFlags();
  36. }
  37. // Initialize UBSan-specific flags.
  38. InitializeFlags();
  39. SuppressionContext::InitIfNecessary();
  40. ubsan_inited = true;
  41. }
  42. #if SANITIZER_CAN_USE_PREINIT_ARRAY
  43. __attribute__((section(".preinit_array"), used))
  44. void (*__local_ubsan_preinit)(void) = __ubsan::InitIfNecessary;
  45. #else
  46. // Use a dynamic initializer.
  47. class UbsanInitializer {
  48. public:
  49. UbsanInitializer() {
  50. InitIfNecessary();
  51. }
  52. };
  53. static UbsanInitializer ubsan_initializer;
  54. #endif // SANITIZER_CAN_USE_PREINIT_ARRAY