asan_interceptors.cc revision 619e8bf99d2714c4411fefba22d54c233d93a177
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"
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h"
201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h"
211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h"
224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include "asan_thread_registry.h"
235b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov#include "interception/interception.h"
241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov// Use macro to describe if specific function should be
2684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov// intercepted on a given platform.
27670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#if !defined(_WIN32)
28847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1
29670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#else
30847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
31670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#endif
32670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov
33670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#if !defined(__APPLE__)
34670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov# define ASAN_INTERCEPT_STRNLEN 1
35670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#else
36670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov# define ASAN_INTERCEPT_STRNLEN 0
37670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#endif
3884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov
3934a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if defined(ANDROID) || defined(_WIN32)
4034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov# define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 0
4134a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#else
4234a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov# define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1
4334a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#endif
4434a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov
454e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// Use extern declarations of intercepted functions on Mac and Windows
464e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// to avoid including system headers.
474e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov#if defined(__APPLE__) || (defined(_WIN32) && !defined(_DLL))
486ebea222e306fbe53aab78d7781e5ac19be46b5dAlexey Samsonovextern "C" {
4973fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonov// signal.h
5034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov# if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
5173fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonovstruct sigaction;
5273fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonovint sigaction(int sig, const struct sigaction *act,
5373fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonov              struct sigaction *oldact);
5473fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonovvoid *signal(int signum, void *handler);
554e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif
566ebea222e306fbe53aab78d7781e5ac19be46b5dAlexey Samsonov
574e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// setjmp.h
584e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid longjmp(void* env, int value);
594e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# if !defined(_WIN32)
604e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid _longjmp(void *env, int value);
614e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif
622716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov
634e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// string.h / strings.h
644e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovint memcmp(const void *a1, const void *a2, size_t size);
654e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid* memmove(void *to, const void *from, size_t size);
664e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid* memcpy(void *to, const void *from, size_t size);
674e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid* memset(void *block, int c, size_t size);
684e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strchr(const char *str, int c);
69d01c51d33a5b4c52160c0a6cc18f7739a0a137d3Alexey Samsonov# if defined(__APPLE__)
7056e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovchar* index(const char *string, int c);
714e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif
724e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strcat(char *to, const char* from);  // NOLINT
734e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strcpy(char *to, const char* from);  // NOLINT
744e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strncpy(char *to, const char* from, size_t size);
752716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanovint strcmp(const char *s1, const char* s2);
764e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovint strncmp(const char *s1, const char* s2, size_t size);
7756e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonov# if !defined(_WIN32)
7856e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovint strcasecmp(const char *s1, const char *s2);
7956e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovint strncasecmp(const char *s1, const char *s2, size_t n);
8056e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovchar* strdup(const char *s);
8156e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonov# endif
8256e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovsize_t strlen(const char *s);
8381a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov# if ASAN_INTERCEPT_STRNLEN
844e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovsize_t strnlen(const char *s, size_t maxlen);
854e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif
862716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov
8784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov// stdlib.h
88847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonovint atoi(const char *nptr);
89847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonovlong atol(const char *nptr);  // NOLINT
908f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovlong strtol(const char *nptr, char **endptr, int base);  // NOLINT
91847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov# if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
92847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonovlong long atoll(const char *nptr);  // NOLINT
9384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonovlong long strtoll(const char *nptr, char **endptr, int base);  // NOLINT
9484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov# endif
9584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov
964e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// Windows threads.
974e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# if defined(_WIN32)
982716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov__declspec(dllimport)
992716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanovvoid* __stdcall CreateThread(void *sec, size_t st, void* start,
1002716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov                             void *arg, DWORD fl, DWORD *id);
1014e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif
102a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov
103a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov// Posix threads.
104a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov# if !defined(_WIN32)
105a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonovint pthread_create(void *thread, void *attr, void *(*start_routine)(void*),
106a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov                   void *arg);
107a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov# endif
1082716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov}  // extern "C"
1092716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov#endif
1102716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov
1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a single byte in memory.
1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// On error calls __asan_report_error, which aborts the program.
1159f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany#define ACCESS_ADDRESS(address, isWrite)   do {         \
1169f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany  if (AddressIsPoisoned(address)) {                     \
1179f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany    GET_CURRENT_PC_BP_SP;                               \
1189f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany    __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \
1199f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany  } \
1209f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany} while (0)
1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// and ASAN_WRITE_RANGE as macro instead of function so
1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// that no extra frames are created, and stack trace contains
1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// relevant information only.
1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a memory range.
1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// More complex implementation is possible, for now just
1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// checking the first and the last byte of a range.
1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (size > 0) { \
1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    uintptr_t ptr = (uintptr_t)(offset); \
1339f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany    ACCESS_ADDRESS(ptr, isWrite); \
1349f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany    ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \
1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  } \
136e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_READ_RANGE(offset, size) do { \
1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ACCESS_MEMORY_RANGE(offset, size, false); \
140e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_WRITE_RANGE(offset, size) do { \
1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ACCESS_MEMORY_RANGE(offset, size, true); \
144e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Behavior of functions like "memcpy" or "strcpy" is undefined
1471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// if memory intervals overlap. We report error in this case.
1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Macro is used to avoid creation of new frames.
1490985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanystatic inline bool RangesOverlap(const char *offset1, size_t length1,
1500985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany                                 const char *offset2, size_t length2) {
1510985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
153c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const char *offset1 = (const char*)_offset1; \
1551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const char *offset2 = (const char*)_offset2; \
1560985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  if (RangesOverlap(offset1, length1, offset2, length2)) { \
157c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    Report("ERROR: AddressSanitizer %s-param-overlap: " \
1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany           "memory ranges [%p,%p) and [%p, %p) overlap\n", \
159c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany           name, offset1, offset1 + length1, offset2, offset2 + length2); \
1601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    PRINT_CURRENT_STACK(); \
1611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ShowStatsAndAbort(); \
1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  } \
163e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
165e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany#define ENSURE_ASAN_INITED() do { \
166e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  CHECK(!asan_init_is_running); \
167e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  if (!asan_inited) { \
168e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany    __asan_init(); \
169e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  } \
170e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0)
1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1728898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovstatic inline bool IsSpace(int c) {
1738898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  return (c == ' ') || (c == '\n') || (c == '\t') ||
1748898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov         (c == '\f') || (c == '\r') || (c == '\v');
1758898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov}
1768898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov
1778898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovstatic inline bool IsDigit(int c) {
1788898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  return (c >= '0') && (c <= '9');
1798898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov}
1808898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov
1818898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovstatic inline int ToLower(int c) {
1828898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
1838898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov}
1848898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov
1858898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov// ---------------------- Internal string functions ---------------- {{{1
1868898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov
1878898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovint64_t internal_simple_strtoll(const char *nptr, char **endptr, int base) {
1888898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  CHECK(base == 10);
1898898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  while (IsSpace(*nptr)) nptr++;
1908898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  int sgn = 1;
1918898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  uint64_t res = 0;
1928898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  bool have_digits = false;
1938898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  char *old_nptr = (char*)nptr;
1948898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  if (*nptr == '+') {
1958898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    sgn = 1;
1968898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    nptr++;
1978898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  } else if (*nptr == '-') {
1988898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    sgn = -1;
1998898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    nptr++;
2008898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  }
2018898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  while (IsDigit(*nptr)) {
202e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
2038898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    int digit = ((*nptr) - '0');
204e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
2058898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    have_digits = true;
2068898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    nptr++;
2078898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  }
2088898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  if (endptr != NULL) {
2098898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov    *endptr = (have_digits) ? (char*)nptr : old_nptr;
2108898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  }
2118898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  if (sgn > 0) {
212e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov    return (int64_t)(Min((uint64_t)INT64_MAX, res));
2138898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  } else {
214e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov    return (res > INT64_MAX) ? INT64_MIN : ((int64_t)res * -1);
2158898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  }
2168898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov}
2178898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov
2188898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovint64_t internal_atoll(const char *nptr) {
2198898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  return internal_simple_strtoll(nptr, (char**)NULL, 10);
2208898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov}
2218898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov
2221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strlen(const char *s) {
2231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i = 0;
2241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  while (s[i]) i++;
2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return i;
2261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strnlen(const char *s, size_t maxlen) {
22981a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN
23009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  if (REAL(strnlen) != NULL) {
23109672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    return REAL(strnlen)(s, maxlen);
2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
233f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#endif
2341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i = 0;
2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  while (i < maxlen && s[i]) i++;
2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return i;
2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2395362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanovchar* internal_strchr(const char *s, int c) {
2405362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov  while (true) {
2415362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov    if (*s == (char)c)
2425362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov      return (char*)s;
2435362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov    if (*s == 0)
2445362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov      return NULL;
2455362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov    s++;
2465362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov  }
2475362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov}
2485362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov
249de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid* internal_memchr(const void* s, int c, size_t n) {
250de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  const char* t = (char*)s;
251de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  for (size_t i = 0; i < n; ++i, ++t)
252de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany    if (*t == c)
253de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany      return (void*)t;
254de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  return NULL;
255de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany}
256de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
257de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint internal_memcmp(const void* s1, const void* s2, size_t n) {
258de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  const char* t1 = (char*)s1;
259de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  const char* t2 = (char*)s2;
260de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  for (size_t i = 0; i < n; ++i, ++t1, ++t2)
261de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany    if (*t1 != *t2)
262de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany      return *t1 < *t2 ? -1 : 1;
263de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany  return 0;
264de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany}
265de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany
266ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko// Should not be used in performance-critical places.
267ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenkovoid* internal_memset(void* s, int c, size_t n) {
268ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  // The next line prevents Clang from making a call to memset() instead of the
269ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  // loop below.
270ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  // FIXME: building the runtime with -ffreestanding is a better idea. However
271ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  // there currently are linktime problems due to PR12396.
272ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  char volatile *t = (char*)s;
273ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  for (size_t i = 0; i < n; ++i, ++t) {
274ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko    *t = c;
275ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  }
276ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  return s;
277ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko}
278ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko
279a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strstr(const char *haystack, const char *needle) {
280a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  // This is O(N^2), but we are not using it in hot places.
281a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t len1 = internal_strlen(haystack);
282a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t len2 = internal_strlen(needle);
283a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  if (len1 < len2) return 0;
284a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  for (size_t pos = 0; pos <= len1 - len2; pos++) {
285a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany    if (internal_memcmp(haystack + pos, needle, len2) == 0)
286a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany      return (char*)haystack + pos;
287a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  }
288a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  return 0;
289a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany}
290a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany
291a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strncat(char *dst, const char *src, size_t n) {
292a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t len = internal_strlen(dst);
293a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  size_t i;
294a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  for (i = 0; i < n && src[i]; i++)
295a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany    dst[len + i] = src[i];
296a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  dst[len + i] = 0;
297a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany  return dst;
298a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany}
2991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
300f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryanyint internal_strcmp(const char *s1, const char *s2) {
301f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany  while (true) {
302f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    unsigned c1 = *s1;
303f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    unsigned c2 = *s2;
304f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    if (c1 != c2) return (c1 < c2) ? -1 : 1;
305f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    if (c1 == 0) break;
306f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    s1++;
307f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    s2++;
308f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany  }
309f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany  return 0;
310f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany}
311f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany
3123fe913558354f76707e2c5584559521399854b79Alexander Potapenkochar *internal_strncpy(char *dst, const char *src, size_t n) {
3133fe913558354f76707e2c5584559521399854b79Alexander Potapenko  size_t i;
3143fe913558354f76707e2c5584559521399854b79Alexander Potapenko  for (i = 0; i < n && src[i]; i++)
3153fe913558354f76707e2c5584559521399854b79Alexander Potapenko    dst[i] = src[i];
3163fe913558354f76707e2c5584559521399854b79Alexander Potapenko  return dst;
3173fe913558354f76707e2c5584559521399854b79Alexander Potapenko}
3183fe913558354f76707e2c5584559521399854b79Alexander Potapenko
3191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}  // namespace __asan
3201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
3211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Wrappers ---------------- {{{1
3221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan;  // NOLINT
3231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
324600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
3254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  AsanThread *t = (AsanThread*)arg;
3264803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  asanThreadRegistry().SetCurrent(t);
3274803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return t->ThreadStart();
3284803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3294803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3306f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#ifndef _WIN32
331b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy StepanovINTERCEPTOR(int, pthread_create, void *thread,
332b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy Stepanov    void *attr, void *(*start_routine)(void*), void *arg) {
3339cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  GET_STACK_TRACE_HERE(kStackTraceMax);
3344803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
33555cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov  AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
33655cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov  asanThreadRegistry().RegisterThread(t);
33709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(pthread_create)(thread, attr, asan_thread_start, t);
3384803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
339919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif  // !_WIN32
3404803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
34134a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
342f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, signal, int signum, void *handler) {
343034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko  if (!AsanInterceptsSignal(signum)) {
344034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko    return REAL(signal)(signum, handler);
3454803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  }
346034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko  return NULL;
3474803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
349da13ba833b046553f50b54538e4828287ddbf5c0Alexey SamsonovINTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
350da13ba833b046553f50b54538e4828287ddbf5c0Alexey Samsonov                            struct sigaction *oldact) {
351034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko  if (!AsanInterceptsSignal(signum)) {
352034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko    return REAL(sigaction)(signum, act, oldact);
3534803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  }
354034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko  return 0;
3554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
35634a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#elif ASAN_POSIX
35734a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov// We need to have defined REAL(sigaction) on posix systems.
35834a3202a2c22816a6da66959e266a2d078ded37bAlexey SamsonovDEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
35934a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov    struct sigaction *oldact);
36034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#endif  // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
3614803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
362f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, longjmp, void *env, int val) {
363f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany  __asan_handle_no_return();
36409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  REAL(longjmp)(env, val);
3654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
36707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32)
368f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, _longjmp, void *env, int val) {
369f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany  __asan_handle_no_return();
37009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  REAL(_longjmp)(env, val);
3714803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3724803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
373f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, siglongjmp, void *env, int val) {
374f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany  __asan_handle_no_return();
37509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  REAL(siglongjmp)(env, val);
3764803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
37707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif
3784803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3793389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov#if ASAN_HAS_EXCEPTIONS == 1
3803389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov#ifdef __APPLE__
3814803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void __cxa_throw(void *a, void *b, void *c);
3823389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov#endif  // __APPLE__
3834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
384f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
38509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  CHECK(REAL(__cxa_throw));
386f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany  __asan_handle_no_return();
38709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  REAL(__cxa_throw)(a, b, c);
3884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
3894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif
3904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
3914803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// intercept mlock and friends.
3924803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
3934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// All functions return 0 (success).
3944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void MlockIsUnsupported() {
3954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  static bool printed = 0;
3964803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  if (printed) return;
3974803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  printed = true;
3984803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
3994803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
4003389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov
401f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonovextern "C" {
4023389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE
4034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlock(const void *addr, size_t len) {
4044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
4054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
4064803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
4073389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov
4083389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE
4094803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlock(const void *addr, size_t len) {
4104803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
4114803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
4124803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
4133389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov
4143389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE
4154803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlockall(int flags) {
4164803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
4174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
4184803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
4193389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov
4203389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE
4214803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlockall(void) {
4224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  MlockIsUnsupported();
4234803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return 0;
4244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
4254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}  // extern "C"
4264803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
42752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCmp(unsigned char c1, unsigned char c2) {
42852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
42952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany}
43052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany
43152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
4328898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  int c1_low = ToLower(c1);
4338898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov  int c2_low = ToLower(c2);
43452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  return c1_low - c2_low;
43552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany}
43652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany
437f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, memcmp, const void *a1, const void *a2, size_t size) {
43852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  ENSURE_ASAN_INITED();
43952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  unsigned char c1 = 0, c2 = 0;
44052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  const unsigned char *s1 = (const unsigned char*)a1;
44152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  const unsigned char *s2 = (const unsigned char*)a2;
44252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  size_t i;
44352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  for (i = 0; i < size; i++) {
44452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany    c1 = s1[i];
44552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany    c2 = s2[i];
44652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany    if (c1 != c2) break;
44752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  }
44852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  ASAN_READ_RANGE(s1, Min(i + 1, size));
44952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  ASAN_READ_RANGE(s2, Min(i + 1, size));
45052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany  return CharCmp(c1, c2);
45152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany}
45252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany
453f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, memcpy, void *to, const void *from, size_t size) {
4541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // memcpy is called during __asan_init() from the internals
4551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // of printf(...).
4561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
45709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    return REAL(memcpy)(to, from, size);
4581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
459e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_intrin) {
461c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany    if (to != from) {
462c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany      // We do not treat memcpy with to==from as a bug.
463c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany      // See http://llvm.org/bugs/show_bug.cgi?id=11763.
464c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany      CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);
465c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany    }
4661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(from, size);
4671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(to, size);
4681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
46909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(memcpy)(to, from, size);
4701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
472f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) {
473e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_intrin) {
4751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(from, size);
4761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(to, size);
4771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
47809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(memmove)(to, from, size);
4791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
481f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, memset, void *block, int c, size_t size) {
482ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko  // memset is called inside Printf.
483e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  if (asan_init_is_running) {
48409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    return REAL(memset)(block, c, size);
485e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  }
486e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
4871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_intrin) {
4881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(block, size);
4891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
49009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(memset)(block, c, size);
4911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
4921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
493f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strchr, const char *str, int c) {
494e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
49509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  char *result = REAL(strchr)(str, c);
4961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
49709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1;
4981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(str, bytes_read);
4991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return result;
5011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
503adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov#ifdef __linux__
5044b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovINTERCEPTOR(char*, index, const char *string, int c)
505adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov  ALIAS(WRAPPER_NAME(strchr));
506f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#else
5074b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovDEFINE_REAL(char*, index, const char *string, int c);
508f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#endif
509f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov
510f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
511af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ENSURE_ASAN_INITED();
512af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  unsigned char c1, c2;
513af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  size_t i;
514af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  for (i = 0; ; i++) {
515af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c1 = (unsigned char)s1[i];
516af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c2 = (unsigned char)s2[i];
517af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
518af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  }
519af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ASAN_READ_RANGE(s1, i + 1);
520af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ASAN_READ_RANGE(s2, i + 1);
521af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  return CharCaseCmp(c1, c2);
522af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany}
523af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany
524f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcat, char *to, const char *from) {  // NOLINT
5250985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  ENSURE_ASAN_INITED();
5260985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  if (FLAG_replace_str) {
52709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    size_t from_length = REAL(strlen)(from);
5280985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    ASAN_READ_RANGE(from, from_length + 1);
5290985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    if (from_length > 0) {
53009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov      size_t to_length = REAL(strlen)(to);
5310985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany      ASAN_READ_RANGE(to, to_length);
5320985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany      ASAN_WRITE_RANGE(to + to_length, from_length + 1);
533c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany      CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1);
5340985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany    }
5350985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany  }
53609672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(strcat)(to, from);  // NOLINT
5370985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany}
5380985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany
539f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
540f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany  if (!asan_inited) {
541f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany    return internal_strcmp(s1, s2);
5421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  unsigned char c1, c2;
5441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i;
5451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (i = 0; ; i++) {
5461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c1 = (unsigned char)s1[i];
5471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c2 = (unsigned char)s2[i];
5481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (c1 != c2 || c1 == '\0') break;
5491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ASAN_READ_RANGE(s1, i + 1);
5511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  ASAN_READ_RANGE(s2, i + 1);
5521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return CharCmp(c1, c2);
5531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
555f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcpy, char *to, const char *from) {  // NOLINT
5561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strcpy is called from malloc_default_purgeable_zone()
5571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
5581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
55909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    return REAL(strcpy)(to, from);  // NOLINT
5601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
561e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
56309672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    size_t from_size = REAL(strlen)(from) + 1;
564c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
5651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(from, from_size);
5661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(to, from_size);
5671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
56809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(strcpy)(to, from);  // NOLINT
5691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
571f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strdup, const char *s) {
572e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
5731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
57409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    size_t length = REAL(strlen)(s);
5751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(s, length + 1);
5761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
57709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(strdup)(s);
5781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
580f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(size_t, strlen, const char *s) {
5811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strlen is called from malloc_default_purgeable_zone()
5821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
5831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
58409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    return REAL(strlen)(s);
5851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
586e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
58709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  size_t length = REAL(strlen)(s);
5881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
5891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(s, length + 1);
5901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
5911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return length;
5921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
5931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
594f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, size_t n) {
595af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  ENSURE_ASAN_INITED();
596af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  unsigned char c1 = 0, c2 = 0;
597af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  size_t i;
598f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov  for (i = 0; i < n; i++) {
599af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c1 = (unsigned char)s1[i];
600af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    c2 = (unsigned char)s2[i];
601af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
602af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  }
603f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov  ASAN_READ_RANGE(s1, Min(i + 1, n));
604f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov  ASAN_READ_RANGE(s2, Min(i + 1, n));
605af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany  return CharCaseCmp(c1, c2);
606af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany}
607af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany
608f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strncmp, const char *s1, const char *s2, size_t size) {
6091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // strncmp is called from malloc_default_purgeable_zone()
6101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // in __asan::ReplaceSystemAlloc() on Mac.
6111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (asan_init_is_running) {
61209672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    return REAL(strncmp)(s1, s2, size);
6131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
6141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  unsigned char c1 = 0, c2 = 0;
6151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i;
6161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (i = 0; i < size; i++) {
6171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c1 = (unsigned char)s1[i];
6181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    c2 = (unsigned char)s2[i];
6191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (c1 != c2 || c1 == '\0') break;
6201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
6212d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany  ASAN_READ_RANGE(s1, Min(i + 1, size));
6222d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany  ASAN_READ_RANGE(s2, Min(i + 1, size));
6231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return CharCmp(c1, c2);
6241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
6251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
626f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strncpy, char *to, const char *from, size_t size) {
627e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
6281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
6292d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany    size_t from_size = Min(size, internal_strnlen(from, size) + 1);
630c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany    CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
6311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_READ_RANGE(from, from_size);
6321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    ASAN_WRITE_RANGE(to, size);
6331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
63409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  return REAL(strncpy)(to, from, size);
6351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
6361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
63781a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN
638f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) {
639e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany  ENSURE_ASAN_INITED();
64009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov  size_t length = REAL(strnlen)(s, maxlen);
6411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  if (FLAG_replace_str) {
6422d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany    ASAN_READ_RANGE(s, Min(length + 1, maxlen));
6431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
6441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return length;
6451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
64681a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#endif  // ASAN_INTERCEPT_STRNLEN
647547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
6488f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline bool IsValidStrtolBase(int base) {
6498f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  return (base == 0) || (2 <= base && base <= 36);
6508f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov}
6518f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov
6528f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
6538f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  CHECK(endptr != NULL);
6548f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  if (nptr == *endptr) {
6558f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    // No digits were found at strtol call, we need to find out the last
6568f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    // symbol accessed by strtoll on our own.
6578f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    // We get this symbol by skipping leading blanks and optional +/- sign.
6588f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    while (IsSpace(*nptr)) nptr++;
6598f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    if (*nptr == '+' || *nptr == '-') nptr++;
6608f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    *endptr = (char*)nptr;
6618f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  }
6628f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  CHECK(*endptr >= nptr);
66384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov}
66484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov
665847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, strtol, const char *nptr,  // NOLINT
66684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov            char **endptr, int base) {
66784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  ENSURE_ASAN_INITED();
66884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  if (!FLAG_replace_str) {
669847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov    return REAL(strtol)(nptr, endptr, base);
67084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  }
67184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  char *real_endptr;
672847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  long result = REAL(strtol)(nptr, &real_endptr, base);  // NOLINT
67384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  if (endptr != NULL) {
67484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov    *endptr = real_endptr;
67584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  }
6768f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  if (IsValidStrtolBase(base)) {
6778f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    FixRealStrtolEndptr(nptr, &real_endptr);
67884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov    ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
67984ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  }
68084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov  return result;
68184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov}
68284ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov
683847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(int, atoi, const char *nptr) {
684847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  ENSURE_ASAN_INITED();
685847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  if (!FLAG_replace_str) {
686847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov    return REAL(atoi)(nptr);
687847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  }
688847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  char *real_endptr;
689847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // "man atoi" tells that behavior of atoi(nptr) is the same as
690847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // strtol(nptr, NULL, 10), i.e. it sets errno to ERANGE if the
691847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // parsed integer can't be stored in *long* type (even if it's
692847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // different from int). So, we just imitate this behavior.
693847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  int result = REAL(strtol)(nptr, &real_endptr, 10);
694847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  FixRealStrtolEndptr(nptr, &real_endptr);
695847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
696847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  return result;
697847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov}
698847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov
699847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, atol, const char *nptr) {  // NOLINT
700847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  ENSURE_ASAN_INITED();
701847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  if (!FLAG_replace_str) {
702847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov    return REAL(atol)(nptr);
703847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  }
704847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  char *real_endptr;
705847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  long result = REAL(strtol)(nptr, &real_endptr, 10);  // NOLINT
706847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  FixRealStrtolEndptr(nptr, &real_endptr);
707847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
708847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  return result;
709847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov}
710847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov
711847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
712847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, strtoll, const char *nptr,  // NOLINT
7138f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov            char **endptr, int base) {
7148f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  ENSURE_ASAN_INITED();
7158f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  if (!FLAG_replace_str) {
716847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov    return REAL(strtoll)(nptr, endptr, base);
7178f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  }
7188f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  char *real_endptr;
719847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  long long result = REAL(strtoll)(nptr, &real_endptr, base);  // NOLINT
7208f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  if (endptr != NULL) {
7218f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    *endptr = real_endptr;
7228f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  }
723847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // If base has unsupported value, strtoll can exit with EINVAL
724847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // without reading any characters. So do additional checks only
725847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  // if base is valid.
7268f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  if (IsValidStrtolBase(base)) {
7278f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    FixRealStrtolEndptr(nptr, &real_endptr);
7288f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov    ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
7298f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  }
7308f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov  return result;
7318f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov}
7328f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov
733847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, atoll, const char *nptr) {  // NOLINT
734847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  ENSURE_ASAN_INITED();
735847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  if (!FLAG_replace_str) {
736847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov    return REAL(atoll)(nptr);
737847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  }
738847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  char *real_endptr;
739847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  long long result = REAL(strtoll)(nptr, &real_endptr, 10);  // NOLINT
740847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  FixRealStrtolEndptr(nptr, &real_endptr);
741847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
742847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov  return result;
743847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov}
744847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#endif  // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
745847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov
746580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov#define ASAN_INTERCEPT_FUNC(name) do { \
747580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov      if (!INTERCEPT_FUNCTION(name) && FLAG_v > 0) \
748580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov        Report("AddressSanitizer: failed to intercept '" #name "'\n"); \
749580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov    } while (0)
750580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov
751600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32)
752600972e3427173cc8904d741decd1af0ed5de9fdTimur IskhodzhanovINTERCEPTOR_WINAPI(DWORD, CreateThread,
753600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov                   void* security, size_t stack_size,
754600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov                   DWORD (__stdcall *start_routine)(void*), void* arg,
755600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov                   DWORD flags, void* tid) {
756600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  GET_STACK_TRACE_HERE(kStackTraceMax);
757600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
758600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
759600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  asanThreadRegistry().RegisterThread(t);
760600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  return REAL(CreateThread)(security, stack_size,
761600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov                            asan_thread_start, t, flags, tid);
762600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov}
763600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov
764600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovnamespace __asan {
765600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovvoid InitializeWindowsInterceptors() {
766580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(CreateThread);
767600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov}
768600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov
769600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov}  // namespace __asan
770600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif
771600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov
772547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1
773547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan {
774547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() {
775fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany  static bool was_called_once;
776fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany  CHECK(was_called_once == false);
777fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany  was_called_once = true;
77807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // Intercept mem* functions.
779580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(memcmp);
780580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(memmove);
781580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(memset);
78238dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov  if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
783580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov    ASAN_INTERCEPT_FUNC(memcpy);
784573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko  } else {
78509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov    REAL(memcpy) = REAL(memmove);
786573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko  }
78707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov
78807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // Intercept str* functions.
789580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strcat);  // NOLINT
790580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strchr);
791580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strcmp);
792580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT
793580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strlen);
794580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strncmp);
795580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strncpy);
79607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32)
797580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strcasecmp);
798580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strdup);
799580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strncasecmp);
80007bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# ifndef __APPLE__
801580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(index);
80207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# else
803619e8bf99d2714c4411fefba22d54c233d93a177Meador Inge  CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr)));
80407bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# endif
80507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif
80681a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN
807580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strnlen);
80807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif
8095b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov
810580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(atoi);
811580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(atol);
812580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strtol);
813847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
814580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(atoll);
815580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(strtoll);
81684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov#endif
81784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov
81807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // Intecept signal- and jump-related functions.
819580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(longjmp);
82034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
821580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(sigaction);
822580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(signal);
823919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif
824919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov
82507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32)
826580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(_longjmp);
8275b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov  INTERCEPT_FUNCTION(__cxa_throw);
82807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# if !defined(__APPLE__)
82907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
83007bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // there.
831580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(siglongjmp);
83207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# endif
8333e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif
8343e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov
83507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // Intercept threading-related functions
83607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32)
837580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov  ASAN_INTERCEPT_FUNC(pthread_create);
83807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif
83907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov
840600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  // Some Windows-specific interceptors.
841600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32)
842600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov  InitializeWindowsInterceptors();
843600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif
844600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov
84507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov  // Some Mac-specific interceptors.
84607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if defined(__APPLE__)
847beba6448539095b67cab266d09cd7b7d313b8c3dAlexey Samsonov  InitializeMacInterceptors();
848547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif
849547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
850547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  if (FLAG_v > 0) {
8512962f26071ebef1d5fec52b5569e5ae7aae45c9bAlexander Potapenko    Report("AddressSanitizer: libc interceptors initialized\n");
852547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany  }
853547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany}
854547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany
855547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany}  // namespace __asan
856