asan_rtl.cc revision b76ea0ce262a97e39fbf443b6aa8768c2c27e7b7
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===-- asan_rtl.cc -------------------------------------------------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file is a part of AddressSanitizer, an address sanity checker. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Main file of the ASan run-time library. 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "asan_allocator.h" 15bdc601b196c48d4cd56a5ceb45d41ae4e87371abKen Dyck#include "asan_interceptors.h" 1649aa7ff1245abd03e6e998e01302df31e4c6f8f6Argyrios Kyrtzidis#include "asan_internal.h" 17980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#include "asan_mapping.h" 18aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#include "asan_poisoning.h" 19b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis#include "asan_report.h" 20e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "asan_stack.h" 212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "asan_stats.h" 2219cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson#include "asan_thread.h" 231b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "sanitizer_common/sanitizer_atomic.h" 24a9376d470ccb0eac74fe09a6b2a18a890f1d17c4Chris Lattner#include "sanitizer_common/sanitizer_flags.h" 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "sanitizer_common/sanitizer_libc.h" 26f5942a44880be26878592eb052b737579349411eBenjamin Kramer#include "sanitizer_common/sanitizer_symbolizer.h" 2785f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson 286fe7c8aa8c7546743ecd0ac0138c2cf5d8155386Nate Begemannamespace __asan { 29f5942a44880be26878592eb052b737579349411eBenjamin Kramer 3029445a0542d128cd7ee587ee52229670b9b54a12Anders Carlssonuptr AsanMappingProfile[kAsanMappingProfileSize]; 3129445a0542d128cd7ee587ee52229670b9b54a12Anders Carlsson 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void AsanDie() { 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer static atomic_uint32_t num_calls; 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Don't die twice - run a busy loop. 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer while (1) { } 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3861710854be2b098428aff5316e64bd34b30fbcb7Chris Lattner if (flags()->sleep_before_dying) { 39444be7366d0a1e172c0290a1ea54c1cb16b5947cDaniel Dunbar Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); 40e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar SleepForSeconds(flags()->sleep_before_dying); 411b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner } 421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (flags()->unmap_shadow_on_exit) { 431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (kMidMemBeg) { 44782fa308a765aeac2acb39c4e697c937ec21185bMike Stump UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); 45083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); 46083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump } else { 471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); 482e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 500f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall if (death_callback) 510f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall death_callback(); 52369a3bd9979cf529eed529aa037de713c213e47dFariborz Jahanian if (flags()->abort_on_error) 531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Abort(); 54e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar internal__exit(flags()->exitcode); 5514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff} 56e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar 57e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbarstatic void AsanCheckFailed(const char *file, int line, const char *cond, 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer u64 v1, u64 v2) { 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer file, line, cond, (uptr)v1, (uptr)v2); 614b05b1dee6cc65ae61d93dab7edff72710f24589Ted Kremenek // FIXME: check for infinite recursion without a thread-local counter here. 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer PRINT_CURRENT_STACK(); 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Die(); 64b26153c2b06934b6d39886cae2a379988d9c3e2bEli Friedman} 65b74668edbc119880eb0a7e563432314432cb775dNuno Lopes 660953e767ff7817f97b3ab20896b229891eeff45bJohn McCall// -------------------------- Flags ------------------------- {{{1 670953e767ff7817f97b3ab20896b229891eeff45bJohn McCallstatic const int kDefaultMallocContextSize = 30; 680953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 690953e767ff7817f97b3ab20896b229891eeff45bJohn McCallFlags asan_flags_dont_use_directly; // use via flags(). 700953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 710953e767ff7817f97b3ab20896b229891eeff45bJohn McCallstatic const char *MaybeCallAsanDefaultOptions() { 720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall return (&__asan_default_options) ? __asan_default_options() : ""; 73b74668edbc119880eb0a7e563432314432cb775dNuno Lopes} 74b74668edbc119880eb0a7e563432314432cb775dNuno Lopes 75b74668edbc119880eb0a7e563432314432cb775dNuno Lopesstatic const char *MaybeUseAsanDefaultOptionsCompileDefiniton() { 76b74668edbc119880eb0a7e563432314432cb775dNuno Lopes#ifdef ASAN_DEFAULT_OPTIONS 77b74668edbc119880eb0a7e563432314432cb775dNuno Lopes// Stringize the macro value. 78b74668edbc119880eb0a7e563432314432cb775dNuno Lopes# define ASAN_STRINGIZE(x) #x 79b74668edbc119880eb0a7e563432314432cb775dNuno Lopes# define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options) 80b74668edbc119880eb0a7e563432314432cb775dNuno Lopes return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS); 81b74668edbc119880eb0a7e563432314432cb775dNuno Lopes#else 82b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar return ""; 83b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar#endif 84b74668edbc119880eb0a7e563432314432cb775dNuno Lopes} 85b74668edbc119880eb0a7e563432314432cb775dNuno Lopes 86b74668edbc119880eb0a7e563432314432cb775dNuno Lopesstatic void ParseFlagsFromString(Flags *f, const char *str) { 87b74668edbc119880eb0a7e563432314432cb775dNuno Lopes ParseCommonFlagsFromString(str); 88b74668edbc119880eb0a7e563432314432cb775dNuno Lopes CHECK((uptr)common_flags()->malloc_context_size <= kStackTraceMax); 89b74668edbc119880eb0a7e563432314432cb775dNuno Lopes 90ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor ParseFlag(str, &f->quarantine_size, "quarantine_size"); 911ae0afaf14b7ce9bed33c1fe51077d01a313434dDouglas Gregor ParseFlag(str, &f->verbosity, "verbosity"); 921ae0afaf14b7ce9bed33c1fe51077d01a313434dDouglas Gregor ParseFlag(str, &f->redzone, "redzone"); 931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CHECK_GE(f->redzone, 16); 941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CHECK(IsPowerOfTwo(f->redzone)); 951ae0afaf14b7ce9bed33c1fe51077d01a313434dDouglas Gregor 961ae0afaf14b7ce9bed33c1fe51077d01a313434dDouglas Gregor ParseFlag(str, &f->debug, "debug"); 97ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor ParseFlag(str, &f->report_globals, "report_globals"); 98ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor ParseFlag(str, &f->check_initialization_order, "check_initialization_order"); 99ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor 100ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor ParseFlag(str, &f->replace_str, "replace_str"); 101b26153c2b06934b6d39886cae2a379988d9c3e2bEli Friedman ParseFlag(str, &f->replace_intrin, "replace_intrin"); 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free"); 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->use_fake_stack, "use_fake_stack"); 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size"); 1052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ParseFlag(str, &f->malloc_fill_byte, "malloc_fill_byte"); 1062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ParseFlag(str, &f->exitcode, "exitcode"); 1072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning"); 1082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying"); 1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->handle_segv, "handle_segv"); 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->allow_user_segv_handler, "allow_user_segv_handler"); 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack"); 1127c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size"); 113dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit"); 1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseFlag(str, &f->abort_on_error, "abort_on_error"); 115dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->print_stats, "print_stats"); 116dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->print_legend, "print_legend"); 117dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->atexit, "atexit"); 118dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->disable_core, "disable_core"); 119c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor ParseFlag(str, &f->allow_reexec, "allow_reexec"); 1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history"); 1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->log_path, "log_path"); 122dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->poison_heap, "poison_heap"); 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch"); 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlag(str, &f->use_stack_depot, "use_stack_depot"); 125dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->strict_memcmp, "strict_memcmp"); 126dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor ParseFlag(str, &f->strict_init_order, "strict_init_order"); 127dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor} 128dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor 129dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregorvoid InitializeFlags(Flags *f, const char *env) { 130dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor CommonFlags *cf = common_flags(); 131dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); 132dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor cf->symbolize = true; 133dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor cf->malloc_context_size = kDefaultMallocContextSize; 1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump cf->fast_unwind_on_fatal = false; 135dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor cf->fast_unwind_on_malloc = true; 1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor cf->strip_path_prefix = ""; 1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor internal_memset(f, 0, sizeof(*f)); 1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; 1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor f->verbosity = 0; 1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->redzone = 16; 1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->debug = false; 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->report_globals = 1; 144e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall f->check_initialization_order = false; 1456b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall f->replace_str = true; 146e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall f->replace_intrin = true; 1476b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall f->mac_ignore_invalid_free = false; 1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->use_fake_stack = true; 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->max_malloc_fill_size = 0x1000; // By default, fill only the first 4K. 1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->malloc_fill_byte = 0xbe; 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump f->allow_user_poisoning = true; 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->sleep_before_dying = 0; 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->handle_segv = ASAN_NEEDS_SEGV; 1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump f->allow_user_segv_handler = false; 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->use_sigaltstack = false; 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->check_malloc_usable_size = true; 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->unmap_shadow_on_exit = false; 15915b91764d08e886391c865c4a444d7b51141c284Eli Friedman f->abort_on_error = false; 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->print_stats = false; 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->print_legend = true; 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->atexit = false; 1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->disable_core = (SANITIZER_WORDSIZE == 64); 1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->allow_reexec = true; 1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->print_full_thread_history = true; 1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->log_path = 0; 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->poison_heap = true; 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Turn off alloc/dealloc mismatch checker on Mac for now. 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // TODO(glider): Fix known issues and enable this back. 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0);; 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->use_stack_depot = true; 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->strict_memcmp = true; 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer f->strict_init_order = false; 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Override from compile definition. 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefiniton()); 1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Override from user-specified string. 1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ParseFlagsFromString(f, MaybeCallAsanDefaultOptions()); 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (flags()->verbosity) { 18164c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis Report("Using the defaults from __asan_default_options: %s\n", 1822df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner MaybeCallAsanDefaultOptions()); 1832df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner } 1842df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner 1852df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner // Override from command line. 1863a2503227c3db04a3619735127483263c1075ef7Chris Lattner ParseFlagsFromString(f, env); 1873a2503227c3db04a3619735127483263c1075ef7Chris Lattner} 1883a2503227c3db04a3619735127483263c1075ef7Chris Lattner 1893a2503227c3db04a3619735127483263c1075ef7Chris Lattner// -------------------------- Globals --------------------- {{{1 19064c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidisint asan_inited; 191f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredithbool asan_init_is_running; 192f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredithvoid (*death_callback)(void); 193f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith 194f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith#if !ASAN_FIXED_MAPPING 195f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredithuptr kHighMemEnd, kMidMemBeg, kMidMemEnd; 196f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith#endif 197f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith 198f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith// -------------------------- Misc ---------------- {{{1 199f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredithvoid ShowStatsAndAbort() { 200f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith __asan_print_accumulated_stats(); 2018e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor Die(); 202898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor} 203898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor 204898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// ---------------------- mmap -------------------- {{{1 205898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// Reserve memory range [beg, end]. 206898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorstatic void ReserveShadowMemoryRange(uptr beg, uptr end) { 207898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor CHECK_EQ((beg % GetPageSizeCached()), 0); 208898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor CHECK_EQ(((end + 1) % GetPageSizeCached()), 0); 209898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor uptr size = end - beg + 1; 2108e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor void *res = MmapFixedNoReserve(beg, size); 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (res != (void*)beg) { 212e89d15944dd3be750a09805ad21222d2fa9321faAnders Carlsson Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " 213e89d15944dd3be750a09805ad21222d2fa9321faAnders Carlsson "Perhaps you're using ulimit -v\n", size); 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Abort(); 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// --------------- LowLevelAllocateCallbac ---------- {{{1 2198e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregorstatic void OnLowLevelAllocate(uptr ptr, uptr size) { 2207e219e47de26346885d667131977bd9ca2d7662aSteve Naroff PoisonShadow(ptr, size, kAsanInternalHeapMagic); 2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 222de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff 223de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff// -------------------------- Run-time entry ------------------- {{{1 224de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff// exported functions 22513dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian#define ASAN_REPORT_ERROR(type, is_write, size) \ 2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpextern "C" NOINLINE INTERFACE_ATTRIBUTE \ 22713dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanianvoid __asan_report_ ## type ## size(uptr addr); \ 228de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroffvoid __asan_report_ ## type ## size(uptr addr) { \ 229de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff GET_CALLER_PC_BP_SP; \ 23013dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian __asan_report_error(pc, bp, sp, addr, is_write, size); \ 23114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff} 232a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek 2331eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpASAN_REPORT_ERROR(load, false, 1) 23433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz JahanianASAN_REPORT_ERROR(load, false, 2) 23533e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz JahanianASAN_REPORT_ERROR(load, false, 4) 2366e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian RedlASAN_REPORT_ERROR(load, false, 8) 2376e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian RedlASAN_REPORT_ERROR(load, false, 16) 2386e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian RedlASAN_REPORT_ERROR(store, true, 1) 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerASAN_REPORT_ERROR(store, true, 2) 2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerASAN_REPORT_ERROR(store, true, 4) 241251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas GregorASAN_REPORT_ERROR(store, true, 8) 242663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas GregorASAN_REPORT_ERROR(store, true, 16) 2437caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor 244663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor#define ASAN_REPORT_ERROR_N(type, is_write) \ 2457caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorextern "C" NOINLINE INTERFACE_ATTRIBUTE \ 2467caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorvoid __asan_report_ ## type ## _n(uptr addr, uptr size); \ 2477caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorvoid __asan_report_ ## type ## _n(uptr addr, uptr size) { \ 2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump GET_CALLER_PC_BP_SP; \ 2497caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor __asan_report_error(pc, bp, sp, addr, is_write, size); \ 2507caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor} 2517caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor 2521eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpASAN_REPORT_ERROR_N(load, false) 253251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas GregorASAN_REPORT_ERROR_N(store, true) 254251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor 2557caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor// Force the linker to keep the symbols for various ASan interface functions. 2567caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor// We want to keep those in the executable in order to let the instrumented 2577caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor// dynamic libraries access the symbol even if it is not used by the executable 2587caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor// itself. This should help if the build system is removing dead code at link 259251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor// time. 260251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregorstatic NOINLINE void force_interface_symbols() { 2617caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor volatile int fake_condition = 0; // prevent dead condition elimination. 2627caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor // __asan_report_* functions are noreturn, so we need a switch to prevent 2637ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall // the compiler from removing any of them. 264ed97649e9574b9d854fa4d6109c9333ae0993554John McCall switch (fake_condition) { 2657ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall case 1: __asan_report_load1(0); break; 266ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 2: __asan_report_load2(0); break; 267ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 3: __asan_report_load4(0); break; 2680d8df780aef1acda5962347a32591efc629b6748Anders Carlsson case 4: __asan_report_load8(0); break; 2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case 5: __asan_report_load16(0); break; 2700d8df780aef1acda5962347a32591efc629b6748Anders Carlsson case 6: __asan_report_store1(0); break; 2710d8df780aef1acda5962347a32591efc629b6748Anders Carlsson case 7: __asan_report_store2(0); break; 2720d8df780aef1acda5962347a32591efc629b6748Anders Carlsson case 8: __asan_report_store4(0); break; 2730d8df780aef1acda5962347a32591efc629b6748Anders Carlsson case 9: __asan_report_store8(0); break; 274ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 10: __asan_report_store16(0); break; 275ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 12: __asan_register_globals(0, 0); break; 276ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 13: __asan_unregister_globals(0, 0); break; 277ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 14: __asan_set_death_callback(0); break; 278ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 15: __asan_set_error_report_callback(0); break; 279ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 16: __asan_handle_no_return(); break; 280ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 17: __asan_address_is_poisoned(0); break; 281ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 18: __asan_get_allocated_size(0); break; 282ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 19: __asan_get_current_allocated_bytes(); break; 283ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 20: __asan_get_estimated_allocated_size(0); break; 284ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 21: __asan_get_free_bytes(); break; 285ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 22: __asan_get_heap_size(); break; 286ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 23: __asan_get_ownership(0); break; 287ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 24: __asan_get_unmapped_bytes(); break; 288ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 25: __asan_poison_memory_region(0, 0); break; 289ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 26: __asan_unpoison_memory_region(0, 0); break; 290ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 27: __asan_set_error_exit_code(0); break; 291ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 28: __asan_stack_free(0, 0, 0); break; 292ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 29: __asan_stack_malloc(0, 0); break; 293ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 30: __asan_before_dynamic_init(0); break; 294ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 31: __asan_after_dynamic_init(); break; 295ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 32: __asan_poison_stack_memory(0, 0); break; 296ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 33: __asan_unpoison_stack_memory(0, 0); break; 297ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case 34: __asan_region_is_poisoned(0, 0); break; 2980d8df780aef1acda5962347a32591efc629b6748Anders Carlsson case 35: __asan_describe_address(0); break; 2990d8df780aef1acda5962347a32591efc629b6748Anders Carlsson } 300d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson} 301d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson 302d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlssonstatic void asan_atexit() { 303d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson Printf("AddressSanitizer exit stats:\n"); 304d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson __asan_print_accumulated_stats(); 3051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Print AsanMappingProfile. 306d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson for (uptr i = 0; i < kAsanMappingProfileSize; i++) { 307d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson if (AsanMappingProfile[i] == 0) continue; 308d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]); 309d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson } 310d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson} 311d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson 312d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlssonstatic void InitializeHighMemEnd() { 313d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson#if !ASAN_FIXED_MAPPING 314d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson#if SANITIZER_WORDSIZE == 64 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump# if defined(__powerpc64__) 316d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson // FIXME: 317d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson // On PowerPC64 we have two different address space layouts: 44- and 46-bit. 318d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson // We somehow need to figure our which one we are using now and choose 3192e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // one of 0x00000fffffffffffUL and 0x00003fffffffffffUL. 3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Note that with 'ulimit -s unlimited' the stack is moved away from the top 3212e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // of the address space, so simply checking the stack address is not enough. 3222e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor kHighMemEnd = (1ULL << 44) - 1; // 0x00000fffffffffffUL 3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump# else 3242e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor kHighMemEnd = (1ULL << 47) - 1; // 0x00007fffffffffffUL; 3252e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor# endif 3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#else // SANITIZER_WORDSIZE == 32 3272e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor kHighMemEnd = (1ULL << 32) - 1; // 0xffffffff; 3282e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#endif // SANITIZER_WORDSIZE 3292e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#endif // !ASAN_FIXED_MAPPING 3302e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor} 3312e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 3322e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorstatic void ProtectGap(uptr a, uptr size) { 3332e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor CHECK_EQ(a, (uptr)Mprotect(a, size)); 3342e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor} 3352e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 3362e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorstatic void PrintAddressSpaceLayout() { 3372e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || HighMem ||\n", 3382e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)kHighMemBeg, (void*)kHighMemEnd); 3392e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || HighShadow ||\n", 3402e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)kHighShadowBeg, (void*)kHighShadowEnd); 3412e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (kMidMemBeg) { 3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Printf("|| `[%p, %p]` || ShadowGap3 ||\n", 3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (void*)kShadowGap3Beg, (void*)kShadowGap3End); 3442e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || MidMem ||\n", 3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (void*)kMidMemBeg, (void*)kMidMemEnd); 3462e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || ShadowGap2 ||\n", 3472e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)kShadowGap2Beg, (void*)kShadowGap2End); 3482e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || MidShadow ||\n", 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (void*)kMidShadowBeg, (void*)kMidShadowEnd); 3502e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 3512e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || ShadowGap ||\n", 3522e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)kShadowGapBeg, (void*)kShadowGapEnd); 3532e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (kLowShadowBeg) { 3542e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || LowShadow ||\n", 3552e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)kLowShadowBeg, (void*)kLowShadowEnd); 3562e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("|| `[%p, %p]` || LowMem ||\n", 3572e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)kLowMemBeg, (void*)kLowMemEnd); 3582e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 3592e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("MemToShadow(shadow): %p %p %p %p", 3602e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)MEM_TO_SHADOW(kLowShadowBeg), 3612e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)MEM_TO_SHADOW(kLowShadowEnd), 3622e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)MEM_TO_SHADOW(kHighShadowBeg), 3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (void*)MEM_TO_SHADOW(kHighShadowEnd)); 3642e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (kMidMemBeg) { 3652e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf(" %p %p", 3662e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (void*)MEM_TO_SHADOW(kMidShadowBeg), 3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (void*)MEM_TO_SHADOW(kMidShadowEnd)); 3682e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 3692e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("\n"); 3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Printf("red_zone=%zu\n", (uptr)flags()->redzone); 3712e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("malloc_context_size=%zu\n", 3722e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor (uptr)common_flags()->malloc_context_size); 3732e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 3742e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE); 3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY); 3762e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET); 3772e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 3782e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (kMidMemBeg) 3792e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor CHECK(kMidShadowBeg > kLowShadowEnd && 3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump kMidMemBeg > kMidShadowEnd && 3812e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor kHighShadowBeg > kMidMemEnd); 3822e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor} 3832e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // namespace __asan 3852e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 3862e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor// ---------------------- Interface ---------------- {{{1 3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpusing namespace __asan; // NOLINT 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3892e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#if !SANITIZER_SUPPORTS_WEAK_HOOKS 3902e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorextern "C" { 3912e22253e03e175144aeb9d13350a12fd83f858beDouglas GregorSANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE 3922e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorconst char* __asan_default_options() { return ""; } 3932e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor} // extern "C" 3942e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#endif 3952e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 3962e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorint NOINLINE __asan_set_error_exit_code(int exit_code) { 3972e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor int old = flags()->exitcode; 3982e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor flags()->exitcode = exit_code; 3992e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor return old; 4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 4012e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4022e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorvoid NOINLINE __asan_handle_no_return() { 4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump int local_stack; 4042e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor AsanThread *curr_thread = GetCurrentThread(); 4052e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor CHECK(curr_thread); 4061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump uptr PageSize = GetPageSizeCached(); 4072e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor uptr top = curr_thread->stack_top(); 4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1); 4092e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor PoisonShadow(bottom, top - bottom, 0); 4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 4112e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4122e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorvoid NOINLINE __asan_set_death_callback(void (*callback)(void)) { 4132e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor death_callback = callback; 4142e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor} 4152e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4162e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregorvoid __asan_init() { 4172e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (asan_inited) return; 4182e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor SanitizerToolName = "AddressSanitizer"; 4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CHECK(!asan_init_is_running && "ASan init calls itself!"); 4202e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor asan_init_is_running = true; 4212e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor InitializeHighMemEnd(); 4222e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4232e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // Make sure we are not statically linked. 4242e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor AsanDoesNotSupportStaticLinkage(); 4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Install tool-specific callbacks in sanitizer_common. 4272e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor SetDieCallback(AsanDie); 4282e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor SetCheckFailedCallback(AsanCheckFailed); 4292e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor SetPrintfAndReportCallback(AppendToErrorMessageBuffer); 4302e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Initialize flags. This must be done early, because most of the 4322e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // initialization steps look at flags(). 4332e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor const char *options = GetEnv("ASAN_OPTIONS"); 4342e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor InitializeFlags(flags(), options); 4352e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor __sanitizer_set_report_path(flags()->log_path); 4362e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4372e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (flags()->verbosity && options) { 4382e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Report("Parsed ASAN_OPTIONS: %s\n", options); 4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 4402e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4412e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // Re-exec ourselves if we need to set additional env or command line args. 4422e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor MaybeReexec(); 4432e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Setup internal allocator callback. 4452e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor SetLowLevelAllocateCallback(OnLowLevelAllocate); 4462e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4472e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (flags()->atexit) { 4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Atexit(asan_atexit); 4492e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 4502e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // interceptors 4522e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor InitializeAsanInterceptors(); 4532e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ReplaceSystemMalloc(); 4552e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ReplaceOperatorsNewAndDelete(); 4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4572e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor uptr shadow_start = kLowShadowBeg; 4582e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (kLowShadowBeg) shadow_start -= GetMmapGranularity(); 4592e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor uptr shadow_end = kHighShadowEnd; 4602e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor bool full_shadow_is_available = 4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump MemoryRangeIsAvailable(shadow_start, shadow_end); 4622e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4632e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#if SANITIZER_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING 4642e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (!full_shadow_is_available) { 4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0; 4662e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0; 4672e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 4682e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor#endif 4692e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4702e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (flags()->verbosity) 4712e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor PrintAddressSpaceLayout(); 4722e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (flags()->disable_core) { 4742e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor DisableCoreDumper(); 4752e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 4762e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 4772e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (full_shadow_is_available) { 4782e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // mmap the low shadow plus at least one page at the left. 4791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (kLowShadowBeg) 4802e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); 4812e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // mmap the high shadow. 4822e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 4832e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // protect the gap. 4842e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else if (kMidMemBeg && 4862e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) && 4872e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor MemoryRangeIsAvailable(kMidMemEnd + 1, shadow_end)) { 4882e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor CHECK(kLowShadowBeg != kLowShadowEnd); 4892e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // mmap the low shadow plus at least one page at the left. 4902e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); 4912e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // mmap the mid shadow. 4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd); 4932e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // mmap the high shadow. 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 4952e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // protect the gaps. 4962e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1); 4982e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1); 4992e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } else { 5002e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Report("Shadow memory range interleaves with an existing memory mapping. " 5012e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor "ASan cannot proceed correctly. ABORTING.\n"); 5022e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor DumpProcessMap(); 5032e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor Die(); 5042e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor } 5052e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 5062e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor InstallSignalHandlers(); 5072e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // Start symbolizer process if necessary. 5082e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor const char* external_symbolizer = common_flags()->external_symbolizer_path; 5092e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor if (common_flags()->symbolize && external_symbolizer && 5102e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor external_symbolizer[0]) { 5112e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor InitializeExternalSymbolizer(external_symbolizer); 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 5132e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // should be set to 1 prior to initializing the threads. 5162e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor asan_inited = 1; 5172e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor asan_init_is_running = false; 5182e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor 5192e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor // Create main thread. 520464175bba1318bef7905122e9fda20cff926df78Chris Lattner AsanTSDInit(AsanThread::TSDDtor); 521464175bba1318bef7905122e9fda20cff926df78Chris Lattner AsanThread *main_thread = AsanThread::Create(0, 0); 522464175bba1318bef7905122e9fda20cff926df78Chris Lattner CreateThreadContextArgs create_main_args = { main_thread, 0 }; 523a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner u32 main_tid = asanThreadRegistry().CreateThread( 524b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner 0, true, 0, &create_main_args); 525b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner CHECK_EQ(0, main_tid); 526b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SetCurrentThread(main_thread); 527183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall main_thread->ThreadStart(GetPid()); 528b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner force_interface_symbols(); // no-op. 529b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner 530b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner InitializeAllocator(); 531b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner 532b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (flags()->verbosity) { 533b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Report("AddressSanitizer Init done\n"); 534b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 535b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner} 536b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner