asan_globals.cc revision 53177247698bfba075f2d5b255a447fc3ced6976
1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- asan_globals.cc ---------------------------------------------------===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Handle globals.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h"
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h"
161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h"
177e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov#include "asan_poisoning.h"
18e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov#include "asan_report.h"
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h"
201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h"
211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread.h"
227e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov#include "sanitizer_common/sanitizer_common.h"
23f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukov#include "sanitizer_common/sanitizer_mutex.h"
247e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov#include "sanitizer_common/sanitizer_placement_new.h"
251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanytypedef __asan_global Global;
291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
30b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryanystruct ListOfGlobals {
31b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  const Global *g;
32b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  ListOfGlobals *next;
33b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany};
34b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany
35f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukovstatic BlockingMutex mu_for_globals(LINKER_INITIALIZED);
36947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic LowLevelAllocator allocator_for_globals;
373945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryanystatic ListOfGlobals *list_of_all_globals;
381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
397e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonovstatic const int kDynamicInitGlobalsInitialCapacity = 512;
40dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonovstruct DynInitGlobal {
41dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov  Global g;
42dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov  bool initialized;
43dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov};
44a64d4359902f1f64992aedfe10d8882ae7c66f40Alexey Samsonovtypedef InternalMmapVector<DynInitGlobal> VectorOfGlobals;
457e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov// Lazy-initialized and never deleted.
467e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonovstatic VectorOfGlobals *dynamic_init_globals;
477e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov
48abfdbdf5bc7e9d202652fe061acd20c14a4d22f4Timur IskhodzhanovALWAYS_INLINE void PoisonShadowForGlobal(const Global *g, u8 value) {
497e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  FastPoisonShadow(g->beg, g->size_with_redzone, value);
507e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov}
517e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov
52abfdbdf5bc7e9d202652fe061acd20c14a4d22f4Timur IskhodzhanovALWAYS_INLINE void PoisonRedZones(const Global &g) {
53a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany  uptr aligned_size = RoundUpTo(g.size, SHADOW_GRANULARITY);
547e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  FastPoisonShadow(g.beg + aligned_size, g.size_with_redzone - aligned_size,
557e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov                   kAsanGlobalRedzoneMagic);
56a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany  if (g.size != aligned_size) {
577e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    FastPoisonShadowPartialRightRedzone(
58a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany        g.beg + RoundDownTo(g.size, SHADOW_GRANULARITY),
59a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany        g.size % SHADOW_GRANULARITY,
60a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany        SHADOW_GRANULARITY,
61a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany        kAsanGlobalRedzoneMagic);
621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
6505e16a028d26503153a8fe512a500676cad66031Alexey Samsonovstatic void ReportGlobal(const Global &g, const char *prefix) {
6605e16a028d26503153a8fe512a500676cad66031Alexey Samsonov  Report("%s Global: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n",
6705e16a028d26503153a8fe512a500676cad66031Alexey Samsonov         prefix, (void*)g.beg, g.size, g.size_with_redzone, g.name,
6805e16a028d26503153a8fe512a500676cad66031Alexey Samsonov         g.module_name, g.has_dynamic_init);
6905e16a028d26503153a8fe512a500676cad66031Alexey Samsonov}
7005e16a028d26503153a8fe512a500676cad66031Alexey Samsonov
71589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanovbool DescribeAddressIfGlobal(uptr addr, uptr size) {
72cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov  if (!flags()->report_globals) return false;
73f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukov  BlockingMutexLock lock(&mu_for_globals);
741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  bool res = false;
753945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
76b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany    const Global &g = *l->g;
77cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov    if (flags()->report_globals >= 2)
7805e16a028d26503153a8fe512a500676cad66031Alexey Samsonov      ReportGlobal(g, "Search");
79589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov    res |= DescribeAddressRelativeToGlobal(addr, size, g);
801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return res;
821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Register a global variable.
851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This function may be called more than once for every global
861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// so we store the globals in a map.
871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic void RegisterGlobal(const Global *g) {
881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  CHECK(asan_inited);
893945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  if (flags()->report_globals >= 2)
9005e16a028d26503153a8fe512a500676cad66031Alexey Samsonov    ReportGlobal(*g, "Added");
91cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov  CHECK(flags()->report_globals);
921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  CHECK(AddrIsInMem(g->beg));
93b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  CHECK(AddrIsAlignedByGranularity(g->beg));
94c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
957e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  if (flags()->poison_heap)
967e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    PoisonRedZones(*g);
9753177247698bfba075f2d5b255a447fc3ced6976Peter Collingbourne  ListOfGlobals *l = new(allocator_for_globals) ListOfGlobals;
98b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany  l->g = g;
993945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  l->next = list_of_all_globals;
1003945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  list_of_all_globals = l;
1013945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  if (g->has_dynamic_init) {
1027e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    if (dynamic_init_globals == 0) {
10353177247698bfba075f2d5b255a447fc3ced6976Peter Collingbourne      dynamic_init_globals = new(allocator_for_globals)
1047e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov          VectorOfGlobals(kDynamicInitGlobalsInitialCapacity);
1057e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    }
106dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    DynInitGlobal dyn_global = { *g, false };
107dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    dynamic_init_globals->push_back(dyn_global);
1083945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  }
1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
111c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryanystatic void UnregisterGlobal(const Global *g) {
112c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  CHECK(asan_inited);
113cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov  CHECK(flags()->report_globals);
114c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  CHECK(AddrIsInMem(g->beg));
115c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  CHECK(AddrIsAlignedByGranularity(g->beg));
116c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
1177e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  if (flags()->poison_heap)
1187e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    PoisonShadowForGlobal(g, 0);
119c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  // We unpoison the shadow memory for the global but we do not remove it from
120c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  // the list because that would require O(n^2) time with the current list
121c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  // implementation. It might not be worth doing anyway.
122c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany}
123c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany
12446efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonovvoid StopInitOrderChecking() {
12546efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov  BlockingMutexLock lock(&mu_for_globals);
12646efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov  if (!flags()->check_initialization_order || !dynamic_init_globals)
12746efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    return;
12846efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov  flags()->check_initialization_order = false;
12946efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov  for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
13046efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
13146efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    const Global *g = &dyn_g.g;
13246efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    // Unpoison the whole global.
13346efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    PoisonShadowForGlobal(g, 0);
13446efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    // Poison redzones back.
13546efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov    PoisonRedZones(*g);
13646efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov  }
13746efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov}
13846efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov
1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}  // namespace __asan
1401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Interface ---------------- {{{1
1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan;  // NOLINT
1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Register an array of globals.
1459aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryanyvoid __asan_register_globals(__asan_global *globals, uptr n) {
146cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov  if (!flags()->report_globals) return;
147f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukov  BlockingMutexLock lock(&mu_for_globals);
1489aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany  for (uptr i = 0; i < n; i++) {
1491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    RegisterGlobal(&globals[i]);
1501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
1511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
152c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany
153c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany// Unregister an array of globals.
1543945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// We must do this when a shared objects gets dlclosed.
1559aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryanyvoid __asan_unregister_globals(__asan_global *globals, uptr n) {
156cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov  if (!flags()->report_globals) return;
157f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukov  BlockingMutexLock lock(&mu_for_globals);
1589aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany  for (uptr i = 0; i < n; i++) {
159c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany    UnregisterGlobal(&globals[i]);
160c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany  }
161c491061eddb0bb7047470b2746cbcbfe7730b2a9Kostya Serebryany}
1623945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany
1633945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// This method runs immediately prior to dynamic initialization in each TU,
1643945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// when all dynamically initialized globals are unpoisoned.  This method
1653945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// poisons all global variables not defined in this TU, so that a dynamic
1663945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// initializer can only touch global variables in the same TU.
16705e16a028d26503153a8fe512a500676cad66031Alexey Samsonovvoid __asan_before_dynamic_init(const char *module_name) {
1687e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  if (!flags()->check_initialization_order ||
1697e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov      !flags()->poison_heap)
1707e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    return;
171dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov  bool strict_init_order = flags()->strict_init_order;
1727e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  CHECK(dynamic_init_globals);
17305e16a028d26503153a8fe512a500676cad66031Alexey Samsonov  CHECK(module_name);
1747e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  CHECK(asan_inited);
175f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukov  BlockingMutexLock lock(&mu_for_globals);
1767e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  if (flags()->report_globals >= 3)
1777e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    Printf("DynInitPoison module: %s\n", module_name);
1787e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
179dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
180dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    const Global *g = &dyn_g.g;
181dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    if (dyn_g.initialized)
182dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov      continue;
1837e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    if (g->module_name != module_name)
1847e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov      PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);
185dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    else if (!strict_init_order)
186dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov      dyn_g.initialized = true;
1873945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany  }
1883945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany}
1893945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany
1903945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// This method runs immediately after dynamic initialization in each TU, when
1913945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// all dynamically initialized globals except for those defined in the current
1923945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany// TU are poisoned.  It simply unpoisons all dynamically initialized globals.
1933945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryanyvoid __asan_after_dynamic_init() {
1947e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  if (!flags()->check_initialization_order ||
1957e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov      !flags()->poison_heap)
1967e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov    return;
1977e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  CHECK(asan_inited);
198f4f51f2cc6fa936f0c65577f82e6b62989d546eeDmitry Vyukov  BlockingMutexLock lock(&mu_for_globals);
1997e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  // FIXME: Optionally report that we're unpoisoning globals from a module.
2007e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
201dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
202dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    const Global *g = &dyn_g.g;
203dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    if (!dyn_g.initialized) {
204dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov      // Unpoison the whole global.
205dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov      PoisonShadowForGlobal(g, 0);
206dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov      // Poison redzones back.
207dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov      PoisonRedZones(*g);
208dfeef67b23ba92bbee598293164ee20078f633a1Alexey Samsonov    }
2097e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov  }
2103945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany}
211