1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- asan_rtl.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// Main file of the ASan run-time library. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h" 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h" 161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_lock.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h" 19e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov#include "asan_report.h" 201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread.h" 231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread_registry.h" 24d865fecddccebf898ceed24d096fc58fb29a6e57Chandler Carruth#include "sanitizer/asan_interface.h" 25fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov#include "sanitizer_common/sanitizer_atomic.h" 26cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov#include "sanitizer_common/sanitizer_flags.h" 279552db72ce37a9f090be4d9fecfbe75458c6d7bbAlexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 289c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov#include "sanitizer_common/sanitizer_symbolizer.h" 291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3047657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonovnamespace __sanitizer { 3147657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonovusing namespace __asan; 3247657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov 3347657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonovvoid Die() { 34fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov static atomic_uint32_t num_calls; 35fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 3647657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov // Don't die twice - run a busy loop. 3747657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov while (1) { } 3847657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov } 39cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->sleep_before_dying) { 404e21c6bc78bdc36736cd61639a160ea5f725b333Alexey Samsonov Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); 41cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov SleepForSeconds(flags()->sleep_before_dying); 4247657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov } 43cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->unmap_shadow_on_exit) 44a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); 4547657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov if (death_callback) 4647657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov death_callback(); 47cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->abort_on_error) 4847657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov Abort(); 49cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov Exit(flags()->exitcode); 5047657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov} 5147657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov 52ec3b0732a62bd0a52da7bbfc4e227038ccf9372cAlexander PotapenkoSANITIZER_INTERFACE_ATTRIBUTE 5315a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonovvoid CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) { 54283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", 5515a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov file, line, cond, (uptr)v1, (uptr)v2); 568e23d275ec871c16b71f3a98cc475f0db8cb3863Alexander Potapenko // FIXME: check for infinite recursion without a thread-local counter here. 5715a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov PRINT_CURRENT_STACK(); 5815a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov ShowStatsAndAbort(); 5915a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov} 6015a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov 6147657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov} // namespace __sanitizer 6247657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov 631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// -------------------------- Flags ------------------------- {{{1 666d924facc5c979a0d25f484cffcdb51c766ed551Kostya Serebryanystatic const int kDeafultMallocContextSize = 30; 6762f10e7e8b604275ca1c7cc924f32854d04829fbAlexander Potapenko 68cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonovstatic Flags asan_flags; 69cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 70cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey SamsonovFlags *flags() { 71cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov return &asan_flags; 72cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov} 73cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 74cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonovstatic void ParseFlagsFromString(Flags *f, const char *str) { 75cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->quarantine_size, "quarantine_size"); 76cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->symbolize, "symbolize"); 77cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->verbosity, "verbosity"); 78cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->redzone, "redzone"); 79cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov CHECK(f->redzone >= 16); 80cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov CHECK(IsPowerOfTwo(f->redzone)); 81cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 82cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->debug, "debug"); 83cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->report_globals, "report_globals"); 843945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany ParseFlag(str, &f->check_initialization_order, "initialization_order"); 85cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->malloc_context_size, "malloc_context_size"); 8678c7f57e2dd5240b0c2c8bfefd8a776c517f1e22Alexander Potapenko CHECK((uptr)f->malloc_context_size <= kStackTraceMax); 87cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 88cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->replace_str, "replace_str"); 89cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->replace_intrin, "replace_intrin"); 90cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->replace_cfallocator, "replace_cfallocator"); 91cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free"); 92cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->use_fake_stack, "use_fake_stack"); 93cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size"); 94cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->exitcode, "exitcode"); 95cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning"); 96cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying"); 97cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->handle_segv, "handle_segv"); 98cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack"); 99cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size"); 100cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit"); 101cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->abort_on_error, "abort_on_error"); 102cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->atexit, "atexit"); 103cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlag(str, &f->disable_core, "disable_core"); 1044e21c6bc78bdc36736cd61639a160ea5f725b333Alexey Samsonov ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix"); 105eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko ParseFlag(str, &f->allow_reexec, "allow_reexec"); 10671b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history"); 107cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov} 108cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 109b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonovextern "C" { 110c6b8716d9acd202d311a7d9095eeed440bba1ce5Alexey SamsonovSANITIZER_WEAK_ATTRIBUTE 111c6b8716d9acd202d311a7d9095eeed440bba1ce5Alexey SamsonovSANITIZER_INTERFACE_ATTRIBUTE 112c6b8716d9acd202d311a7d9095eeed440bba1ce5Alexey Samsonovconst char* __asan_default_options() { return ""; } 113b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonov} // extern "C" 114b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonov 115cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonovvoid InitializeFlags(Flags *f, const char *env) { 116cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov internal_memset(f, 0, sizeof(*f)); 117cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 1187315c26122cbdfee82f4dbadaedd5c1b85755503Evgeniy Stepanov f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; 119cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->symbolize = false; 120cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->verbosity = 0; 1217ed1d2b699767dd1875994cb625d51a95b44221aAlexey Samsonov f->redzone = (ASAN_LOW_MEMORY) ? 64 : 128; 1227ed1d2b699767dd1875994cb625d51a95b44221aAlexey Samsonov f->debug = false; 123cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->report_globals = 1; 1243945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany f->check_initialization_order = true; 1256d924facc5c979a0d25f484cffcdb51c766ed551Kostya Serebryany f->malloc_context_size = kDeafultMallocContextSize; 126cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->replace_str = true; 127cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->replace_intrin = true; 1287ed1d2b699767dd1875994cb625d51a95b44221aAlexey Samsonov f->replace_cfallocator = true; 1297ed1d2b699767dd1875994cb625d51a95b44221aAlexey Samsonov f->mac_ignore_invalid_free = false; 130cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->use_fake_stack = true; 131cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->max_malloc_fill_size = 0; 132cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; 133cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->allow_user_poisoning = true; 134cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->sleep_before_dying = 0; 135cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->handle_segv = ASAN_NEEDS_SEGV; 136cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->use_sigaltstack = false; 137cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->check_malloc_usable_size = true; 138cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->unmap_shadow_on_exit = false; 139cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->abort_on_error = false; 140cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->atexit = false; 141cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov f->disable_core = (__WORDSIZE == 64); 1424e21c6bc78bdc36736cd61639a160ea5f725b333Alexey Samsonov f->strip_path_prefix = ""; 143eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko f->allow_reexec = true; 14471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov f->print_full_thread_history = true; 145cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 146cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov // Override from user-specified string. 147b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonov ParseFlagsFromString(f, __asan_default_options()); 148b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonov if (flags()->verbosity) { 149b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonov Report("Using the defaults from __asan_default_options: %s\n", 150b750c4c8af128bdd63543f3715f2c147fc3e95bfAlexey Samsonov __asan_default_options()); 151cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov } 152cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov 153cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov // Override from command line. 154cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov ParseFlagsFromString(f, env); 155cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov} 1561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// -------------------------- Globals --------------------- {{{1 1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint asan_inited; 1591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanybool asan_init_is_running; 16047657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonovvoid (*death_callback)(void); 1611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// -------------------------- Misc ---------------- {{{1 1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ShowStatsAndAbort() { 1641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany __asan_print_accumulated_stats(); 16547657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov Die(); 1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- mmap -------------------- {{{1 169a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany// Reserve memory range [beg, end]. 1703f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic void ReserveShadowMemoryRange(uptr beg, uptr end) { 1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CHECK((beg % kPageSize) == 0); 1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CHECK(((end + 1) % kPageSize) == 0); 1733f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr size = end - beg + 1; 174f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov void *res = MmapFixedNoReserve(beg, size); 1755aabcb547a983653a754258d63e27e3790c564d3Alexander Potapenko if (res != (void*)beg) { 1765aabcb547a983653a754258d63e27e3790c564d3Alexander Potapenko Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " 1775aabcb547a983653a754258d63e27e3790c564d3Alexander Potapenko "Perhaps you're using ulimit -v\n", size); 1785aabcb547a983653a754258d63e27e3790c564d3Alexander Potapenko Abort(); 1795aabcb547a983653a754258d63e27e3790c564d3Alexander Potapenko } 1801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 18270e177e29c6f9ac987b65a79f6b4f3ebdabc75ccAlexey Samsonov// --------------- LowLevelAllocateCallbac ---------- {{{1 18370e177e29c6f9ac987b65a79f6b4f3ebdabc75ccAlexey Samsonovstatic void OnLowLevelAllocate(uptr ptr, uptr size) { 18470e177e29c6f9ac987b65a79f6b4f3ebdabc75ccAlexey Samsonov PoisonShadow(ptr, size, kAsanInternalHeapMagic); 185b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany} 186b89567ce41bef82cf92a9c741c78b632c07b2781Kostya Serebryany 1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// -------------------------- Run-time entry ------------------- {{{1 1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// exported functions 18951e75c45a6886455a5bdb91c0951bc77dd2c47a2Kostya Serebryany#define ASAN_REPORT_ERROR(type, is_write, size) \ 1900a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonovextern "C" NOINLINE INTERFACE_ATTRIBUTE \ 1913f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid __asan_report_ ## type ## size(uptr addr); \ 1923f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid __asan_report_ ## type ## size(uptr addr) { \ 1939f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany GET_CALLER_PC_BP_SP; \ 19451e75c45a6886455a5bdb91c0951bc77dd2c47a2Kostya Serebryany __asan_report_error(pc, bp, sp, addr, is_write, size); \ 1951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(load, false, 1) 1981e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(load, false, 2) 1991e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(load, false, 4) 2001e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(load, false, 8) 2011e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(load, false, 16) 2021e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(store, true, 1) 2031e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(store, true, 2) 2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(store, true, 4) 2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(store, true, 8) 2061e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyASAN_REPORT_ERROR(store, true, 16) 2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Force the linker to keep the symbols for various ASan interface functions. 2091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We want to keep those in the executable in order to let the instrumented 2101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dynamic libraries access the symbol even if it is not used by the executable 2111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// itself. This should help if the build system is removing dead code at link 2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// time. 2133fe913558354f76707e2c5584559521399854b79Alexander Potapenkostatic NOINLINE void force_interface_symbols() { 2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany volatile int fake_condition = 0; // prevent dead condition elimination. 215448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko // __asan_report_* functions are noreturn, so we need a switch to prevent 216448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko // the compiler from removing any of them. 217448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko switch (fake_condition) { 218448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 1: __asan_report_load1(0); break; 219448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 2: __asan_report_load2(0); break; 220448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 3: __asan_report_load4(0); break; 221448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 4: __asan_report_load8(0); break; 222448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 5: __asan_report_load16(0); break; 223448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 6: __asan_report_store1(0); break; 224448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 7: __asan_report_store2(0); break; 225448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 8: __asan_report_store4(0); break; 226448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 9: __asan_report_store8(0); break; 227448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 10: __asan_report_store16(0); break; 228448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 11: __asan_register_global(0, 0, 0); break; 229448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 12: __asan_register_globals(0, 0); break; 230448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 13: __asan_unregister_globals(0, 0); break; 231448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 14: __asan_set_death_callback(0); break; 232448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 15: __asan_set_error_report_callback(0); break; 233448fe9a2383222633194754de34e6a3c0351ac68Alexander Potapenko case 16: __asan_handle_no_return(); break; 2345a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 17: __asan_address_is_poisoned(0); break; 2355a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 18: __asan_get_allocated_size(0); break; 2365a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 19: __asan_get_current_allocated_bytes(); break; 2375a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 20: __asan_get_estimated_allocated_size(0); break; 2385a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 21: __asan_get_free_bytes(); break; 2395a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 22: __asan_get_heap_size(); break; 2405a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 23: __asan_get_ownership(0); break; 2415a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 24: __asan_get_unmapped_bytes(); break; 2425a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 25: __asan_poison_memory_region(0, 0); break; 2435a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 26: __asan_unpoison_memory_region(0, 0); break; 2445a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 27: __asan_set_error_exit_code(0); break; 2455a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 28: __asan_stack_free(0, 0, 0); break; 2465a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenko case 29: __asan_stack_malloc(0, 0); break; 247e2430d22c5f9055622a98dc9f885fc73b64cba23Alexey Samsonov case 30: __asan_set_on_error_callback(0); break; 24808d978809ac98095815e5cab80caeb0089f89a1eAlexey Samsonov case 31: __asan_default_options(); break; 249128892cb26ee50b0fa2171198c7a919540dcd4e7Kostya Serebryany case 32: __asan_before_dynamic_init(0, 0); break; 250128892cb26ee50b0fa2171198c7a919540dcd4e7Kostya Serebryany case 33: __asan_after_dynamic_init(); break; 251b21de9e71522a7f9ed31fd92aafe6936873a971cAlexey Samsonov case 34: __asan_malloc_hook(0, 0); break; 252b21de9e71522a7f9ed31fd92aafe6936873a971cAlexey Samsonov case 35: __asan_free_hook(0); break; 253c93d3e2bdfb1ad9cce26a6e8d66764ed97a6d6b4Alexey Samsonov case 36: __asan_set_symbolize_callback(0); break; 2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic void asan_atexit() { 258283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("AddressSanitizer exit stats:\n"); 2591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany __asan_print_accumulated_stats(); 2601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 2631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2644803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// ---------------------- Interface ---------------- {{{1 2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2675a9938d4de74d41cb5f167f751a621dfb7545b64Alexander Potapenkoint NOINLINE __asan_set_error_exit_code(int exit_code) { 268cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov int old = flags()->exitcode; 269cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov flags()->exitcode = exit_code; 2701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return old; 2711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 273dadc45d92ea166174b9b119f7fedc25fd3b538d7Alexander Potapenkovoid NOINLINE __asan_handle_no_return() { 274f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany int local_stack; 275f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 276f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany CHECK(curr_thread); 2773f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr top = curr_thread->stack_top(); 2783f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr bottom = ((uptr)&local_stack - kPageSize) & ~(kPageSize-1); 279f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany PoisonShadow(bottom, top - bottom, 0); 280f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany} 281f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany 2822f3f962de9aeaef47d41bf3d6009bbd0280e2620Alexander Potapenkovoid NOINLINE __asan_set_death_callback(void (*callback)(void)) { 283e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany death_callback = callback; 284e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany} 285e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany 286fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenkovoid __asan_init() { 287fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenko if (asan_inited) return; 28870e177e29c6f9ac987b65a79f6b4f3ebdabc75ccAlexey Samsonov CHECK(!asan_init_is_running && "ASan init calls itself!"); 289fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenko asan_init_is_running = true; 290fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenko 291fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenko // Make sure we are not statically linked. 292fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenko AsanDoesNotSupportStaticLinkage(); 293fca72fd2741372d2e947366277258bff1092e73eAlexander Potapenko 294283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany SetPrintfAndReportCallback(AppendToErrorMessageBuffer); 295283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany 296eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // Initialize flags. This must be done early, because most of the 297eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // initialization steps look at flags(). 2983dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov const char *options = GetEnv("ASAN_OPTIONS"); 299cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov InitializeFlags(flags(), options); 300feb479345ccc947e3e7429b949caa7f89c84a85eAlexander Potapenko 301cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->verbosity && options) { 302feb479345ccc947e3e7429b949caa7f89c84a85eAlexander Potapenko Report("Parsed ASAN_OPTIONS: %s\n", options); 303feb479345ccc947e3e7429b949caa7f89c84a85eAlexander Potapenko } 304feb479345ccc947e3e7429b949caa7f89c84a85eAlexander Potapenko 305eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // Re-exec ourselves if we need to set additional env or command line args. 306eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko MaybeReexec(); 307eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 308947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov // Setup internal allocator callback. 309947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov SetLowLevelAllocateCallback(OnLowLevelAllocate); 310947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov 311cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->atexit) { 312b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonov Atexit(asan_atexit); 3131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // interceptors 3161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany InitializeAsanInterceptors(); 3171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ReplaceSystemMalloc(); 3194d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov ReplaceOperatorsNewAndDelete(); 3201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 321cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->verbosity) { 322e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov Printf("|| `[%p, %p]` || HighMem ||\n", 323e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)kHighMemBeg, (void*)kHighMemEnd); 324e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov Printf("|| `[%p, %p]` || HighShadow ||\n", 325e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)kHighShadowBeg, (void*)kHighShadowEnd); 326e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov Printf("|| `[%p, %p]` || ShadowGap ||\n", 327e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)kShadowGapBeg, (void*)kShadowGapEnd); 328e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov Printf("|| `[%p, %p]` || LowShadow ||\n", 329e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)kLowShadowBeg, (void*)kLowShadowEnd); 330e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov Printf("|| `[%p, %p]` || LowMem ||\n", 331e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)kLowMemBeg, (void*)kLowMemEnd); 3321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Printf("MemToShadow(shadow): %p %p %p %p\n", 333e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)MEM_TO_SHADOW(kLowShadowBeg), 334e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)MEM_TO_SHADOW(kLowShadowEnd), 335e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)MEM_TO_SHADOW(kHighShadowBeg), 336e4309e8141382372465ea065e86d8f946aa99c38Alexey Samsonov (void*)MEM_TO_SHADOW(kHighShadowEnd)); 337cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov Printf("red_zone=%zu\n", (uptr)flags()->redzone); 338cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size); 3391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3403f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE); 3413f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY); 3423f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET); 3431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 3441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 346cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->disable_core) { 347be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov DisableCoreDumper(); 3481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 350dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov uptr shadow_start = kLowShadowBeg; 351dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov if (kLowShadowBeg > 0) shadow_start -= kMmapGranularity; 352dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov uptr shadow_end = kHighShadowEnd; 353dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov if (MemoryRangeIsAvailable(shadow_start, shadow_end)) { 354a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany if (kLowShadowBeg != kLowShadowEnd) { 3553e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov // mmap the low shadow plus at least one page. 3563e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd); 3571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 358a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany // mmap the high shadow. 359a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 3601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // protect the gap 361f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 362a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany CHECK(prot == (void*)kShadowGapBeg); 363c50e83576323d93433086b4c751f1746597a4286Alexander Potapenko } else { 364c50e83576323d93433086b4c751f1746597a4286Alexander Potapenko Report("Shadow memory range interleaves with an existing memory mapping. " 365c50e83576323d93433086b4c751f1746597a4286Alexander Potapenko "ASan cannot proceed correctly. ABORTING.\n"); 366be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov DumpProcessMap(); 36747657ce6cbac2fa93d0fd765c5d2872443b50e87Alexey Samsonov Die(); 3681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 370f03d8afc8b8dd072c4e2884a7475ee28ac5f3f41Alexander Potapenko InstallSignalHandlers(); 3719c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov // Start symbolizer process if necessary. 3729c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov if (flags()->symbolize) { 3739c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov const char *external_symbolizer = GetEnv("ASAN_SYMBOLIZER_PATH"); 3749c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov if (external_symbolizer) { 3759c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov InitializeExternalSymbolizer(external_symbolizer); 3769c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov } 3779c6e5303fa025a73a09cee0766ae403909b1bb8bAlexey Samsonov } 378c93d3e2bdfb1ad9cce26a6e8d66764ed97a6d6b4Alexey Samsonov#ifdef _WIN32 379c93d3e2bdfb1ad9cce26a6e8d66764ed97a6d6b4Alexey Samsonov __asan_set_symbolize_callback(WinSymbolize); 380c93d3e2bdfb1ad9cce26a6e8d66764ed97a6d6b4Alexey Samsonov#endif // _WIN32 381f03d8afc8b8dd072c4e2884a7475ee28ac5f3f41Alexander Potapenko 3821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 3831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // should be set to 1 prior to initializing the threads. 3841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_inited = 1; 3851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_init_is_running = false; 3861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asanThreadRegistry().Init(); 3881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asanThreadRegistry().GetMain()->ThreadStart(); 38951e75c45a6886455a5bdb91c0951bc77dd2c47a2Kostya Serebryany force_interface_symbols(); // no-op. 3901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 391cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->verbosity) { 392d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany Report("AddressSanitizer Init done\n"); 3931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3958bcc6b93abafee3cb15e20fda0f1e1d4967bb80eEvgeniy Stepanov 3968bcc6b93abafee3cb15e20fda0f1e1d4967bb80eEvgeniy Stepanov#if defined(ASAN_USE_PREINIT_ARRAY) 39738ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov // On Linux, we force __asan_init to be called before anyone else 39838ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov // by placing it into .preinit_array section. 39938ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov // FIXME: do we have anything like this on Mac? 40038ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov __attribute__((section(".preinit_array"))) 40138ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov typeof(__asan_init) *__asan_preinit =__asan_init; 40238ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov#elif defined(_WIN32) && defined(_DLL) 40338ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov // On Windows, when using dynamic CRT (/MD), we can put a pointer 40438ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov // to __asan_init into the global list of C initializers. 40538ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov // See crt0dat.c in the CRT sources for the details. 40639c22ee8c3d2d052148a40fd00f1adbb17aabe4dTimur Iskhodzhanov #pragma section(".CRT$XIB", long, read) // NOLINT 40738ed73630902782ba3743529d0cce2ba3014c53eTimur Iskhodzhanov __declspec(allocate(".CRT$XIB")) void (*__asan_preinit)() = __asan_init; 4088bcc6b93abafee3cb15e20fda0f1e1d4967bb80eEvgeniy Stepanov#endif 409