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