[compiler-rt] [NFC][asan] Switch from list to DynInitGlobalsByModule (PR #101596)
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 3 08:51:24 PDT 2024
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/101596
>From 3d62680d61001ba730cabb98be55a624a9e13cc0 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 1 Aug 2024 18:17:29 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20change?=
=?UTF-8?q?s=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
[skip ci]
---
compiler-rt/lib/asan/asan_globals.cpp | 60 +++++++++----------
.../Helpers/initialization-nobug-extra.cpp | 6 +-
.../asan/TestCases/initialization-nobug.cpp | 19 +++---
3 files changed, 41 insertions(+), 44 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp
index e2ff0a51acf77..cc5308a24fe89 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 {
@@ -39,16 +40,15 @@ struct GlobalListNode {
typedef IntrusiveList<GlobalListNode> ListOfGlobals;
static Mutex mu_for_globals;
-static ListOfGlobals list_of_all_globals;
+static ListOfGlobals list_of_all_globals SANITIZER_GUARDED_BY(mu_for_globals);
-static const int kDynamicInitGlobalsInitialCapacity = 512;
struct DynInitGlobal {
- Global g;
- bool initialized;
+ Global g = {};
+ bool initialized = false;
+ DynInitGlobal *next = nullptr;
};
-typedef InternalMmapVector<DynInitGlobal> VectorOfGlobals;
-// Lazy-initialized and never deleted.
-static VectorOfGlobals *dynamic_init_globals;
+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 {
@@ -58,7 +58,8 @@ struct GlobalRegistrationSite {
typedef InternalMmapVector<GlobalRegistrationSite> GlobalRegistrationSiteVector;
static GlobalRegistrationSiteVector *global_registration_site_vector;
-static ListOfGlobals &GlobalsByIndicator(uptr odr_indicator) {
+static ListOfGlobals &GlobalsByIndicator(uptr odr_indicator)
+ SANITIZER_REQUIRES(mu_for_globals) {
using MapOfGlobals = DenseMap<uptr, ListOfGlobals>;
static MapOfGlobals *globals_by_indicator = nullptr;
@@ -158,7 +159,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;
@@ -185,7 +187,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.
@@ -223,7 +226,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");
@@ -254,16 +257,13 @@ static void RegisterGlobal(const Global *g) {
AddGlobalToList(list_of_all_globals, g);
if (g->has_dynamic_init) {
- if (!dynamic_init_globals) {
- dynamic_init_globals = new (GetGlobalLowLevelAllocator()) VectorOfGlobals;
- dynamic_init_globals->reserve(kDynamicInitGlobalsInitialCapacity);
- }
- DynInitGlobal dyn_global = { *g, false };
- dynamic_init_globals->push_back(dyn_global);
+ dynamic_init_globals.push_back(new (GetGlobalLowLevelAllocator())
+ DynInitGlobal{*g, false});
}
}
-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");
@@ -285,12 +285,11 @@ static void UnregisterGlobal(const Global *g) {
}
void StopInitOrderChecking() {
- Lock lock(&mu_for_globals);
- if (!flags()->check_initialization_order || !dynamic_init_globals)
+ if (!flags()->check_initialization_order)
return;
+ Lock lock(&mu_for_globals);
flags()->check_initialization_order = false;
- for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
- DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
+ for (const DynInitGlobal &dyn_g : dynamic_init_globals) {
const Global *g = &dyn_g.g;
// Unpoison the whole global.
PoisonShadowForGlobal(g, 0);
@@ -451,9 +450,7 @@ 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);
@@ -461,8 +458,7 @@ 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 (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
- DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
+ for (DynInitGlobal &dyn_g : dynamic_init_globals) {
const Global *g = &dyn_g.g;
if (dyn_g.initialized)
continue;
@@ -477,15 +473,13 @@ 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);
- // 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];
+ 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.
diff --git a/compiler-rt/test/asan/TestCases/Helpers/initialization-nobug-extra.cpp b/compiler-rt/test/asan/TestCases/Helpers/initialization-nobug-extra.cpp
index 886165affd760..0ce5359b405d0 100644
--- a/compiler-rt/test/asan/TestCases/Helpers/initialization-nobug-extra.cpp
+++ b/compiler-rt/test/asan/TestCases/Helpers/initialization-nobug-extra.cpp
@@ -1,9 +1,9 @@
// Linker initialized:
int getAB();
-static int ab = getAB();
+int ab = getAB();
// Function local statics:
int countCalls();
-static int one = countCalls();
+int one = countCalls();
// Trivial constructor, non-trivial destructor:
int getStructWithDtorValue();
-static int val = getStructWithDtorValue();
+int val = getStructWithDtorValue();
diff --git a/compiler-rt/test/asan/TestCases/initialization-nobug.cpp b/compiler-rt/test/asan/TestCases/initialization-nobug.cpp
index d4dc855148ad3..6cfef022ae57e 100644
--- a/compiler-rt/test/asan/TestCases/initialization-nobug.cpp
+++ b/compiler-rt/test/asan/TestCases/initialization-nobug.cpp
@@ -1,19 +1,16 @@
// A collection of various initializers which shouldn't trip up initialization
// order checking. If successful, this will just return 0.
-// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-nobug-extra.cpp -o %t
-// RUN: %env_asan_opts=check_initialization_order=true %run %t 2>&1
-// RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-nobug-extra.cpp -o %t
-// RUN: %env_asan_opts=check_initialization_order=true %run %t 2>&1
-// RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-nobug-extra.cpp -o %t
-// RUN: %env_asan_opts=check_initialization_order=true %run %t 2>&1
-// RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-nobug-extra.cpp -o %t
-// RUN: %env_asan_opts=check_initialization_order=true %run %t 2>&1
+// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-nobug-extra.cpp -o %t && %env_asan_opts=check_initialization_order=true:report_globals=3 %run %t 2>&1 | FileCheck %s --implicit-check-not "DynInit"
+// RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-nobug-extra.cpp -o %t && %env_asan_opts=check_initialization_order=true:report_globals=3 %run %t 2>&1 | FileCheck %s --implicit-check-not "DynInit"
+// RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-nobug-extra.cpp -o %t && %env_asan_opts=check_initialization_order=true:report_globals=3 %run %t 2>&1 | FileCheck %s --implicit-check-not "DynInit"
+// RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-nobug-extra.cpp -o %t && %env_asan_opts=check_initialization_order=true:report_globals=3 %run %t 2>&1 | FileCheck %s --implicit-check-not "DynInit"
// Simple access:
// Make sure that accessing a global in the same TU is safe
bool condition = true;
+__attribute__((noinline, weak))
int initializeSameTU() {
return condition ? 0x2a : 052;
}
@@ -46,3 +43,9 @@ StructWithDtor struct_with_dtor;
int getStructWithDtorValue() { return struct_with_dtor.value; }
int main() { return 0; }
+
+
+// CHECK: DynInitPoison module: {{.*}}initialization-nobug.cpp
+// CHECK: DynInitUnpoison
+// CHECK: DynInitPoison module: {{.*}}initialization-nobug-extra.cpp
+// CHECK: DynInitUnpoison
More information about the llvm-commits
mailing list