asan_globals.cc revision 947fbd1a073fcd38988c1ec131452e99bb0313f8
127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//===-- asan_globals.cc ---------------------------------------------------===//
227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//                     The LLVM Compiler Infrastructure
427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// This file is distributed under the University of Illinois Open Source
627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// License. See LICENSE.TXT for details.
727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//===----------------------------------------------------------------------===//
927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// This file is a part of AddressSanitizer, an address sanity checker.
1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Handle globals.
1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//===----------------------------------------------------------------------===//
1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "asan_interceptors.h"
1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "asan_interface.h"
1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "asan_internal.h"
172272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi#include "asan_lock.h"
1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "asan_mapping.h"
1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "asan_report.h"
2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "asan_stack.h"
213473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi#include "asan_stats.h"
228635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong#include "asan_thread.h"
233473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshinamespace __asan {
2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshitypedef __asan_global Global;
273473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistruct ListOfGlobals {
2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  const Global *g;
3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  ListOfGlobals *next;
3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi};
3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic AsanLock mu_for_globals(LINKER_INITIALIZED);
343473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimistatic LowLevelAllocator allocator_for_globals;
353473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimistatic ListOfGlobals *list_of_all_globals;
363473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimistatic ListOfGlobals *list_of_dynamic_init_globals;
371608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
383473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimivoid PoisonRedZones(const Global &g)  {
393473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi  uptr shadow_rz_size = kGlobalAndStackRedzone >> SHADOW_SCALE;
4027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(shadow_rz_size == 1 || shadow_rz_size == 2 || shadow_rz_size == 4);
413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  // full right redzone
42e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  uptr g_aligned_size = kGlobalAndStackRedzone *
433473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi      ((g.size + kGlobalAndStackRedzone - 1) / kGlobalAndStackRedzone);
443473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi  PoisonShadow(g.beg + g_aligned_size,
453473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi               kGlobalAndStackRedzone, kAsanGlobalRedzoneMagic);
463473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi  if ((g.size % kGlobalAndStackRedzone) != 0) {
473473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    // partial right redzone
483473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    u64 g_aligned_down_size = kGlobalAndStackRedzone *
493473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi        (g.size / kGlobalAndStackRedzone);
503473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    CHECK(g_aligned_down_size == g_aligned_size - kGlobalAndStackRedzone);
513473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    PoisonShadowPartialRightRedzone(g.beg + g_aligned_down_size,
5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                    g.size % kGlobalAndStackRedzone,
5327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                    kGlobalAndStackRedzone,
54e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi                                    kAsanGlobalRedzoneMagic);
55e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  }
563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block}
5727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
58e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatic uptr GetAlignedSize(uptr size) {
5927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  return ((size + kGlobalAndStackRedzone - 1) / kGlobalAndStackRedzone)
6027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      * kGlobalAndStackRedzone;
6127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
63e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimibool DescribeAddressIfGlobal(uptr addr) {
6427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!flags()->report_globals) return false;
6527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  ScopedLock lock(&mu_for_globals);
6627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  bool res = false;
678f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang  for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
688f00151cbe693d52f3e233757c57fab3b6396d21Gloria Wang    const Global &g = *l->g;
692272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    if (flags()->report_globals >= 2)
702272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi      Report("Search Global: beg=%p size=%zu name=%s\n",
712272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi             (void*)g.beg, g.size, (char*)g.name);
722272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    res |= DescribeAddressRelativeToGlobal(addr, g);
732272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  }
742272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  return res;
75e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
76e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi
7727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Register a global variable.
7827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// This function may be called more than once for every global
79e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi// so we store the globals in a map.
80e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimistatic void RegisterGlobal(const Global *g) {
8127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(asan_inited);
8227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (flags()->report_globals >= 2)
8327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    Report("Added Global: beg=%p size=%zu/%zu name=%s dyn.init=%zu\n",
8427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi           (void*)g->beg, g->size, g->size_with_redzone, g->name,
853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block           g->has_dynamic_init);
8627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(flags()->report_globals);
8727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsInMem(g->beg));
8827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->beg));
8927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
9027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  PoisonRedZones(*g);
913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  ListOfGlobals *l =
9227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      (ListOfGlobals*)allocator_for_globals.Allocate(sizeof(ListOfGlobals));
9327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  l->g = g;
9427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  l->next = list_of_all_globals;
9527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  list_of_all_globals = l;
9627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (g->has_dynamic_init) {
973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    l = (ListOfGlobals*)allocator_for_globals.Allocate(sizeof(ListOfGlobals));
9827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    l->g = g;
9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    l->next = list_of_dynamic_init_globals;
10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    list_of_dynamic_init_globals = l;
1013473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi  }
1023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block}
1033473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi
1043473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimistatic void UnregisterGlobal(const Global *g) {
1053473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi  CHECK(asan_inited);
10627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(flags()->report_globals);
1073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  CHECK(AddrIsInMem(g->beg));
10827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->beg));
10927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
11027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  PoisonShadow(g->beg, g->size_with_redzone, 0);
11127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // We unpoison the shadow memory for the global but we do not remove it from
1123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  // the list because that would require O(n^2) time with the current list
11327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // implementation. It might not be worth doing anyway.
11427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
11527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
11627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Poison all shadow memory for a single global.
1173856b090cd04ba5dd4a59a12430ed724d5995909Steve Blockstatic void PoisonGlobalAndRedzones(const Global *g) {
11827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(asan_inited);
11927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(flags()->check_initialization_order);
12027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsInMem(g->beg));
1212272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  CHECK(AddrIsAlignedByGranularity(g->beg));
12227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
12327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (flags()->report_globals >= 3)
1243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    Printf("DynInitPoison  : %s\n", g->name);
12527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  PoisonShadow(g->beg, g->size_with_redzone, kAsanInitializationOrderMagic);
12627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
12727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
12827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic void UnpoisonGlobal(const Global *g) {
1293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  CHECK(asan_inited);
13027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(flags()->check_initialization_order);
13127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsInMem(g->beg));
13227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->beg));
13327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
13427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (flags()->report_globals >= 3)
1353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    Printf("DynInitUnpoison: %s\n", g->name);
13627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  PoisonShadow(g->beg, g->size_with_redzone, 0);
13727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  PoisonRedZones(*g);
13827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
13927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
14027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}  // namespace __asan
1413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
14227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// ---------------------- Interface ---------------- {{{1
14327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiusing namespace __asan;  // NOLINT
14427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1452272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi// Register one global with a default redzone.
14627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshivoid __asan_register_global(uptr addr, uptr size,
1473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                            const char *name) {
148328745b130c1c59e53d68a9a3c71675d3932d34bJames Dong  if (!flags()->report_globals) return;
149328745b130c1c59e53d68a9a3c71675d3932d34bJames Dong  ScopedLock lock(&mu_for_globals);
150328745b130c1c59e53d68a9a3c71675d3932d34bJames Dong  Global *g = (Global *)allocator_for_globals.Allocate(sizeof(Global));
1512272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  g->beg = addr;
15227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  g->size = size;
15327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  g->size_with_redzone = GetAlignedSize(size) + kGlobalAndStackRedzone;
1542272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  g->name = name;
155a2cd44cb5067b4fe98794860690394254d3ac73cGloria Wang  RegisterGlobal(g);
1563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block}
157328745b130c1c59e53d68a9a3c71675d3932d34bJames Dong
158328745b130c1c59e53d68a9a3c71675d3932d34bJames Dong// Register an array of globals.
159328745b130c1c59e53d68a9a3c71675d3932d34bJames Dongvoid __asan_register_globals(__asan_global *globals, uptr n) {
1602272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  if (!flags()->report_globals) return;
16127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  ScopedLock lock(&mu_for_globals);
16227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  for (uptr i = 0; i < n; i++) {
16327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    RegisterGlobal(&globals[i]);
16427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
16527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
1663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Unregister an array of globals.
16827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// We must do this when a shared objects gets dlclosed.
16927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshivoid __asan_unregister_globals(__asan_global *globals, uptr n) {
1702272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  if (!flags()->report_globals) return;
1713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  ScopedLock lock(&mu_for_globals);
1722272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  for (uptr i = 0; i < n; i++) {
17327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    UnregisterGlobal(&globals[i]);
17427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
1752272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi}
1763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1772272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi// This method runs immediately prior to dynamic initialization in each TU,
17827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// when all dynamically initialized globals are unpoisoned.  This method
17927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// poisons all global variables not defined in this TU, so that a dynamic
18027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// initializer can only touch global variables in the same TU.
1813856b090cd04ba5dd4a59a12430ed724d5995909Steve Blockvoid __asan_before_dynamic_init(uptr first_addr, uptr last_addr) {
18227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!flags()->check_initialization_order) return;
18327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(list_of_dynamic_init_globals);
18427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  ScopedLock lock(&mu_for_globals);
18527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  bool from_current_tu = false;
18627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // The list looks like:
1873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  // a => ... => b => last_addr => ... => first_addr => c => ...
18827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // The globals of the current TU reside between last_addr and first_addr.
18927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  for (ListOfGlobals *l = list_of_dynamic_init_globals; l; l = l->next) {
19027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (l->g->beg == last_addr)
19127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      from_current_tu = true;
1923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    if (!from_current_tu)
19327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      PoisonGlobalAndRedzones(l->g);
19427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (l->g->beg == first_addr)
19527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      from_current_tu = false;
19627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
19727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  CHECK(!from_current_tu);
1983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block}
19927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
20027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// This method runs immediately after dynamic initialization in each TU, when
20127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// all dynamically initialized globals except for those defined in the current
20227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// TU are poisoned.  It simply unpoisons all dynamically initialized globals.
2039d2f386dd2885eaffa11fd494ae258bb09fe6397James Dongvoid __asan_after_dynamic_init() {
2043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  if (!flags()->check_initialization_order) return;
2053473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi  ScopedLock lock(&mu_for_globals);
2069d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong  for (ListOfGlobals *l = list_of_dynamic_init_globals; l; l = l->next)
2073473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi    UnpoisonGlobal(l->g);
2083473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi}
2093473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi