asan_rtl.cc revision 09672caefb5694f1981a1712fdefa44840a95e67
1ad5e73887052193afda72db8efcb812bd083a4a8John McCall//===-- asan_rtl.cc ---------------------------------------------*- C++ -*-===//
25f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor//
35f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor//                     The LLVM Compiler Infrastructure
4b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson//
59234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// This file is distributed under the University of Illinois Open Source
69234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// License. See LICENSE.TXT for details.
79234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//
89234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//===----------------------------------------------------------------------===//
99234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//
109234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// This file is a part of AddressSanitizer, an address sanity checker.
1131455256ae26cc7069111643ec4429ea564377daSean Hunt//
1231455256ae26cc7069111643ec4429ea564377daSean Hunt// Main file of the ASan run-time library.
1331455256ae26cc7069111643ec4429ea564377daSean Hunt//===----------------------------------------------------------------------===//
149234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "asan_allocator.h"
155f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor#include "asan_interceptors.h"
165f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor#include "asan_interface.h"
179234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "asan_internal.h"
18b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_lock.h"
19b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_mapping.h"
20b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_procmaps.h"
219234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "asan_stack.h"
22b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_stats.h"
23b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_thread.h"
24b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_thread_registry.h"
259234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson
26b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlssonnamespace __asan {
27b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson
284843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson// -------------------------- Flags ------------------------- {{{1
299234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonstatic const size_t kMallocContextSize = 30;
304843e584b54460973b8445d38907bab0401ebb0cAnders Carlssonstatic int    FLAG_atexit;
314843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson
324843e584b54460973b8445d38907bab0401ebb0cAnders Carlssonsize_t FLAG_redzone;  // power of two, >= 32
339234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonsize_t FLAG_quarantine_size;
34c6c91bc019ff7fa09f6570025ba011aad4c0d004Anders Carlssonint    FLAG_demangle;
35984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonbool   FLAG_symbolize;
369234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonint    FLAG_v;
37984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonint    FLAG_debug;
38984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonbool   FLAG_poison_shadow;
399234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonint    FLAG_report_globals;
40984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonsize_t FLAG_malloc_context_size = kMallocContextSize;
4191e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonuintptr_t FLAG_large_malloc;
429234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonbool   FLAG_handle_segv;
4391e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonbool   FLAG_replace_str;
4491e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonbool   FLAG_replace_intrin;
452928c2107f2e0007f35fe1c224aab63535f1403dAnders Carlssonbool   FLAG_replace_cfallocator;  // Used on Mac only.
4691e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonsize_t FLAG_max_malloc_fill_size = 0;
47329749c1ec1ead3c41af52260f1203e4991b4e83Anders Carlssonbool   FLAG_use_fake_stack;
481b42c794481f6f958267e4ba913d74fef43161f6Anders Carlssonint    FLAG_exitcode = EXIT_FAILURE;
491b42c794481f6f958267e4ba913d74fef43161f6Anders Carlssonbool   FLAG_allow_user_poisoning;
50283a062a633d6e868aa2be319da812341fe73728Anders Carlssonint    FLAG_sleep_before_dying;
51283a062a633d6e868aa2be319da812341fe73728Anders Carlsson
522df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner// -------------------------- Globals --------------------- {{{1
539234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonint asan_inited;
542df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattnerbool asan_init_is_running;
557a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson
567a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson// -------------------------- Misc ---------------- {{{1
577a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlssonvoid ShowStatsAndAbort() {
589234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson  __asan_print_accumulated_stats();
597a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  AsanDie();
607a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson}
619234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson
627a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlssonstatic void PrintBytes(const char *before, uintptr_t *a) {
637a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  uint8_t *bytes = (uint8_t*)a;
647a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  size_t byte_num = (__WORDSIZE) / 8;
659234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson  Printf("%s%p:", before, (uintptr_t)a);
667a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  for (size_t i = 0; i < byte_num; i++) {
677a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    Printf(" %lx%lx", bytes[i] >> 4, bytes[i] & 15);
689234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson  }
697a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  Printf("\n");
707a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson}
717a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson
727a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlssonsize_t ReadFileToBuffer(const char *file_name, char **buff,
739234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson                         size_t *buff_size, size_t max_len) {
747a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  const size_t kMinFileLen = kPageSize;
757a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  size_t read_len = 0;
769234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson  *buff = 0;
777a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  *buff_size = 0;
787a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson  // The files we usually open are not seekable, so try different buffer sizes.
799234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson  for (size_t size = kMinFileLen; size <= max_len; size *= 2) {
807a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson    int fd = AsanOpenReadonly(file_name);
810e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    if (fd < 0) return -1;
820e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    AsanUnmapOrDie(*buff, *buff_size);
830e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    *buff = (char*)AsanMmapSomewhereOrDie(size, __FUNCTION__);
849234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    *buff_size = size;
850e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    // Read up to one page at a time.
860e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    read_len = 0;
879234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    bool reached_eof = false;
880e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson    while (read_len + kPageSize <= size) {
89cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson      size_t just_read = AsanRead(fd, *buff + read_len, kPageSize);
909234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson      if (just_read == 0) {
91cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson        reached_eof = true;
92cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson        break;
9303c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson      }
9403c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson      read_len += just_read;
9503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson    }
969234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson    AsanClose(fd);
977624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson    if (reached_eof)  // We've read the whole file.
987624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson      break;
997624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson  }
1007482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  return read_len;
1017482e247163978792654ca1a99913e19dd507e0aAnders Carlsson}
1027624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson
1037624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson// ---------------------- mmap -------------------- {{{1
104d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlssonvoid OutOfMemoryMessageAndDie(const char *mem_type, size_t size) {
10503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson  Report("ERROR: AddressSanitizer failed to allocate "
10603c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson         "0x%lx (%ld) bytes of %s\n",
10703c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson         size, size, mem_type);
10803c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson  PRINT_CURRENT_STACK();
10903c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson  ShowStatsAndAbort();
1107624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson}
1117624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson
1127624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson// Reserve memory range [beg, end].
1137482e247163978792654ca1a99913e19dd507e0aAnders Carlssonstatic void ReserveShadowMemoryRange(uintptr_t beg, uintptr_t end) {
1147482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  CHECK((beg % kPageSize) == 0);
1157482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  CHECK(((end + 1) % kPageSize) == 0);
1167482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  size_t size = end - beg + 1;
1177482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  void *res = AsanMmapFixedNoReserve(beg, size);
118d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  CHECK(res == (void*)beg && "ReserveShadowMemoryRange failed");
119d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson}
120d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
121d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson// ---------------------- LowLevelAllocator ------------- {{{1
122d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlssonvoid *LowLevelAllocator::Allocate(size_t size) {
123d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  CHECK((size & (size - 1)) == 0 && "size must be a power of two");
124d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson  if (allocated_end_ - allocated_current_ < size) {
125d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    size_t size_to_allocate = Max(size, kPageSize);
126d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    allocated_current_ =
127d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson        (char*)AsanMmapSomewhereOrDie(size_to_allocate, __FUNCTION__);
128d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    allocated_end_ = allocated_current_ + size_to_allocate;
129d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson    PoisonShadow((uintptr_t)allocated_current_, size_to_allocate,
1307482e247163978792654ca1a99913e19dd507e0aAnders Carlsson                 kAsanInternalHeapMagic);
1317482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  }
1327482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  CHECK(allocated_end_ - allocated_current_ >= size);
133d58d6f778de936516d8815783f2e88348c41dce4Anders Carlsson  void *res = allocated_current_;
1347482e247163978792654ca1a99913e19dd507e0aAnders Carlsson  allocated_current_ += size;
1355cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  return res;
1365cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson}
1375cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson
1385cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson// ---------------------- DescribeAddress -------------------- {{{1
1395cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlssonstatic bool DescribeStackAddress(uintptr_t addr, uintptr_t access_size) {
1405cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr);
1415cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson  if (!t) return false;
142add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  const intptr_t kBufSize = 4095;
143add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  char buf[kBufSize];
144add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  uintptr_t offset = 0;
145add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  const char *frame_descr = t->GetFrameNameByAddr(addr, &offset);
1468257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  // This string is created by the compiler and has the following form:
147add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  // "FunctioName n alloc_1 alloc_2 ... alloc_n"
148add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  // where alloc_i looks like "offset size len ObjectName ".
149add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  CHECK(frame_descr);
150add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  // Report the function name and the offset.
151add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson  const char *name_end = REAL(strchr)(frame_descr, ' ');
152ae3524866124021f3bc695886668254093c0793fAnders Carlsson  CHECK(name_end);
153ae3524866124021f3bc695886668254093c0793fAnders Carlsson  buf[0] = 0;
154ae3524866124021f3bc695886668254093c0793fAnders Carlsson  internal_strncat(buf, frame_descr,
155ae3524866124021f3bc695886668254093c0793fAnders Carlsson                   Min(kBufSize,
156ae3524866124021f3bc695886668254093c0793fAnders Carlsson                       static_cast<intptr_t>(name_end - frame_descr)));
157ae3524866124021f3bc695886668254093c0793fAnders Carlsson  Printf("Address %p is located at offset %ld "
158ae3524866124021f3bc695886668254093c0793fAnders Carlsson         "in frame <%s> of T%d's stack:\n",
159ae3524866124021f3bc695886668254093c0793fAnders Carlsson         addr, offset, buf, t->tid());
1601668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  // Report the number of stack objects.
1611668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  char *p;
1621668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  size_t n_objects = strtol(name_end, &p, 10);
1631668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  CHECK(n_objects > 0);
1641668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  Printf("  This frame has %ld object(s):\n", n_objects);
1651668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  // Report all objects in this frame.
1661668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson  for (size_t i = 0; i < n_objects; i++) {
167aeb85374e92619b8e4ce92ac6e30756b5053a137Anders Carlsson    size_t beg, size;
1681668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson    intptr_t len;
1691668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson    beg  = strtol(p, &p, 10);
1701668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson    size = strtol(p, &p, 10);
1711668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson    len  = strtol(p, &p, 10);
1721668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson    if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') {
1731668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson      Printf("AddressSanitizer can't parse the stack frame descriptor: |%s|\n",
1741668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson             frame_descr);
1751668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson      break;
1761668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson    }
1770ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson    p++;
1780ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson    buf[0] = 0;
1790ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson    internal_strncat(buf, p, Min(kBufSize, len));
1800ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson    p += len;
1810ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson    Printf("    [%ld, %ld) '%s'\n", beg, beg + size, buf);
1820ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  }
1830ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson  Printf("HINT: this may be a false positive if your program uses "
1840ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson         "some custom stack unwind mechanism\n"
18550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson         "      (longjmp and C++ exceptions *are* supported)\n");
18650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  t->summary()->Announce();
18750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  return true;
18850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson}
18950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
19050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlssonstatic NOINLINE void DescribeAddress(uintptr_t addr, uintptr_t access_size) {
19150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  // Check if this is a global.
19250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  if (DescribeAddrIfGlobal(addr))
19350755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson    return;
19450755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
19550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  if (DescribeStackAddress(addr, access_size))
19650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson    return;
19750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
19850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  // finally, check if this is a heap.
19950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson  DescribeHeapAddress(addr, access_size);
20050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson}
20150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
20250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson// -------------------------- Run-time entry ------------------- {{{1
203b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson// exported functions
204b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson#define ASAN_REPORT_ERROR(type, is_write, size)                     \
205b217c1b9d2225521f4021984ad5a424784fa22bbAnders CarlssonNOINLINE ASAN_INTERFACE_ATTRIBUTE                                   \
206b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlssonextern "C" void __asan_report_ ## type ## size(uintptr_t addr);     \
207b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlssonextern "C" void __asan_report_ ## type ## size(uintptr_t addr) {    \
208b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  GET_BP_PC_SP;                                                     \
209b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson  __asan_report_error(pc, bp, sp, addr, is_write, size);            \
210b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson}
211b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson
212c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(load, false, 1)
2135c478cf2d54157062cd843737324e0d0df03a464Anders CarlssonASAN_REPORT_ERROR(load, false, 2)
214c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(load, false, 4)
2155c478cf2d54157062cd843737324e0d0df03a464Anders CarlssonASAN_REPORT_ERROR(load, false, 8)
216c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(load, false, 16)
217c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 1)
218c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 2)
219c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 4)
220c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 8)
221c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 16)
2228e51a1f5da6ef4a1a168d14116c6eed3a578a263John McCall
223c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// Force the linker to keep the symbols for various ASan interface functions.
224c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// We want to keep those in the executable in order to let the instrumented
225c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// dynamic libraries access the symbol even if it is not used by the executable
226c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// itself. This should help if the build system is removing dead code at link
227a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson// time.
228a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlssonstatic void force_interface_symbols() {
229a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson  volatile int fake_condition = 0;  // prevent dead condition elimination.
230a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson  if (fake_condition) {
231a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson    __asan_report_load1(NULL);
232a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson    __asan_report_load2(NULL);
233e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson    __asan_report_load4(NULL);
23458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_load8(NULL);
23558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_load16(NULL);
23658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_store1(NULL);
23758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_store2(NULL);
23858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_store4(NULL);
23958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_store8(NULL);
24058040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_report_store16(NULL);
24158040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_register_global(0, 0, NULL);
24258040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_register_globals(NULL, 0);
24358040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson    __asan_unregister_globals(NULL, 0);
24458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson  }
24558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson}
24658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson
24758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson// -------------------------- Init ------------------- {{{1
24858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson#if defined(_WIN32)
24958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson// atoll is not defined on Windows.
250e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonint64_t atoll(const char *str) {
251e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  UNIMPLEMENTED();
252e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  return -1;
2538f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor}
254e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson#endif
255e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
256e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonstatic int64_t IntFlagValue(const char *flags, const char *flag,
2578f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor                            int64_t default_val) {
258e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  if (!flags) return default_val;
259e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  const char *str = internal_strstr(flags, flag);
260e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  if (!str) return default_val;
261e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  return atoll(str + internal_strlen(flag));
262e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson}
2638f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor
264e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonstatic void asan_atexit() {
265e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  Printf("AddressSanitizer exit stats:\n");
266e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  __asan_print_accumulated_stats();
2678f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor}
268e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
269e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonvoid CheckFailed(const char *cond, const char *file, int line) {
270e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  Report("CHECK failed: %s at %s:%d\n", cond, file, line);
271e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson  PRINT_CURRENT_STACK();
2728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  ShowStatsAndAbort();
273e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson}
274e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
275e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson}  // namespace __asan
2768257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2778257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson// ---------------------- Interface ---------------- {{{1
2788257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonusing namespace __asan;  // NOLINT
2798257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2808257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonint __asan_set_error_exit_code(int exit_code) {
2818257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  int old = FLAG_exitcode;
2828257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  FLAG_exitcode = exit_code;
2838257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  return old;
2848257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson}
2858257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2868257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonvoid __asan_report_error(uintptr_t pc, uintptr_t bp, uintptr_t sp,
2878257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson                         uintptr_t addr, bool is_write, size_t access_size) {
2888257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  // Do not print more than one report, otherwise they will mix up.
2898257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  static int num_calls = 0;
2908257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  if (AtomicInc(&num_calls) > 1) return;
2918257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2928257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  Printf("=================================================================\n");
2938257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  const char *bug_descr = "unknown-crash";
2948257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson  if (AddrIsInMem(addr)) {
2959e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    uint8_t *shadow_addr = (uint8_t*)MemToShadow(addr);
2969e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    // If we are accessing 16 bytes, look at the second shadow byte.
2979e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY)
2989e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      shadow_addr++;
2999e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    // If we are in the partial right redzone, look at the next shadow byte.
3009e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    if (*shadow_addr > 0 && *shadow_addr < 128)
3019e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      shadow_addr++;
3029e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson    switch (*shadow_addr) {
3039e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      case kAsanHeapLeftRedzoneMagic:
3049e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      case kAsanHeapRightRedzoneMagic:
3059e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson        bug_descr = "heap-buffer-overflow";
3069e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson        break;
3079e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      case kAsanHeapFreeMagic:
3088f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor        bug_descr = "heap-use-after-free";
3099e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson        break;
3109e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      case kAsanStackLeftRedzoneMagic:
311f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson        bug_descr = "stack-buffer-underflow";
312f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson        break;
313a9efbf009468f36df0bb66551677339055757d51Nuno Lopes      case kAsanStackMidRedzoneMagic:
314a9efbf009468f36df0bb66551677339055757d51Nuno Lopes      case kAsanStackRightRedzoneMagic:
31531455256ae26cc7069111643ec4429ea564377daSean Hunt      case kAsanStackPartialRedzoneMagic:
31631455256ae26cc7069111643ec4429ea564377daSean Hunt        bug_descr = "stack-buffer-overflow";
31731455256ae26cc7069111643ec4429ea564377daSean Hunt        break;
31831455256ae26cc7069111643ec4429ea564377daSean Hunt      case kAsanStackAfterReturnMagic:
31931455256ae26cc7069111643ec4429ea564377daSean Hunt        bug_descr = "stack-use-after-return";
32031455256ae26cc7069111643ec4429ea564377daSean Hunt        break;
32131455256ae26cc7069111643ec4429ea564377daSean Hunt      case kAsanUserPoisonedMemoryMagic:
32231455256ae26cc7069111643ec4429ea564377daSean Hunt        bug_descr = "use-after-poison";
32331455256ae26cc7069111643ec4429ea564377daSean Hunt        break;
32431455256ae26cc7069111643ec4429ea564377daSean Hunt      case kAsanGlobalRedzoneMagic:
3251dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall        bug_descr = "global-buffer-overflow";
3261dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall        break;
3271dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    }
3281dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  }
3291dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3301dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
3311dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  int curr_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
3321dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3331dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  if (curr_thread) {
3341dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    // We started reporting an error message. Stop using the fake stack
3351dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    // in case we will call an instrumented function from a symbolizer.
3361dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    curr_thread->fake_stack().StopUsingFakeStack();
3371dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  }
3381dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3391dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Report("ERROR: AddressSanitizer %s on address "
3401dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall         "%p at pc 0x%lx bp 0x%lx sp 0x%lx\n",
3411dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall         bug_descr, addr, pc, bp, sp);
3421dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3431dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  Printf("%s of size %d at %p thread T%d\n",
3441dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall         access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
3451dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall         access_size, addr, curr_tid);
3461dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3471dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  if (FLAG_debug) {
3481dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall    PrintBytes("PC: ", (uintptr_t*)pc);
3491dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  }
3501dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3511dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp);
3521dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  stack.PrintStack();
3531dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3541dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  CHECK(AddrIsInMem(addr));
3551dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3561dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  DescribeAddress(addr, access_size);
3571dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3581dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  uintptr_t shadow_addr = MemToShadow(addr);
3592f27bf854f0519810b34afd209089cc75536b757John McCall  Report("ABORTING\n");
3602f27bf854f0519810b34afd209089cc75536b757John McCall  __asan_print_accumulated_stats();
3612f27bf854f0519810b34afd209089cc75536b757John McCall  Printf("Shadow byte and word:\n");
3622f27bf854f0519810b34afd209089cc75536b757John McCall  Printf("  %p: %x\n", shadow_addr, *(unsigned char*)shadow_addr);
3632f27bf854f0519810b34afd209089cc75536b757John McCall  uintptr_t aligned_shadow = shadow_addr & ~(kWordSize - 1);
3642f27bf854f0519810b34afd209089cc75536b757John McCall  PrintBytes("  ", (uintptr_t*)(aligned_shadow));
3652f27bf854f0519810b34afd209089cc75536b757John McCall  Printf("More shadow bytes:\n");
366e1e342f4a96f132d8d7e802284417bd520f9f4f8John McCall  PrintBytes("  ", (uintptr_t*)(aligned_shadow-4*kWordSize));
3671dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall  PrintBytes("  ", (uintptr_t*)(aligned_shadow-3*kWordSize));
36832fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  PrintBytes("  ", (uintptr_t*)(aligned_shadow-2*kWordSize));
36932fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  PrintBytes("  ", (uintptr_t*)(aligned_shadow-1*kWordSize));
37032fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  PrintBytes("=>", (uintptr_t*)(aligned_shadow+0*kWordSize));
37132fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  PrintBytes("  ", (uintptr_t*)(aligned_shadow+1*kWordSize));
3728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  PrintBytes("  ", (uintptr_t*)(aligned_shadow+2*kWordSize));
37332fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  PrintBytes("  ", (uintptr_t*)(aligned_shadow+3*kWordSize));
37432fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor  PrintBytes("  ", (uintptr_t*)(aligned_shadow+4*kWordSize));
375aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson  AsanDie();
376aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson}
377aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson
378aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlssonvoid __asan_init() {
379ad5e73887052193afda72db8efcb812bd083a4a8John McCall  if (asan_inited) return;
380ad5e73887052193afda72db8efcb812bd083a4a8John McCall  asan_init_is_running = true;
381ad5e73887052193afda72db8efcb812bd083a4a8John McCall
382ad5e73887052193afda72db8efcb812bd083a4a8John McCall  // Make sure we are not statically linked.
383ad5e73887052193afda72db8efcb812bd083a4a8John McCall  AsanDoesNotSupportStaticLinkage();
384ad5e73887052193afda72db8efcb812bd083a4a8John McCall
385ad5e73887052193afda72db8efcb812bd083a4a8John McCall  // flags
386ad5e73887052193afda72db8efcb812bd083a4a8John McCall  const char *options = AsanGetEnv("ASAN_OPTIONS");
387ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_malloc_context_size =
388ad5e73887052193afda72db8efcb812bd083a4a8John McCall      IntFlagValue(options, "malloc_context_size=", kMallocContextSize);
389ad5e73887052193afda72db8efcb812bd083a4a8John McCall  CHECK(FLAG_malloc_context_size <= kMallocContextSize);
390ad5e73887052193afda72db8efcb812bd083a4a8John McCall
391ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_max_malloc_fill_size =
392ad5e73887052193afda72db8efcb812bd083a4a8John McCall      IntFlagValue(options, "max_malloc_fill_size=", 0);
393ad5e73887052193afda72db8efcb812bd083a4a8John McCall
394ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_v = IntFlagValue(options, "verbosity=", 0);
395ad5e73887052193afda72db8efcb812bd083a4a8John McCall
396ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_redzone = IntFlagValue(options, "redzone=", 128);
397ad5e73887052193afda72db8efcb812bd083a4a8John McCall  CHECK(FLAG_redzone >= 32);
398ad5e73887052193afda72db8efcb812bd083a4a8John McCall  CHECK((FLAG_redzone & (FLAG_redzone - 1)) == 0);
399ad5e73887052193afda72db8efcb812bd083a4a8John McCall
400ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_atexit = IntFlagValue(options, "atexit=", 0);
401ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_poison_shadow = IntFlagValue(options, "poison_shadow=", 1);
4028f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  FLAG_report_globals = IntFlagValue(options, "report_globals=", 1);
403ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_handle_segv = IntFlagValue(options, "handle_segv=", ASAN_NEEDS_SEGV);
404ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_symbolize = IntFlagValue(options, "symbolize=", 1);
4058f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  FLAG_demangle = IntFlagValue(options, "demangle=", 1);
406ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_debug = IntFlagValue(options, "debug=", 0);
407ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_replace_cfallocator = IntFlagValue(options, "replace_cfallocator=", 1);
408ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_replace_str = IntFlagValue(options, "replace_str=", 1);
409ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_replace_intrin = IntFlagValue(options, "replace_intrin=", 1);
410ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_use_fake_stack = IntFlagValue(options, "use_fake_stack=", 1);
411ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_exitcode = IntFlagValue(options, "exitcode=", EXIT_FAILURE);
412ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_allow_user_poisoning = IntFlagValue(options,
413ad5e73887052193afda72db8efcb812bd083a4a8John McCall                                           "allow_user_poisoning=", 1);
414ad5e73887052193afda72db8efcb812bd083a4a8John McCall  FLAG_sleep_before_dying = IntFlagValue(options, "sleep_before_dying=", 0);
415ad5e73887052193afda72db8efcb812bd083a4a8John McCall
416ad5e73887052193afda72db8efcb812bd083a4a8John McCall  if (FLAG_atexit) {
417d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    atexit(asan_atexit);
418d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  }
419d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
420d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  FLAG_quarantine_size =
421d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      IntFlagValue(options, "quarantine_size=", 1UL << 28);
422d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
423d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  // interceptors
424d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  InitializeAsanInterceptors();
425d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
426d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  ReplaceSystemMalloc();
427d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  InstallSignalHandlers();
428d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
429d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  if (FLAG_v) {
430d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("|| `[%p, %p]` || HighMem    ||\n", kHighMemBeg, kHighMemEnd);
431d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("|| `[%p, %p]` || HighShadow ||\n",
432d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           kHighShadowBeg, kHighShadowEnd);
433d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("|| `[%p, %p]` || ShadowGap  ||\n",
434d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           kShadowGapBeg, kShadowGapEnd);
435d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("|| `[%p, %p]` || LowShadow  ||\n",
436d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           kLowShadowBeg, kLowShadowEnd);
437d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("|| `[%p, %p]` || LowMem     ||\n", kLowMemBeg, kLowMemEnd);
438d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("MemToShadow(shadow): %p %p %p %p\n",
439d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           MEM_TO_SHADOW(kLowShadowBeg),
440d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           MEM_TO_SHADOW(kLowShadowEnd),
441d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           MEM_TO_SHADOW(kHighShadowBeg),
442d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola           MEM_TO_SHADOW(kHighShadowEnd));
443d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("red_zone=%ld\n", FLAG_redzone);
444d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("malloc_context_size=%ld\n", (int)FLAG_malloc_context_size);
445d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
446d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("SHADOW_SCALE: %lx\n", SHADOW_SCALE);
447d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("SHADOW_GRANULARITY: %lx\n", SHADOW_GRANULARITY);
448d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    Printf("SHADOW_OFFSET: %lx\n", SHADOW_OFFSET);
449d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
4508f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor  }
451d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
452d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  if (__WORDSIZE == 64) {
4537002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall    // Disable core dumper -- it makes little sense to dump 16T+ core.
454d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    AsanDisableCoreDumper();
455d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola  }
4569b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola
4579b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  {
4589b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    if (kLowShadowBeg != kLowShadowEnd) {
4599b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola      // mmap the low shadow plus one page.
4609b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola      ReserveShadowMemoryRange(kLowShadowBeg - kPageSize, kLowShadowEnd);
4619b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    }
4629b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    // mmap the high shadow.
4639b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
4649b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    // protect the gap
4659b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    void *prot = AsanMprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
4669b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola    CHECK(prot == (void*)kShadowGapBeg);
4679b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  }
4689b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola
4699b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
4709b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola  // should be set to 1 prior to initializing the threads.
471  asan_inited = 1;
472  asan_init_is_running = false;
473
474  asanThreadRegistry().Init();
475  asanThreadRegistry().GetMain()->ThreadStart();
476  force_interface_symbols();  // no-op.
477
478  if (FLAG_v) {
479    Report("AddressSanitizer Init done\n");
480  }
481}
482
483#if defined(ASAN_USE_PREINIT_ARRAY)
484// On Linux, we force __asan_init to be called before anyone else
485// by placing it into .preinit_array section.
486// FIXME: do we have anything like this on Mac?
487__attribute__((section(".preinit_array")))
488  typeof(__asan_init) *__asan_preinit =__asan_init;
489#endif
490