asan_interceptors.cc revision d47189c1b63a4de755d7ec071f8d56c8d01cc667
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_interceptors.cc ------------------------------------*- C++ -*-===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
12d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// Intercept various libc functions.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h"
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h"
171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interface.h"
181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h"
19547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#include "asan_mac.h"
201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h"
211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h"
221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h"
234803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include "asan_thread_registry.h"
241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include <new>
26af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany#include <ctype.h>
271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <dlfcn.h>
281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2935dd9d8f54f15f16be6c224e303bbf75d667f248Kostya Serebryany#include <string.h>
3035dd9d8f54f15f16be6c224e303bbf75d667f248Kostya Serebryany#include <strings.h>
312fc648c5d1775f13844d4459347e2b7328411e85Kostya Serebryany#include <pthread.h>
3235dd9d8f54f15f16be6c224e303bbf75d667f248Kostya Serebryany
33d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// To replace weak system functions on Linux we just need to declare functions
34d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// with same names in our library and then obtain the real function pointers
35d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// using dlsym(). This is not so on Mac OS, where the two-level namespace makes
36d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// our replacement functions invisible to other libraries. This may be overcomed
37d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared
38d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// libraries in Chromium were noticed when doing so.
39d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// Instead we use mach_override, a handy framework for patching functions at
40d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// runtime. To avoid possible name clashes, our replacement functions have
41d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// the "wrap_" prefix on Mac.
42d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany//
43d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// After interception, the calls to system functions will be substituted by
44d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// calls to our interceptors. We store pointers to system function f()
45d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// in __asan::real_f().
46d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany//
47d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// TODO(glider): mach_override_ptr() tends to spend too much time
48d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// in allocateBranchIsland(). This should be ok for real-word
49d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// application, but slows down our tests which fork too many children.
50d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#ifdef __APPLE__
51d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#include "mach_override/mach_override.h"
52d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define WRAPPER_NAME(x) "wrap_"#x
53d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
54d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define OVERRIDE_FUNCTION(oldfunc, newfunc)                             \
55d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  CHECK(0 == __asan_mach_override_ptr((void*)(oldfunc),                        \
56d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany                                      (void*)(newfunc),                        \
57d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany                                      (void**)&real_##oldfunc));               \
58d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  CHECK(real_##oldfunc != NULL);
59d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
60d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc)                   \
61d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  do { __asan_mach_override_ptr((void*)(oldfunc),                              \
62d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany                                (void*)(newfunc),                              \
63d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany                                (void**)&real_##oldfunc); } while (0)
64d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
65d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION(func)                                        \
66d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  OVERRIDE_FUNCTION(func, WRAP(func))
67d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
68d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION_IF_EXISTS(func)                              \
69d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  OVERRIDE_FUNCTION_IF_EXISTS(func, WRAP(func))
70d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
71d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#else  // __linux__
72d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define WRAPPER_NAME(x) #x
73d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
74d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION(func)                                        \
75d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  CHECK((real_##func = (func##_f)dlsym(RTLD_NEXT, #func)));
76d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
77d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION_IF_EXISTS(func)                              \
78d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany  do { real_##func = (func##_f)dlsym(RTLD_NEXT, #func); } while (0)
79d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#endif
80d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany
811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef void (*longjmp_f)(void *env, int val);
844803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef longjmp_f _longjmp_f;
854803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef longjmp_f siglongjmp_f;
864803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef void (*__cxa_throw_f)(void *, void *, void *);
87d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryanytypedef int (*pthread_create_f)(void *thread, const void *attr,
884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany                                void *(*start_routine) (void *), void *arg);
894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#ifdef __APPLE__
904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_async_f_f real_dispatch_async_f;
914803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_sync_f_f real_dispatch_sync_f;
924803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_after_f_f real_dispatch_after_f;
934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_barrier_async_f_f real_dispatch_barrier_async_f;
944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_group_async_f_f real_dispatch_group_async_f;
954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanypthread_workqueue_additem_np_f real_pthread_workqueue_additem_np;
964803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif
974803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
984803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanysigaction_f             real_sigaction;
994803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanysignal_f                real_signal;
1004803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanylongjmp_f               real_longjmp;
1014803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany_longjmp_f              real__longjmp;
1024803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanysiglongjmp_f            real_siglongjmp;
1034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany__cxa_throw_f           real___cxa_throw;
1044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanypthread_create_f        real_pthread_create;
1054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyindex_f       real_index;
10752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanymemcmp_f      real_memcmp;
1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanymemcpy_f      real_memcpy;
1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanymemmove_f     real_memmove;
1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanymemset_f      real_memset;
111af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanystrcasecmp_f  real_strcasecmp;
1120985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanystrcat_f      real_strcat;
1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrchr_f      real_strchr;
1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrcmp_f      real_strcmp;
1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrcpy_f      real_strcpy;
1161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrdup_f      real_strdup;
1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrlen_f      real_strlen;
118af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanystrncasecmp_f real_strncasecmp;
1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrncmp_f     real_strncmp;
1201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrncpy_f     real_strncpy;
1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrnlen_f     real_strnlen;
1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a single byte in memory.
1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// On error calls __asan_report_error, which aborts the program.
1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany__attribute__((noinline))
1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic void AccessAddress(uintptr_t address, bool isWrite) {
1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (__asan_address_is_poisoned((void*)address)) {
1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    GET_BP_PC_SP;
1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1);
1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// and ASAN_WRITE_RANGE as macro instead of function so
1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// that no extra frames are created, and stack trace contains
1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// relevant information only.
1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a memory range.
1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// More complex implementation is possible, for now just
1401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// checking the first and the last byte of a range.
1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (size > 0) { \
1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    uintptr_t ptr = (uintptr_t)(offset); \
1441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    AccessAddress(ptr, isWrite); \
1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    AccessAddress(ptr + (size) - 1, isWrite); \
1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  } \
147e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_READ_RANGE(offset, size) do { \
1501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ACCESS_MEMORY_RANGE(offset, size, false); \
151e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_WRITE_RANGE(offset, size) do { \
1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ACCESS_MEMORY_RANGE(offset, size, true); \
155e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Behavior of functions like "memcpy" or "strcpy" is undefined
1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// if memory intervals overlap. We report error in this case.
1591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Macro is used to avoid creation of new frames.
1600985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanystatic inline bool RangesOverlap(const char *offset1, size_t length1,
1610985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany                                 const char *offset2, size_t length2) {
1620985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
164c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const char *offset1 = (const char*)_offset1; \
1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const char *offset2 = (const char*)_offset2; \
1670985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  if (RangesOverlap(offset1, length1, offset2, length2)) { \
168c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    Report("ERROR: AddressSanitizer %s-param-overlap: " \
1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany           "memory ranges [%p,%p) and [%p, %p) overlap\n", \
170c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany           name, offset1, offset1 + length1, offset2, offset2 + length2); \
1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    PRINT_CURRENT_STACK(); \
1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ShowStatsAndAbort(); \
1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  } \
174e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
176e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany#define ENSURE_ASAN_INITED() do { \
177e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  CHECK(!asan_init_is_running); \
178e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  if (!asan_inited) { \
179e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    __asan_init(); \
180e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  } \
181e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strlen(const char *s) {
1841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i = 0;
1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  while (s[i]) i++;
1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return i;
1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strnlen(const char *s, size_t maxlen) {
1901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (real_strnlen != NULL) {
1911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return real_strnlen(s, maxlen);
1921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
1931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i = 0;
1941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  while (i < maxlen && s[i]) i++;
1951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return i;
1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
198de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid* internal_memchr(const void* s, int c, size_t n) {
199de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  const char* t = (char*)s;
200de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  for (size_t i = 0; i < n; ++i, ++t)
201de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany    if (*t == c)
202de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany      return (void*)t;
203de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  return NULL;
204de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany}
205de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
206de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint internal_memcmp(const void* s1, const void* s2, size_t n) {
207de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  const char* t1 = (char*)s1;
208de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  const char* t2 = (char*)s2;
209de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  for (size_t i = 0; i < n; ++i, ++t1, ++t2)
210de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany    if (*t1 != *t2)
211de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany      return *t1 < *t2 ? -1 : 1;
212de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  return 0;
213de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany}
214de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
215a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strstr(const char *haystack, const char *needle) {
216a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  // This is O(N^2), but we are not using it in hot places.
217a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t len1 = internal_strlen(haystack);
218a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t len2 = internal_strlen(needle);
219a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  if (len1 < len2) return 0;
220a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  for (size_t pos = 0; pos <= len1 - len2; pos++) {
221a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany    if (internal_memcmp(haystack + pos, needle, len2) == 0)
222a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany      return (char*)haystack + pos;
223a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  }
224a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  return 0;
225a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany}
226a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany
227a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strncat(char *dst, const char *src, size_t n) {
228a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t len = internal_strlen(dst);
229a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t i;
230a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  for (i = 0; i < n && src[i]; i++)
231a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany    dst[len + i] = src[i];
232a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  dst[len + i] = 0;
233a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  return dst;
234a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany}
2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}  // namespace __asan
2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Wrappers ---------------- {{{1
2391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan;  // NOLINT
2401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2414803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#define OPERATOR_NEW_BODY \
2424803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  GET_STACK_TRACE_HERE_FOR_MALLOC;\
2434803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return asan_memalign(0, size, &stack);
2444803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2454803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#ifdef ANDROID
2464803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new(size_t size) { OPERATOR_NEW_BODY; }
2474803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new[](size_t size) { OPERATOR_NEW_BODY; }
2484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#else
2494803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
2504803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
2514803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new(size_t size, std::nothrow_t const&) throw()
2524803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_NEW_BODY; }
2534803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new[](size_t size, std::nothrow_t const&) throw()
2544803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_NEW_BODY; }
2554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif
2564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2574803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#define OPERATOR_DELETE_BODY \
2584803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  GET_STACK_TRACE_HERE_FOR_FREE(ptr);\
2594803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  asan_free(ptr, &stack);
2604803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2614803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; }
2624803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; }
2634803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete(void *ptr, std::nothrow_t const&) throw()
2644803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_DELETE_BODY; }
2654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete[](void *ptr, std::nothrow_t const&) throw()
2664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_DELETE_BODY;}
2674803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2684803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void *asan_thread_start(void *arg) {
2694803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  AsanThread *t = (AsanThread*)arg;
2704803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  asanThreadRegistry().SetCurrent(t);
2714803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return t->ThreadStart();
2724803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
2734803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2744803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C"
2754803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#ifndef __APPLE__
2764803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany__attribute__((visibility("default")))
2774803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif
2782fc648c5d1775f13844d4459347e2b7328411e85Kostya Serebryanyint WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
2794803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany                         void *(*start_routine) (void *), void *arg) {
2804803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false);
2814803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
2824803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  AsanThread *t = AsanThread::Create(current_tid, start_routine, arg);
2834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  asanThreadRegistry().RegisterThread(t, current_tid, &stack);
2844803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return real_pthread_create(thread, attr, asan_thread_start, t);
2854803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
2864803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2874803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C"
2884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *WRAP(signal)(int signum, void *handler) {
2894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  if (!AsanInterceptsSignal(signum)) {
2904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany    return real_signal(signum, handler);
2914803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  }
2924803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return NULL;
2934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
2944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
2954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C"
29673248e304bfa86596c667b30feda0bf3c61f6ac9Kostya Serebryanyextern int (sigaction)(int signum, const void *act, void *oldact);
29773248e304bfa86596c667b30feda0bf3c61f6ac9Kostya Serebryany
29873248e304bfa86596c667b30feda0bf3c61f6ac9Kostya Serebryanyextern "C"
299547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyint WRAP(sigaction)(int signum, const void *act, void *oldact) {
3004803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  if (!AsanInterceptsSignal(signum)) {
3014803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany    return real_sigaction(signum, act, oldact);
3024803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  }
3034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
3044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3064803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3074803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void UnpoisonStackFromHereToTop() {
3084803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  int local_stack;
3094803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
3104803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  CHECK(curr_thread);
3114803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  uintptr_t top = curr_thread->stack_top();
3124803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1);
3134803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  PoisonShadow(bottom, top - bottom, 0);
3144803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3154803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3164803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(longjmp)(void *env, int val) {
3174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  UnpoisonStackFromHereToTop();
3184803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  real_longjmp(env, val);
3194803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3204803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3214803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(_longjmp)(void *env, int val) {
3224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  UnpoisonStackFromHereToTop();
3234803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  real__longjmp(env, val);
3244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3264803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(siglongjmp)(void *env, int val) {
3274803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  UnpoisonStackFromHereToTop();
3284803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  real_siglongjmp(env, val);
3294803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3304803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3314803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void __cxa_throw(void *a, void *b, void *c);
3324803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3334803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#if ASAN_HAS_EXCEPTIONS == 1
3344803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(__cxa_throw)(void *a, void *b, void *c) {
3354803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  CHECK(&real___cxa_throw);
3364803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  UnpoisonStackFromHereToTop();
3374803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  real___cxa_throw(a, b, c);
3384803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3394803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif
3404803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3414803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" {
3424803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// intercept mlock and friends.
3434803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
3444803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// All functions return 0 (success).
3454803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void MlockIsUnsupported() {
3464803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  static bool printed = 0;
3474803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  if (printed) return;
3484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  printed = true;
3494803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
3504803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3514803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlock(const void *addr, size_t len) {
3524803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
3534803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
3544803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlock(const void *addr, size_t len) {
3564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
3574803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
3584803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3594803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlockall(int flags) {
3604803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
3614803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
3624803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3634803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlockall(void) {
3644803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
3654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
3664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3674803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}  // extern "C"
3684803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3694803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3704803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
37152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCmp(unsigned char c1, unsigned char c2) {
37252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
37352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany}
37452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany
37552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
37652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  int c1_low = tolower(c1);
37752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  int c2_low = tolower(c2);
37852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  return c1_low - c2_low;
37952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany}
38052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany
38120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
38252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanyint WRAP(memcmp)(const void *a1, const void *a2, size_t size) {
38352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  ENSURE_ASAN_INITED();
38452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  unsigned char c1 = 0, c2 = 0;
38552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  const unsigned char *s1 = (const unsigned char*)a1;
38652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  const unsigned char *s2 = (const unsigned char*)a2;
38752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  size_t i;
38852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  for (i = 0; i < size; i++) {
38952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany    c1 = s1[i];
39052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany    c2 = s2[i];
39152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany    if (c1 != c2) break;
39252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  }
39352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  ASAN_READ_RANGE(s1, Min(i + 1, size));
39452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  ASAN_READ_RANGE(s2, Min(i + 1, size));
39552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  return CharCmp(c1, c2);
39652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany}
39752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany
39820688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
3991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *WRAP(memcpy)(void *to, const void *from, size_t size) {
4001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // memcpy is called during __asan_init() from the internals
4011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // of printf(...).
4021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
4031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return real_memcpy(to, from, size);
4041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
405e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_intrin) {
407c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);
4081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(from, size);
4091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(to, size);
4101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
4111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return real_memcpy(to, from, size);
4121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
41420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
4151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *WRAP(memmove)(void *to, const void *from, size_t size) {
416e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_intrin) {
4181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(from, size);
4191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(to, size);
4201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
4211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return real_memmove(to, from, size);
4221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
42420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
4251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *WRAP(memset)(void *block, int c, size_t size) {
426e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  // memset is called inside INTERCEPT_FUNCTION on Mac.
427e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  if (asan_init_is_running) {
428e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    return real_memset(block, c, size);
429e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  }
430e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_intrin) {
4321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(block, size);
4331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
4341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return real_memset(block, c, size);
4351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
4371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef __APPLE__
43820688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
4391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(index)(const char *str, int c)
4401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  __attribute__((alias(WRAPPER_NAME(strchr))));
4411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif
4421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
44320688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
4441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strchr)(const char *str, int c) {
445e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  char *result = real_strchr(str, c);
4471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
4481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t bytes_read = (result ? result - str : real_strlen(str)) + 1;
4491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(str, bytes_read);
4501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
4511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return result;
4521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
45420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
455af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanyint WRAP(strcasecmp)(const char *s1, const char *s2) {
456af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ENSURE_ASAN_INITED();
457af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  unsigned char c1, c2;
458af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  size_t i;
459af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  for (i = 0; ; i++) {
460af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c1 = (unsigned char)s1[i];
461af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c2 = (unsigned char)s2[i];
462af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
463af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  }
464af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ASAN_READ_RANGE(s1, i + 1);
465af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ASAN_READ_RANGE(s2, i + 1);
466af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  return CharCaseCmp(c1, c2);
467af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany}
468af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany
46920688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
4700985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanychar *WRAP(strcat)(char *to, const char *from) {  // NOLINT
4710985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  ENSURE_ASAN_INITED();
4720985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  if (FLAG_replace_str) {
4730985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    size_t from_length = real_strlen(from);
4740985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    ASAN_READ_RANGE(from, from_length + 1);
4750985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    if (from_length > 0) {
4760985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany      size_t to_length = real_strlen(to);
4770985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany      ASAN_READ_RANGE(to, to_length);
4780985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany      ASAN_WRITE_RANGE(to + to_length, from_length + 1);
479c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany      CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1);
4800985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    }
4810985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  }
4820985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  return real_strcat(to, from);
4830985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany}
4840985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany
48520688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
4861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(strcmp)(const char *s1, const char *s2) {
4871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strcmp is called from malloc_default_purgeable_zone()
4881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
4891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
4901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return real_strcmp(s1, s2);
4911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
4921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  unsigned char c1, c2;
4931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i;
4941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (i = 0; ; i++) {
4951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c1 = (unsigned char)s1[i];
4961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c2 = (unsigned char)s2[i];
4971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (c1 != c2 || c1 == '\0') break;
4981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
4991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ASAN_READ_RANGE(s1, i + 1);
5001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ASAN_READ_RANGE(s2, i + 1);
5011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return CharCmp(c1, c2);
5021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
50420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
5051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strcpy)(char *to, const char *from) {  // NOLINT
5061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strcpy is called from malloc_default_purgeable_zone()
5071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
5081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
5091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return real_strcpy(to, from);
5101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
511e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
5131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t from_size = real_strlen(from) + 1;
514c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
5151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(from, from_size);
5161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(to, from_size);
5171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return real_strcpy(to, from);
5191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
52120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
5221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strdup)(const char *s) {
523e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
5251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t length = real_strlen(s);
5261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(s, length + 1);
5271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return real_strdup(s);
5291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
53120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
5321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t WRAP(strlen)(const char *s) {
5331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strlen is called from malloc_default_purgeable_zone()
5341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
5351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
5361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return real_strlen(s);
5371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
538e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t length = real_strlen(s);
5401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
5411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(s, length + 1);
5421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return length;
5441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
54620688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
547af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanyint WRAP(strncasecmp)(const char *s1, const char *s2, size_t size) {
548af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ENSURE_ASAN_INITED();
549af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  unsigned char c1 = 0, c2 = 0;
550af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  size_t i;
551af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  for (i = 0; i < size; i++) {
552af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c1 = (unsigned char)s1[i];
553af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c2 = (unsigned char)s2[i];
554af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
555af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  }
556af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ASAN_READ_RANGE(s1, Min(i + 1, size));
557af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ASAN_READ_RANGE(s2, Min(i + 1, size));
558af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  return CharCaseCmp(c1, c2);
559af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany}
560af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany
56120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
5621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(strncmp)(const char *s1, const char *s2, size_t size) {
5631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strncmp is called from malloc_default_purgeable_zone()
5641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
5651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
5661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    return real_strncmp(s1, s2, size);
5671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  unsigned char c1 = 0, c2 = 0;
5691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i;
5701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (i = 0; i < size; i++) {
5711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c1 = (unsigned char)s1[i];
5721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c2 = (unsigned char)s2[i];
5731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (c1 != c2 || c1 == '\0') break;
5741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5752d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany  ASAN_READ_RANGE(s1, Min(i + 1, size));
5762d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany  ASAN_READ_RANGE(s2, Min(i + 1, size));
5771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return CharCmp(c1, c2);
5781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
58020688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
5811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strncpy)(char *to, const char *from, size_t size) {
582e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
5842d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany    size_t from_size = Min(size, internal_strnlen(from, size) + 1);
585c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
5861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(from, from_size);
5871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(to, size);
5881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return real_strncpy(to, from, size);
5901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
5921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef __APPLE__
59320688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C"
5941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t WRAP(strnlen)(const char *s, size_t maxlen) {
595e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t length = real_strnlen(s, maxlen);
5971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
5982d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany    ASAN_READ_RANGE(s, Min(length + 1, maxlen));
5991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
6001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return length;
6011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
602d66a8d8f56c66c9749b6d75c61870a121d4d9307Kostya Serebryany#endif
603547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
604547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1
605547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan {
606547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() {
607547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#ifndef __APPLE__
608547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(index);
609547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#else
610547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  OVERRIDE_FUNCTION(index, WRAP(strchr));
611547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif
612547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(memcmp);
613547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(memcpy);
614547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(memmove);
615547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(memset);
616547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strcasecmp);
617547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strcat);  // NOLINT
618547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strchr);
619547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strcmp);
620547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strcpy);  // NOLINT
621547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strdup);
622547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strlen);
623547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strncasecmp);
624547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strncmp);
625547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strncpy);
626547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
627547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(sigaction);
628547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(signal);
629547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(longjmp);
630547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(_longjmp);
631547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw);
632547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(pthread_create);
633547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
634547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#ifdef __APPLE__
635547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(dispatch_async_f);
636547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(dispatch_sync_f);
637547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(dispatch_after_f);
638547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(dispatch_barrier_async_f);
639547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(dispatch_group_async_f);
640547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  // We don't need to intercept pthread_workqueue_additem_np() to support the
641547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  // libdispatch API, but it helps us to debug the unsupported functions. Let's
642547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  // intercept it only during verbose runs.
643547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  if (FLAG_v >= 2) {
644547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany    INTERCEPT_FUNCTION(pthread_workqueue_additem_np);
645547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  }
646547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#else
647547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
648547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  // there.
649547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(siglongjmp);
650547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif
651547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
652547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#ifndef __APPLE__
653547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  INTERCEPT_FUNCTION(strnlen);
654547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif
655547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  if (FLAG_v > 0) {
656547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany    Printf("AddressSanitizer: libc interceptors initialized\n");
657547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  }
658547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany}
659547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
660547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany}  // namespace __asan
661