asan_rtl.cc revision 128892cb26ee50b0fa2171198c7a919540dcd4e7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- asan_rtl.cc -------------------------------------------------------===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// This file is a part of AddressSanitizer, an address sanity checker.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Main file of the ASan run-time library.
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===//
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "asan_allocator.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_interceptors.h"
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "asan_interface.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_internal.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "asan_lock.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_mapping.h"
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "asan_report.h"
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "asan_stack.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "asan_stats.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "asan_thread.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "asan_thread_registry.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sanitizer_common/sanitizer_atomic.h"
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "sanitizer_common/sanitizer_flags.h"
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "sanitizer_common/sanitizer_libc.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace __sanitizer {
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using namespace __asan;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Die() {
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static atomic_uint32_t num_calls;
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Don't die twice - run a busy loop.
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (1) { }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (flags()->sleep_before_dying) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SleepForSeconds(flags()->sleep_before_dying);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags()->unmap_shadow_on_exit)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (death_callback)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    death_callback();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags()->abort_on_error)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Abort();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Exit(flags()->exitcode);
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
51a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSANITIZER_INTERFACE_ATTRIBUTE
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AsanReport("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n",
54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch             file, line, cond, (uptr)v1, (uptr)v2);
55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  PRINT_CURRENT_STACK();
56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ShowStatsAndAbort();
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}  // namespace __sanitizer
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace __asan {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// -------------------------- Flags ------------------------- {{{1
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMallocContextSize = 30;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static Flags asan_flags;
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Flags *flags() {
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return &asan_flags;
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static void ParseFlagsFromString(Flags *f, const char *str) {
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->quarantine_size, "quarantine_size");
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->symbolize, "symbolize");
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->verbosity, "verbosity");
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->redzone, "redzone");
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CHECK(f->redzone >= 16);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(IsPowerOfTwo(f->redzone));
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->debug, "debug");
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->report_globals, "report_globals");
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->check_initialization_order, "initialization_order");
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CHECK(f->malloc_context_size <= kMallocContextSize);
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->replace_str, "replace_str");
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->replace_intrin, "replace_intrin");
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->replace_cfallocator, "replace_cfallocator");
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free");
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->use_fake_stack, "use_fake_stack");
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size");
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ParseFlag(str, &f->exitcode, "exitcode");
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning");
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying");
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ParseFlag(str, &f->handle_segv, "handle_segv");
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack");
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size");
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit");
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ParseFlag(str, &f->abort_on_error, "abort_on_error");
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ParseFlag(str, &f->atexit, "atexit");
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ParseFlag(str, &f->disable_core, "disable_core");
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern "C" {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SANITIZER_WEAK_ATTRIBUTE
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SANITIZER_INTERFACE_ATTRIBUTE
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* __asan_default_options() { return ""; }
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // extern "C"
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void InitializeFlags(Flags *f, const char *env) {
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  internal_memset(f, 0, sizeof(*f));
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 24 : 1UL << 28;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  f->symbolize = false;
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  f->verbosity = 0;
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->redzone = (ASAN_LOW_MEMORY) ? 64 : 128;
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  f->debug = false;
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  f->report_globals = 1;
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  f->check_initialization_order = true;
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->malloc_context_size = kMallocContextSize;
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->replace_str = true;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  f->replace_intrin = true;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  f->replace_cfallocator = true;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  f->mac_ignore_invalid_free = false;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  f->use_fake_stack = true;
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->max_malloc_fill_size = 0;
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->allow_user_poisoning = true;
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  f->sleep_before_dying = 0;
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  f->handle_segv = ASAN_NEEDS_SEGV;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  f->use_sigaltstack = false;
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->check_malloc_usable_size = true;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  f->unmap_shadow_on_exit = false;
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  f->abort_on_error = false;
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  f->atexit = false;
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->disable_core = (__WORDSIZE == 64);
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  f->strip_path_prefix = "";
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override from user-specified string.
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ParseFlagsFromString(f, __asan_default_options());
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (flags()->verbosity) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Report("Using the defaults from __asan_default_options: %s\n",
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           __asan_default_options());
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override from command line.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParseFlagsFromString(f, env);
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// -------------------------- Globals --------------------- {{{1
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int asan_inited;
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool asan_init_is_running;
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid (*death_callback)(void);
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// -------------------------- Misc ---------------- {{{1
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ShowStatsAndAbort() {
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  __asan_print_accumulated_stats();
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Die();
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ---------------------- mmap -------------------- {{{1
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reserve memory range [beg, end].
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ReserveShadowMemoryRange(uptr beg, uptr end) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK((beg % kPageSize) == 0);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(((end + 1) % kPageSize) == 0);
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uptr size = end - beg + 1;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *res = MmapFixedNoReserve(beg, size);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(res == (void*)beg && "ReserveShadowMemoryRange failed");
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ---------------------- LowLevelAllocator ------------- {{{1
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void *LowLevelAllocator::Allocate(uptr size) {
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK((size & (size - 1)) == 0 && "size must be a power of two");
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (allocated_end_ - allocated_current_ < (sptr)size) {
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uptr size_to_allocate = Max(size, kPageSize);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    allocated_current_ =
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (char*)MmapOrDie(size_to_allocate, __FUNCTION__);
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    allocated_end_ = allocated_current_ + size_to_allocate;
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PoisonShadow((uptr)allocated_current_, size_to_allocate,
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 kAsanInternalHeapMagic);
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(allocated_end_ - allocated_current_ >= (sptr)size);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *res = allocated_current_;
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  allocated_current_ += size;
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return res;
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------- Run-time entry ------------------- {{{1
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// exported functions
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define ASAN_REPORT_ERROR(type, is_write, size)                     \
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)extern "C" NOINLINE INTERFACE_ATTRIBUTE                        \
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void __asan_report_ ## type ## size(uptr addr);                \
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void __asan_report_ ## type ## size(uptr addr) {               \
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GET_CALLER_PC_BP_SP;                                              \
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  __asan_report_error(pc, bp, sp, addr, is_write, size);            \
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASAN_REPORT_ERROR(load, false, 1)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ASAN_REPORT_ERROR(load, false, 2)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ASAN_REPORT_ERROR(load, false, 4)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASAN_REPORT_ERROR(load, false, 8)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASAN_REPORT_ERROR(load, false, 16)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ASAN_REPORT_ERROR(store, true, 1)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ASAN_REPORT_ERROR(store, true, 2)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ASAN_REPORT_ERROR(store, true, 4)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASAN_REPORT_ERROR(store, true, 8)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASAN_REPORT_ERROR(store, true, 16)
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Force the linker to keep the symbols for various ASan interface functions.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We want to keep those in the executable in order to let the instrumented
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dynamic libraries access the symbol even if it is not used by the executable
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// itself. This should help if the build system is removing dead code at link
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// time.
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static NOINLINE void force_interface_symbols() {
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  volatile int fake_condition = 0;  // prevent dead condition elimination.
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // __asan_report_* functions are noreturn, so we need a switch to prevent
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the compiler from removing any of them.
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  switch (fake_condition) {
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case 1: __asan_report_load1(0); break;
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case 2: __asan_report_load2(0); break;
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case 3: __asan_report_load4(0); break;
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case 4: __asan_report_load8(0); break;
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case 5: __asan_report_load16(0); break;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 6: __asan_report_store1(0); break;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 7: __asan_report_store2(0); break;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 8: __asan_report_store4(0); break;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 9: __asan_report_store8(0); break;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case 10: __asan_report_store16(0); break;
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 11: __asan_register_global(0, 0, 0); break;
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 12: __asan_register_globals(0, 0); break;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 13: __asan_unregister_globals(0, 0); break;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 14: __asan_set_death_callback(0); break;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 15: __asan_set_error_report_callback(0); break;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 16: __asan_handle_no_return(); break;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case 17: __asan_address_is_poisoned(0); break;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 18: __asan_get_allocated_size(0); break;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 19: __asan_get_current_allocated_bytes(); break;
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 20: __asan_get_estimated_allocated_size(0); break;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case 21: __asan_get_free_bytes(); break;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 22: __asan_get_heap_size(); break;
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 23: __asan_get_ownership(0); break;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 24: __asan_get_unmapped_bytes(); break;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 25: __asan_poison_memory_region(0, 0); break;
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 26: __asan_unpoison_memory_region(0, 0); break;
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 27: __asan_set_error_exit_code(0); break;
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 28: __asan_stack_free(0, 0, 0); break;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 29: __asan_stack_malloc(0, 0); break;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 30: __asan_set_on_error_callback(0); break;
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 31: __asan_default_options(); break;
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case 32: __asan_before_dynamic_init(0, 0); break;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 33: __asan_after_dynamic_init(); break;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void asan_atexit() {
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AsanPrintf("AddressSanitizer exit stats:\n");
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __asan_print_accumulated_stats();
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace __asan
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// ---------------------- Interface ---------------- {{{1
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing namespace __asan;  // NOLINT
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int NOINLINE __asan_set_error_exit_code(int exit_code) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int old = flags()->exitcode;
268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  flags()->exitcode = exit_code;
269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return old;
270558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
272558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid NOINLINE __asan_handle_no_return() {
273558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  int local_stack;
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CHECK(curr_thread);
276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  uptr top = curr_thread->stack_top();
277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  uptr bottom = ((uptr)&local_stack - kPageSize) & ~(kPageSize-1);
278558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PoisonShadow(bottom, top - bottom, 0);
279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
280558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid NOINLINE __asan_set_death_callback(void (*callback)(void)) {
282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  death_callback = callback;
283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid __asan_init() {
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (asan_inited) return;
287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  asan_init_is_running = true;
288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Make sure we are not statically linked.
290558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  AsanDoesNotSupportStaticLinkage();
291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
292558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Initialize flags.
293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const char *options = GetEnv("ASAN_OPTIONS");
294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  InitializeFlags(flags(), options);
295558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
296558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (flags()->verbosity && options) {
297558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Report("Parsed ASAN_OPTIONS: %s\n", options);
298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (flags()->atexit) {
301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Atexit(asan_atexit);
302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
303558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // interceptors
305558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  InitializeAsanInterceptors();
306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ReplaceSystemMalloc();
308558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ReplaceOperatorsNewAndDelete();
309558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (flags()->verbosity) {
311558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Printf("|| `[%p, %p]` || HighMem    ||\n",
312558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch           (void*)kHighMemBeg, (void*)kHighMemEnd);
313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    Printf("|| `[%p, %p]` || HighShadow ||\n",
314558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch           (void*)kHighShadowBeg, (void*)kHighShadowEnd);
315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("|| `[%p, %p]` || ShadowGap  ||\n",
316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           (void*)kShadowGapBeg, (void*)kShadowGapEnd);
317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("|| `[%p, %p]` || LowShadow  ||\n",
318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           (void*)kLowShadowBeg, (void*)kLowShadowEnd);
319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("|| `[%p, %p]` || LowMem     ||\n",
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)           (void*)kLowMemBeg, (void*)kLowMemEnd);
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Printf("MemToShadow(shadow): %p %p %p %p\n",
322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           (void*)MEM_TO_SHADOW(kLowShadowBeg),
323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           (void*)MEM_TO_SHADOW(kLowShadowEnd),
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)           (void*)MEM_TO_SHADOW(kHighShadowBeg),
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)           (void*)MEM_TO_SHADOW(kHighShadowEnd));
326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("red_zone=%zu\n", (uptr)flags()->redzone);
327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (flags()->disable_core) {
336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DisableCoreDumper();
337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uptr shadow_start = kLowShadowBeg;
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (kLowShadowBeg > 0) shadow_start -= kMmapGranularity;
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  uptr shadow_end = kHighShadowEnd;
342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (MemoryRangeIsAvailable(shadow_start, shadow_end)) {
343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (kLowShadowBeg != kLowShadowEnd) {
344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // mmap the low shadow plus at least one page.
345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd);
346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // mmap the high shadow.
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // protect the gap
350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CHECK(prot == (void*)kShadowGapBeg);
352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  } else {
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Report("Shadow memory range interleaves with an existing memory mapping. "
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           "ASan cannot proceed correctly. ABORTING.\n");
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DumpProcessMap();
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    Die();
357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  InstallSignalHandlers();
360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // should be set to 1 prior to initializing the threads.
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  asan_inited = 1;
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  asan_init_is_running = false;
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  asanThreadRegistry().Init();
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  asanThreadRegistry().GetMain()->ThreadStart();
368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  force_interface_symbols();  // no-op.
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (flags()->verbosity) {
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Report("AddressSanitizer Init done\n");
372c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(ASAN_USE_PREINIT_ARRAY)
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // On Linux, we force __asan_init to be called before anyone else
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // by placing it into .preinit_array section.
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // FIXME: do we have anything like this on Mac?
3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  __attribute__((section(".preinit_array")))
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    typeof(__asan_init) *__asan_preinit =__asan_init;
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#elif defined(_WIN32) && defined(_DLL)
3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // On Windows, when using dynamic CRT (/MD), we can put a pointer
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to __asan_init into the global list of C initializers.
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // See crt0dat.c in the CRT sources for the details.
3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  #pragma section(".CRT$XIB", long, read)  // NOLINT
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  __declspec(allocate(".CRT$XIB")) void (*__asan_preinit)() = __asan_init;
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)