27
27
#include " sanitizer_common/sanitizer_placement_new.h"
28
28
#include " sanitizer_common/sanitizer_stackdepot.h"
29
29
#include " sanitizer_common/sanitizer_symbolizer.h"
30
+ #include " sanitizer_common/sanitizer_thread_safety.h"
30
31
31
32
namespace __asan {
32
33
@@ -39,7 +40,7 @@ struct GlobalListNode {
39
40
typedef IntrusiveList<GlobalListNode> ListOfGlobals;
40
41
41
42
static Mutex mu_for_globals;
42
- static ListOfGlobals list_of_all_globals;
43
+ static ListOfGlobals list_of_all_globals SANITIZER_GUARDED_BY (mu_for_globals) ;
43
44
44
45
static const int kDynamicInitGlobalsInitialCapacity = 512 ;
45
46
struct DynInitGlobal {
@@ -48,7 +49,8 @@ struct DynInitGlobal {
48
49
};
49
50
typedef InternalMmapVector<DynInitGlobal> VectorOfGlobals;
50
51
// Lazy-initialized and never deleted.
51
- static VectorOfGlobals *dynamic_init_globals;
52
+ static VectorOfGlobals *dynamic_init_globals
53
+ SANITIZER_GUARDED_BY (mu_for_globals);
52
54
53
55
// We want to remember where a certain range of globals was registered.
54
56
struct GlobalRegistrationSite {
@@ -58,7 +60,8 @@ struct GlobalRegistrationSite {
58
60
typedef InternalMmapVector<GlobalRegistrationSite> GlobalRegistrationSiteVector;
59
61
static GlobalRegistrationSiteVector *global_registration_site_vector;
60
62
61
- static ListOfGlobals &GlobalsByIndicator (uptr odr_indicator) {
63
+ static ListOfGlobals &GlobalsByIndicator (uptr odr_indicator)
64
+ SANITIZER_REQUIRES(mu_for_globals) {
62
65
using MapOfGlobals = DenseMap<uptr, ListOfGlobals>;
63
66
64
67
static MapOfGlobals *globals_by_indicator = nullptr ;
@@ -158,7 +161,8 @@ enum GlobalSymbolState {
158
161
// Check ODR violation for given global G via special ODR indicator. We use
159
162
// this method in case compiler instruments global variables through their
160
163
// local aliases.
161
- static void CheckODRViolationViaIndicator (const Global *g) {
164
+ static void CheckODRViolationViaIndicator (const Global *g)
165
+ SANITIZER_REQUIRES(mu_for_globals) {
162
166
// Instrumentation requests to skip ODR check.
163
167
if (g->odr_indicator == UINTPTR_MAX)
164
168
return ;
@@ -185,7 +189,8 @@ static void CheckODRViolationViaIndicator(const Global *g) {
185
189
// Check ODR violation for given global G by checking if it's already poisoned.
186
190
// We use this method in case compiler doesn't use private aliases for global
187
191
// variables.
188
- static void CheckODRViolationViaPoisoning (const Global *g) {
192
+ static void CheckODRViolationViaPoisoning (const Global *g)
193
+ SANITIZER_REQUIRES(mu_for_globals) {
189
194
if (__asan_region_is_poisoned (g->beg , g->size_with_redzone )) {
190
195
// This check may not be enough: if the first global is much larger
191
196
// the entire redzone of the second global may be within the first global.
@@ -223,7 +228,7 @@ static inline bool UseODRIndicator(const Global *g) {
223
228
// Register a global variable.
224
229
// This function may be called more than once for every global
225
230
// so we store the globals in a map.
226
- static void RegisterGlobal (const Global *g) {
231
+ static void RegisterGlobal (const Global *g) SANITIZER_REQUIRES(mu_for_globals) {
227
232
CHECK (AsanInited ());
228
233
if (flags ()->report_globals >= 2 )
229
234
ReportGlobal (*g, " Added" );
@@ -263,7 +268,8 @@ static void RegisterGlobal(const Global *g) {
263
268
}
264
269
}
265
270
266
- static void UnregisterGlobal (const Global *g) {
271
+ static void UnregisterGlobal (const Global *g)
272
+ SANITIZER_REQUIRES(mu_for_globals) {
267
273
CHECK (AsanInited ());
268
274
if (flags ()->report_globals >= 2 )
269
275
ReportGlobal (*g, " Removed" );
@@ -285,8 +291,10 @@ static void UnregisterGlobal(const Global *g) {
285
291
}
286
292
287
293
void StopInitOrderChecking () {
294
+ if (!flags ()->check_initialization_order )
295
+ return ;
288
296
Lock lock (&mu_for_globals);
289
- if (!flags ()-> check_initialization_order || ! dynamic_init_globals)
297
+ if (!dynamic_init_globals)
290
298
return ;
291
299
flags ()->check_initialization_order = false ;
292
300
for (uptr i = 0 , n = dynamic_init_globals->size (); i < n; ++i) {
@@ -451,14 +459,14 @@ void __asan_unregister_globals(__asan_global *globals, uptr n) {
451
459
// poisons all global variables not defined in this TU, so that a dynamic
452
460
// initializer can only touch global variables in the same TU.
453
461
void __asan_before_dynamic_init (const char *module_name) {
454
- if (!flags ()->check_initialization_order ||
455
- !CanPoisonMemory () ||
456
- !dynamic_init_globals)
462
+ if (!flags ()->check_initialization_order || !CanPoisonMemory ())
457
463
return ;
458
464
bool strict_init_order = flags ()->strict_init_order ;
459
465
CHECK (module_name);
460
466
CHECK (AsanInited ());
461
467
Lock lock (&mu_for_globals);
468
+ if (!dynamic_init_globals)
469
+ return ;
462
470
if (flags ()->report_globals >= 3 )
463
471
Printf (" DynInitPoison module: %s\n " , module_name);
464
472
for (uptr i = 0 , n = dynamic_init_globals->size (); i < n; ++i) {
@@ -477,12 +485,12 @@ void __asan_before_dynamic_init(const char *module_name) {
477
485
// all dynamically initialized globals except for those defined in the current
478
486
// TU are poisoned. It simply unpoisons all dynamically initialized globals.
479
487
void __asan_after_dynamic_init () {
480
- if (!flags ()->check_initialization_order ||
481
- !CanPoisonMemory () ||
482
- !dynamic_init_globals)
488
+ if (!flags ()->check_initialization_order || !CanPoisonMemory ())
483
489
return ;
484
490
CHECK (AsanInited ());
485
491
Lock lock (&mu_for_globals);
492
+ if (!dynamic_init_globals)
493
+ return ;
486
494
// FIXME: Optionally report that we're unpoisoning globals from a module.
487
495
for (uptr i = 0 , n = dynamic_init_globals->size (); i < n; ++i) {
488
496
DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
0 commit comments