diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp index d413b1ebc9fc0..ef886e3d484ed 100644 --- a/compiler-rt/lib/asan/asan_globals.cpp +++ b/compiler-rt/lib/asan/asan_globals.cpp @@ -21,6 +21,7 @@ #include "asan_suppressions.h" #include "asan_thread.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_list.h" #include "sanitizer_common/sanitizer_mutex.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -30,13 +31,14 @@ namespace __asan { typedef __asan_global Global; -struct ListOfGlobals { - const Global *g; - ListOfGlobals *next; +struct GlobalListNode { + const Global *g = nullptr; + GlobalListNode *next = nullptr; }; +typedef IntrusiveList ListOfGlobals; static Mutex mu_for_globals; -static ListOfGlobals *list_of_all_globals; +static ListOfGlobals list_of_all_globals; static const int kDynamicInitGlobalsInitialCapacity = 512; struct DynInitGlobal { @@ -73,6 +75,10 @@ ALWAYS_INLINE void PoisonRedZones(const Global &g) { const uptr kMinimalDistanceFromAnotherGlobal = 64; +static void AddGlobalToList(ListOfGlobals &list, const Global *g) { + list.push_front(new (GetGlobalLowLevelAllocator()) GlobalListNode{g}); +} + static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) { if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false; if (addr >= g.beg + g.size_with_redzone) return false; @@ -114,8 +120,8 @@ int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites, if (!flags()->report_globals) return 0; Lock lock(&mu_for_globals); int res = 0; - for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { - const Global &g = *l->g; + for (const auto &l : list_of_all_globals) { + const Global &g = *l.g; if (flags()->report_globals >= 2) ReportGlobal(g, "Search"); if (IsAddressNearGlobal(addr, g)) { @@ -149,12 +155,13 @@ static void CheckODRViolationViaIndicator(const Global *g) { } // If *odr_indicator is DEFINED, some module have already registered // externally visible symbol with the same name. This is an ODR violation. - for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { - if (g->odr_indicator == l->g->odr_indicator && - (flags()->detect_odr_violation >= 2 || g->size != l->g->size) && - !IsODRViolationSuppressed(g->name)) - ReportODRViolation(g, FindRegistrationSite(g), - l->g, FindRegistrationSite(l->g)); + for (const auto &l : list_of_all_globals) { + if (g->odr_indicator == l.g->odr_indicator && + (flags()->detect_odr_violation >= 2 || g->size != l.g->size) && + !IsODRViolationSuppressed(g->name)) { + ReportODRViolation(g, FindRegistrationSite(g), l.g, + FindRegistrationSite(l.g)); + } } } @@ -165,12 +172,13 @@ static void CheckODRViolationViaPoisoning(const Global *g) { 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. - for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { - if (g->beg == l->g->beg && - (flags()->detect_odr_violation >= 2 || g->size != l->g->size) && - !IsODRViolationSuppressed(g->name)) - ReportODRViolation(g, FindRegistrationSite(g), - l->g, FindRegistrationSite(l->g)); + for (const auto &l : list_of_all_globals) { + if (g->beg == l.g->beg && + (flags()->detect_odr_violation >= 2 || g->size != l.g->size) && + !IsODRViolationSuppressed(g->name)) { + ReportODRViolation(g, FindRegistrationSite(g), l.g, + FindRegistrationSite(l.g)); + } } } } @@ -225,10 +233,9 @@ static void RegisterGlobal(const Global *g) { } if (CanPoisonMemory()) PoisonRedZones(*g); - ListOfGlobals *l = new (GetGlobalLowLevelAllocator()) ListOfGlobals; - l->g = g; - l->next = list_of_all_globals; - list_of_all_globals = l; + + AddGlobalToList(list_of_all_globals, g); + if (g->has_dynamic_init) { if (!dynamic_init_globals) { dynamic_init_globals = new (GetGlobalLowLevelAllocator()) VectorOfGlobals;