[llvm-branch-commits] [NFC][asan] Switch from list to DynInitGLobalsByModule (PR #101596)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 1 18:18:13 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Vitaly Buka (vitalybuka)
<details>
<summary>Changes</summary>
Prepare for incremental poisoning, poisoning all
globals for every TU is expensive.
---
Full diff: https://github.com/llvm/llvm-project/pull/101596.diff
1 Files Affected:
- (modified) compiler-rt/lib/asan/asan_globals.cpp (+61-28)
``````````diff
diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp
index cc5308a24fe89..c7dcc47460e83 100644
--- a/compiler-rt/lib/asan/asan_globals.cpp
+++ b/compiler-rt/lib/asan/asan_globals.cpp
@@ -47,8 +47,6 @@ struct DynInitGlobal {
bool initialized = false;
DynInitGlobal *next = nullptr;
};
-typedef IntrusiveList<DynInitGlobal> DynInitGlobals;
-static DynInitGlobals dynamic_init_globals SANITIZER_GUARDED_BY(mu_for_globals);
// We want to remember where a certain range of globals was registered.
struct GlobalRegistrationSite {
@@ -72,6 +70,22 @@ static ListOfGlobals &GlobalsByIndicator(uptr odr_indicator)
return (*globals_by_indicator)[odr_indicator];
}
+using DynInitGLobalsByModule =
+ DenseMap<const char *, IntrusiveList<DynInitGlobal>>;
+
+// TODO: Add a NoDestroy helper, this patter is very common in sanitizers.
+static DynInitGLobalsByModule &DynInitGlobals()
+ SANITIZER_REQUIRES(mu_for_globals) {
+ static DynInitGLobalsByModule *globals_by_module = nullptr;
+ if (!globals_by_module) {
+ alignas(alignof(DynInitGLobalsByModule)) static char
+ placeholder[sizeof(DynInitGLobalsByModule)];
+ globals_by_module = new (placeholder) DynInitGLobalsByModule();
+ }
+
+ return *globals_by_module;
+}
+
ALWAYS_INLINE void PoisonShadowForGlobal(const Global *g, u8 value) {
FastPoisonShadow(g->beg, g->size_with_redzone, value);
}
@@ -257,8 +271,8 @@ static void RegisterGlobal(const Global *g) SANITIZER_REQUIRES(mu_for_globals) {
AddGlobalToList(list_of_all_globals, g);
if (g->has_dynamic_init) {
- dynamic_init_globals.push_back(new (GetGlobalLowLevelAllocator())
- DynInitGlobal{*g, false});
+ DynInitGlobals()[g->module_name].push_back(
+ new (GetGlobalLowLevelAllocator()) DynInitGlobal{*g, false});
}
}
@@ -284,20 +298,42 @@ static void UnregisterGlobal(const Global *g)
}
}
-void StopInitOrderChecking() {
- if (!flags()->check_initialization_order)
- return;
- Lock lock(&mu_for_globals);
- flags()->check_initialization_order = false;
- for (const DynInitGlobal &dyn_g : dynamic_init_globals) {
+static void UnpoisonDynamicGlobals(IntrusiveList<DynInitGlobal> &dyn_globals,
+ bool mark_initialized) {
+ for (auto &dyn_g : dyn_globals) {
const Global *g = &dyn_g.g;
+ if (dyn_g.initialized)
+ continue;
// Unpoison the whole global.
PoisonShadowForGlobal(g, 0);
// Poison redzones back.
PoisonRedZones(*g);
+ if (mark_initialized)
+ dyn_g.initialized = true;
+ }
+}
+
+static void PoisonDynamicGlobals(
+ const IntrusiveList<DynInitGlobal> &dyn_globals) {
+ for (auto &dyn_g : dyn_globals) {
+ const Global *g = &dyn_g.g;
+ if (dyn_g.initialized)
+ continue;
+ PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);
}
}
+void StopInitOrderChecking() {
+ if (!flags()->check_initialization_order)
+ return;
+ Lock lock(&mu_for_globals);
+ flags()->check_initialization_order = false;
+ DynInitGlobals().forEach([&](auto &kv) {
+ UnpoisonDynamicGlobals(kv.second, /*mark_initialized=*/false);
+ return true;
+ });
+}
+
static bool IsASCII(unsigned char c) { return /*0x00 <= c &&*/ c <= 0x7F; }
const char *MaybeDemangleGlobalName(const char *name) {
@@ -458,15 +494,16 @@ void __asan_before_dynamic_init(const char *module_name) {
Lock lock(&mu_for_globals);
if (flags()->report_globals >= 3)
Printf("DynInitPoison module: %s\n", module_name);
- for (DynInitGlobal &dyn_g : dynamic_init_globals) {
- const Global *g = &dyn_g.g;
- if (dyn_g.initialized)
- continue;
- if (g->module_name != module_name)
- PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);
- else if (!strict_init_order)
- dyn_g.initialized = true;
- }
+
+ DynInitGlobals().forEach([&](auto &kv) {
+ if (kv.first != module_name) {
+ PoisonDynamicGlobals(kv.second);
+ } else {
+ UnpoisonDynamicGlobals(kv.second,
+ /*mark_initialized=*/!strict_init_order);
+ }
+ return true;
+ });
}
// This method runs immediately after dynamic initialization in each TU, when
@@ -479,13 +516,9 @@ void __asan_after_dynamic_init() {
Lock lock(&mu_for_globals);
if (flags()->report_globals >= 3)
Printf("DynInitUnpoison\n");
- for (const DynInitGlobal &dyn_g : dynamic_init_globals) {
- const Global *g = &dyn_g.g;
- if (!dyn_g.initialized) {
- // Unpoison the whole global.
- PoisonShadowForGlobal(g, 0);
- // Poison redzones back.
- PoisonRedZones(*g);
- }
- }
+
+ DynInitGlobals().forEach([&](auto &kv) {
+ UnpoisonDynamicGlobals(kv.second, /*mark_initialized=*/false);
+ return true;
+ });
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/101596
More information about the llvm-branch-commits
mailing list