diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp index 0445a1d44f6820..9766488fed0c94 100644 --- a/compiler-rt/lib/asan/asan_globals.cpp +++ b/compiler-rt/lib/asan/asan_globals.cpp @@ -27,6 +27,7 @@ #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_symbolizer.h" +#include "sanitizer_common/sanitizer_thread_safety.h" namespace __asan { @@ -40,8 +41,9 @@ typedef IntrusiveList ListOfGlobals; typedef DenseMap MapOfGlobals; static Mutex mu_for_globals; -static ListOfGlobals list_of_all_globals; -static MapOfGlobals map_of_globals_by_indicator; +static ListOfGlobals list_of_all_globals SANITIZER_GUARDED_BY(mu_for_globals); +static MapOfGlobals map_of_globals_by_indicator + SANITIZER_GUARDED_BY(mu_for_globals); static const int kDynamicInitGlobalsInitialCapacity = 512; struct DynInitGlobal { @@ -50,7 +52,8 @@ struct DynInitGlobal { }; typedef InternalMmapVector VectorOfGlobals; // Lazy-initialized and never deleted. -static VectorOfGlobals *dynamic_init_globals; +static VectorOfGlobals *dynamic_init_globals + SANITIZER_GUARDED_BY(mu_for_globals); // We want to remember where a certain range of globals was registered. struct GlobalRegistrationSite { @@ -147,7 +150,8 @@ enum GlobalSymbolState { // Check ODR violation for given global G via special ODR indicator. We use // this method in case compiler instruments global variables through their // local aliases. -static void CheckODRViolationViaIndicator(const Global *g) { +static void CheckODRViolationViaIndicator(const Global *g) + SANITIZER_REQUIRES(mu_for_globals) { // Instrumentation requests to skip ODR check. if (g->odr_indicator == UINTPTR_MAX) return; @@ -175,7 +179,8 @@ static void CheckODRViolationViaIndicator(const Global *g) { // Check ODR violation for given global G by checking if it's already poisoned. // We use this method in case compiler doesn't use private aliases for global // variables. -static void CheckODRViolationViaPoisoning(const Global *g) { +static void CheckODRViolationViaPoisoning(const Global *g) + SANITIZER_REQUIRES(mu_for_globals) { if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) { // This check may not be enough: if the first global is much larger // the entire redzone of the second global may be within the first global. @@ -213,7 +218,7 @@ static inline bool UseODRIndicator(const Global *g) { // Register a global variable. // This function may be called more than once for every global // so we store the globals in a map. -static void RegisterGlobal(const Global *g) { +static void RegisterGlobal(const Global *g) SANITIZER_REQUIRES(mu_for_globals) { CHECK(AsanInited()); if (flags()->report_globals >= 2) ReportGlobal(*g, "Added"); @@ -253,7 +258,8 @@ static void RegisterGlobal(const Global *g) { } } -static void UnregisterGlobal(const Global *g) { +static void UnregisterGlobal(const Global *g) + SANITIZER_REQUIRES(mu_for_globals) { CHECK(AsanInited()); if (flags()->report_globals >= 2) ReportGlobal(*g, "Removed"); @@ -275,8 +281,10 @@ static void UnregisterGlobal(const Global *g) { } void StopInitOrderChecking() { + if (!flags()->check_initialization_order) + return; Lock lock(&mu_for_globals); - if (!flags()->check_initialization_order || !dynamic_init_globals) + if (!dynamic_init_globals) return; flags()->check_initialization_order = false; for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) { @@ -441,14 +449,14 @@ void __asan_unregister_globals(__asan_global *globals, uptr n) { // poisons all global variables not defined in this TU, so that a dynamic // initializer can only touch global variables in the same TU. void __asan_before_dynamic_init(const char *module_name) { - if (!flags()->check_initialization_order || - !CanPoisonMemory() || - !dynamic_init_globals) + if (!flags()->check_initialization_order || !CanPoisonMemory()) return; bool strict_init_order = flags()->strict_init_order; CHECK(module_name); CHECK(AsanInited()); Lock lock(&mu_for_globals); + if (!dynamic_init_globals) + return; if (flags()->report_globals >= 3) Printf("DynInitPoison module: %s\n", module_name); for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) { @@ -467,12 +475,12 @@ void __asan_before_dynamic_init(const char *module_name) { // all dynamically initialized globals except for those defined in the current // TU are poisoned. It simply unpoisons all dynamically initialized globals. void __asan_after_dynamic_init() { - if (!flags()->check_initialization_order || - !CanPoisonMemory() || - !dynamic_init_globals) + if (!flags()->check_initialization_order || !CanPoisonMemory()) return; CHECK(AsanInited()); Lock lock(&mu_for_globals); + if (!dynamic_init_globals) + return; // FIXME: Optionally report that we're unpoisoning globals from a module. for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) { DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];