178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===-- msan_interceptors.cc ----------------------------------------------===//
278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//                     The LLVM Compiler Infrastructure
478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// This file is distributed under the University of Illinois Open Source
678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// License. See LICENSE.TXT for details.
778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===----------------------------------------------------------------------===//
978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
1078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// This file is a part of MemorySanitizer.
1178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
1278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Interceptors for standard library functions.
138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
148530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// FIXME: move as many interceptors as possible into
158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// sanitizer_common/sanitizer_common_interceptors.h
1678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===----------------------------------------------------------------------===//
1778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "msan.h"
192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "msan_chained_origin_depot.h"
202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "msan_origin.h"
212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "msan_thread.h"
229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#include "sanitizer_common/sanitizer_platform_limits_posix.h"
2365199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany#include "sanitizer_common/sanitizer_allocator.h"
245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "sanitizer_common/sanitizer_allocator_interface.h"
25cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov#include "sanitizer_common/sanitizer_allocator_internal.h"
26e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov#include "sanitizer_common/sanitizer_atomic.h"
2778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_common.h"
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_interception.h"
29887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov#include "sanitizer_common/sanitizer_stackdepot.h"
3078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_libc.h"
31b9bf700ae7fe59e25976e0abe9636150f3a39cd2Evgeniy Stepanov#include "sanitizer_common/sanitizer_linux.h"
325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "sanitizer_common/sanitizer_tls_get_addr.h"
3378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include <stdarg.h>
3578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// ACHTUNG! No other system header includes in this file.
3678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Ideally, we should get rid of stdarg.h as well.
3778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovusing namespace __msan;
3978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
40e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::memory_order;
41e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::atomic_load;
42e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::atomic_store;
43e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::atomic_uintptr_t;
44e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov
45447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// True if this is a nested interceptor.
46447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovstatic THREADLOCAL int in_interceptor_scope;
47447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" int *__errno_location(void);
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
50447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovstruct InterceptorScope {
51447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  InterceptorScope() { ++in_interceptor_scope; }
52447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  ~InterceptorScope() { --in_interceptor_scope; }
53447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov};
54447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
55447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovbool IsInInterceptorScope() {
56447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  return in_interceptor_scope;
57447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
58447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
5978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#define ENSURE_MSAN_INITED() do { \
608028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  CHECK(!msan_init_is_running); \
6178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!msan_inited) { \
6278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_init(); \
6378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  } \
6478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} while (0)
6578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
66447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// Check that [x, x+n) range is unpoisoned.
67bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov#define CHECK_UNPOISONED_0(x, n)                                             \
68bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov  do {                                                                       \
69bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov    sptr offset = __msan_test_shadow(x, n);                                  \
70bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov    if (__msan::IsInSymbolizer()) break;                                     \
71bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov    if (offset >= 0 && __msan::flags()->report_umrs) {                       \
72bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov      GET_CALLER_PC_BP_SP;                                                   \
73bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov      (void) sp;                                                             \
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      ReportUMRInsideAddressRange(__func__, x, n, offset);                   \
75bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov      __msan::PrintWarningWithOrigin(pc, bp,                                 \
76bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov                                     __msan_get_origin((char *)x + offset)); \
77dbac0a4a41f405d10e3dcad3597fe08986605289Dmitry Vyukov      if (__msan::flags()->halt_on_error) {                                  \
78bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov        Printf("Exiting\n");                                                 \
79bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov        Die();                                                               \
80bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov      }                                                                      \
81bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov    }                                                                        \
8278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  } while (0)
8378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
84447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// Check that [x, x+n) range is unpoisoned unless we are in a nested
85447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// interceptor.
86341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define CHECK_UNPOISONED(x, n)                             \
87341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  do {                                                     \
88341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
89341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  } while (0);
90447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
916afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryanystatic void *fast_memset(void *ptr, int c, SIZE_T n);
926afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryanystatic void *fast_memcpy(void *dst, const void *src, SIZE_T n);
9378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
946afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
9578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
966afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
9778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
9878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(ptr, res *size);
9978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
10078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
10178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1026afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
10378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov            void *file) {
10478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
1056afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
10678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
10778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(ptr, res *size);
10878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
10978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
11078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1116afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
11278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
1136afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
11478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
11578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(buf, res);
11678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
11778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
11878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1196afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
12078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return __msan_memcpy(dest, src, n);
12178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
12278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
123353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy StepanovINTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
124353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  return (char *)__msan_memcpy(dest, src, n) + n;
125353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov}
126353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov
1275492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy StepanovINTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
1285492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  ENSURE_MSAN_INITED();
1295492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  void *res = REAL(memccpy)(dest, src, c, n);
1305492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  CHECK(!res || (res >= dest && res <= (char *)dest + n));
1315492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  SIZE_T sz = res ? (char *)res - (char *)dest : n;
1325492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  CHECK_UNPOISONED(src, sz);
1335492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  __msan_unpoison(dest, sz);
1345492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  return res;
1355492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov}
1365492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov
1376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
13878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return __msan_memmove(dest, src, n);
13978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
14078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1416afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
14278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return __msan_memset(s, c, n);
14378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
14478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
145ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
146ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return __msan_memmove(dest, src, n);
147ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
148ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1496afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
15078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
15178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_EQ(alignment & (alignment - 1), 0);
15278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_NE(memptr, 0);
153b6c8e47a72d526232f4d3e3b36232f30f8818733Evgeniy Stepanov  *memptr = MsanReallocate(&stack, 0, size, alignment, false);
154b6c8e47a72d526232f4d3e3b36232f30f8818733Evgeniy Stepanov  CHECK_NE(*memptr, 0);
155b6c8e47a72d526232f4d3e3b36232f30f8818733Evgeniy Stepanov  __msan_unpoison(memptr, sizeof(*memptr));
15678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return 0;
15778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
15878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
15997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy StepanovINTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) {
16097160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
16197160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  CHECK_EQ(boundary & (boundary - 1), 0);
16297160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  void *ptr = MsanReallocate(&stack, 0, size, boundary, false);
16397160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  return ptr;
16497160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov}
16597160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov
1665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR(void *, aligned_alloc, SIZE_T boundary, SIZE_T size) {
1675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  GET_MALLOC_STACK_TRACE;
1685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  CHECK_EQ(boundary & (boundary - 1), 0);
1695d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  void *ptr = MsanReallocate(&stack, 0, size, boundary, false);
1705d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return ptr;
1715d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
1725d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) {
1745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  GET_MALLOC_STACK_TRACE;
1755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  CHECK_EQ(boundary & (boundary - 1), 0);
1765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  void *ptr = MsanReallocate(&stack, 0, size, boundary, false);
1775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  DTLS_on_libc_memalign(ptr, size * boundary);
1785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return ptr;
1795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
1802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
18197160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy StepanovINTERCEPTOR(void *, valloc, SIZE_T size) {
18297160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
18397160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  void *ptr = MsanReallocate(&stack, 0, size, GetPageSizeCached(), false);
18497160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  return ptr;
18597160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov}
18697160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov
18797160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy StepanovINTERCEPTOR(void *, pvalloc, SIZE_T size) {
18897160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
18997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  uptr PageSize = GetPageSizeCached();
19097160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  size = RoundUpTo(size, PageSize);
19197160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  if (size == 0) {
19297160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov    // pvalloc(0) should allocate one page.
19397160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov    size = PageSize;
19497160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  }
19597160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  void *ptr = MsanReallocate(&stack, 0, size, PageSize, false);
19697160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  return ptr;
19797160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov}
19897160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov
19978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(void, free, void *ptr) {
200effdc7e483708cfa4dc597c21f246c5dbc09daa0Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
20178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (ptr == 0) return;
202effdc7e483708cfa4dc597c21f246c5dbc09daa0Evgeniy Stepanov  MsanDeallocate(&stack, ptr);
20378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
20478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
2052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, cfree, void *ptr) {
2062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_MALLOC_STACK_TRACE;
2072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (ptr == 0) return;
2082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MsanDeallocate(&stack, ptr);
2092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
2125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_allocated_size(ptr);
2132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This function actually returns a struct by value, but we can't unpoison a
2162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// temporary! The following is equivalent on all supported platforms, and we
2172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// have a test to confirm that.
2182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
2192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(memset)(sret, 0, sizeof(*sret));
2202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(sret, sizeof(*sret));
2212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, mallopt, int cmd, int value) {
2242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return -1;
2252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, malloc_stats, void) {
2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // FIXME: implement, but don't call REAL(malloc_stats)!
2292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2316afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, strlen, const char *s) {
23278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2336afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(strlen)(s);
23478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_UNPOISONED(s, res + 1);
23578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
23678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
23778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
2386afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {
23978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2406afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(strnlen)(s, n);
2416afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T scan_size = (res == n) ? res : res + 1;
24278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_UNPOISONED(s, scan_size);
24378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
24478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
24578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
24678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// FIXME: Add stricter shadow checks in str* interceptors (ex.: strcpy should
24778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// check the shadow of the terminating \0 byte).
24878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
24978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
25078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2526afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T n = REAL(strlen)(src);
25378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strcpy)(dest, src);  // NOLINT
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, n + 1, &stack);
25578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
25678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
25778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
2586afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
25978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2616afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T copy_size = REAL(strnlen)(src, n);
26278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (copy_size < n)
26378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    copy_size++;  // trailing \0
26478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strncpy)(dest, src, n);  // NOLINT
2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, copy_size, &stack);
26678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
26778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
26878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
2694bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy StepanovINTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
2704bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  ENSURE_MSAN_INITED();
2712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2724bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  SIZE_T n = REAL(strlen)(src);
2734bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  char *res = REAL(stpcpy)(dest, src);  // NOLINT
2742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, n + 1, &stack);
2754bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  return res;
2764bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov}
2774bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov
27878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, strdup, char *src) {
27978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2816afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T n = REAL(strlen)(src);
28278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strdup)(src);
2832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(res, src, n + 1, &stack);
28478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
28578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
28678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
2878aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy StepanovINTERCEPTOR(char *, __strdup, char *src) {
2888aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  ENSURE_MSAN_INITED();
2892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2908aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  SIZE_T n = REAL(strlen)(src);
2918aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  char *res = REAL(__strdup)(src);
2922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(res, src, n + 1, &stack);
2938aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  return res;
2948aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov}
2958aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov
2968aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy StepanovINTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
2978aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  ENSURE_MSAN_INITED();
2982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2998aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  SIZE_T copy_size = REAL(strnlen)(src, n);
3008aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  char *res = REAL(strndup)(src, n);
3012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(res, src, copy_size, &stack);
3028aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  __msan_unpoison(res + copy_size, 1); // \0
3038aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  return res;
3048aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov}
3058aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov
3068aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy StepanovINTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
3078aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  ENSURE_MSAN_INITED();
3082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3098aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  SIZE_T copy_size = REAL(strnlen)(src, n);
3108aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  char *res = REAL(__strndup)(src, n);
3112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(res, src, copy_size, &stack);
3128aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  __msan_unpoison(res + copy_size, 1); // \0
3138aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  return res;
3148aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov}
3158aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov
3166afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
31778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
31878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(gcvt)(number, ndigit, buf);
31978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  // DynamoRio tool will take care of unpoisoning gcvt result for us.
32078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!__msan_has_dynamic_component()) {
3216afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    SIZE_T n = REAL(strlen)(buf);
32278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(buf, n + 1);
32378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
32478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
32578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
32678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
32778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
32878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
3292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3306afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T src_size = REAL(strlen)(src);
3316afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T dest_size = REAL(strlen)(dest);
33278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strcat)(dest, src);  // NOLINT
3332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest + dest_size, src, src_size + 1, &stack);
33478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
33578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
33678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
33878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
3392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3406afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T dest_size = REAL(strlen)(dest);
3412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T copy_size = REAL(strnlen)(src, n);
34278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strncat)(dest, src, n);  // NOLINT
3432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest + dest_size, src, copy_size, &stack);
3442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(dest + dest_size + copy_size, 1); // \0
34578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
34678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
34778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
3492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
3502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
3512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();                             \
3522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ret_type res = REAL(func)(__VA_ARGS__);           \
3532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!__msan_has_dynamic_component()) {            \
3542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __msan_unpoison(endptr, sizeof(*endptr));       \
3552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                 \
35678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
35778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRTO(ret_type, func)                        \
3592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR(ret_type, func, const char *nptr, char **endptr) { \
3602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr);        \
36178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
36278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRTO_BASE(ret_type, func)                             \
3642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base) { \
3652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base);            \
36678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
36778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRTO_LOC(ret_type, func)                               \
3692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, void *loc) { \
3702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc);              \
37178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
37278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func)                       \
3742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base, \
3752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines              void *loc) {                                               \
3762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc);     \
377e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  }
378e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
3795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO(double, strtod)                                    // NOLINT
3805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO(float, strtof)                                     // NOLINT
3815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO(long double, strtold)                              // NOLINT
3825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE(long, strtol)                                 // NOLINT
3835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE(long long, strtoll)                           // NOLINT
3845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE(unsigned long, strtoul)                       // NOLINT
3855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE(unsigned long long, strtoull)                 // NOLINT
3865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(double, strtod_l)                              // NOLINT
3875d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(double, __strtod_l)                            // NOLINT
3885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(double, __strtod_internal)                     // NOLINT
3895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(float, strtof_l)                               // NOLINT
3905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(float, __strtof_l)                             // NOLINT
3915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(float, __strtof_internal)                      // NOLINT
3925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(long double, strtold_l)                        // NOLINT
3935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(long double, __strtold_l)                      // NOLINT
3945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_LOC(long double, __strtold_internal)               // NOLINT
3955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(long, strtol_l)                           // NOLINT
3965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(long, __strtol_l)                         // NOLINT
3975d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(long, __strtol_internal)                  // NOLINT
3985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(long long, strtoll_l)                     // NOLINT
3995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(long long, __strtoll_l)                   // NOLINT
4005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(long long, __strtoll_internal)            // NOLINT
4015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(unsigned long, strtoul_l)                 // NOLINT
4025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(unsigned long, __strtoul_l)               // NOLINT
4035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(unsigned long, __strtoul_internal)        // NOLINT
4045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(unsigned long long, strtoull_l)           // NOLINT
4055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(unsigned long long, __strtoull_l)         // NOLINT
4065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_STRTO_BASE_LOC(unsigned long long, __strtoull_internal)  // NOLINT
4072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: support *wprintf in common format interceptors.
4092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
4100797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  ENSURE_MSAN_INITED();
4112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(vswprintf)(str, size, format, ap);
4120797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  if (res >= 0 && !__msan_has_dynamic_component()) {
4132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __msan_unpoison(str, 4 * (res + 1));
4140797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  }
4150797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  return res;
4160797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov}
4170797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov
4182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
4190797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  ENSURE_MSAN_INITED();
4200797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  va_list ap;
4210797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  va_start(ap, format);
4222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = vswprintf(str, size, format, ap);
4230797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  va_end(ap);
4240797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  return res;
4250797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov}
4260797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov
4272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {
42878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
4292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
4302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T res = REAL(strxfrm)(dest, src, n);
4312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res < n) __msan_unpoison(dest, res + 1);
43278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
43378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
43478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
4362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            void *loc) {
43778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
4382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
4392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);
4402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res < n) __msan_unpoison(dest, res + 1);
44178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
44278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
44378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
4452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();                                              \
4462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ret_type res = REAL(func)(s, __VA_ARGS__);                         \
4472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1));          \
44878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
44978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
4512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm) {
4522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);
45378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
45478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
4562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
4572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
45878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
45978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
4612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
4622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
4632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            loc);
46478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
46578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
467e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov            __sanitizer_tm *tm) {
4682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);
4692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
4702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
4722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
4732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,
4742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            loc);
4752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
4762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
4782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
4792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
4802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            loc);
48178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
48278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
483801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
484801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  ENSURE_MSAN_INITED();
485801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  int res = REAL(mbtowc)(dest, src, n);
486801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
487801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
488801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
489801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
490801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
491801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  ENSURE_MSAN_INITED();
492801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
493801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
494801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
495801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
496801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
4976afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
49878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
4996afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(wcslen)(s);
50078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
50178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
50278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
50378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
50478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
50578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
50678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
50778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wcschr)(s, wc, ps);
50878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
50978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
51078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
51178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
51278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
51378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
51578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wcscpy)(dest, src);
5162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1), &stack);
51778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
51878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
51978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5206afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
5216afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
52278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
52478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wmemcpy)(dest, src, n);
5252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, n * sizeof(wchar_t), &stack);
52678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
52778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
52878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
529353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy StepanovINTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
530353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  ENSURE_MSAN_INITED();
5312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
532353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  wchar_t *res = REAL(wmempcpy)(dest, src, n);
5332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, n * sizeof(wchar_t), &stack);
534353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  return res;
535353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov}
536353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov
5376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
53878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK(MEM_IS_APP(s));
53978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
54078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = (wchar_t *)fast_memset(s, c, n * sizeof(wchar_t));
54178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  __msan_unpoison(s, n * sizeof(wchar_t));
54278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
54378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
54478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5456afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
54678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
54878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wmemmove)(dest, src, n);
5492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MovePoison(dest, src, n * sizeof(wchar_t), &stack);
55078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
55178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
55278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
55378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
55478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
55578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(wcscmp)(s1, s2);
55678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
55778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
55878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
55978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(double, wcstod, const wchar_t *nptr, wchar_t **endptr) {
56078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
56178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  double res = REAL(wcstod)(nptr, endptr);
56278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  __msan_unpoison(endptr, sizeof(*endptr));
56378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
56478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
56578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
56678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
56778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
56878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(gettimeofday)(tv, tz);
56978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (tv)
57078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(tv, 16);
57178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (tz)
57278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(tz, 8);
57378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
57478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
57578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
57678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
57778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
57878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(fcvt)(x, a, b, c);
57978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!__msan_has_dynamic_component()) {
58078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(b, sizeof(*b));
58178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(c, sizeof(*c));
58278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
58378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
58478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
58578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
58678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, getenv, char *name) {
58778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
58878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(getenv)(name);
58978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!__msan_has_dynamic_component()) {
59078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    if (res)
59178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov      __msan_unpoison(res, REAL(strlen)(res) + 1);
59278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
59378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
59478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
59578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
596534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanovextern char **environ;
597534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
598534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanovstatic void UnpoisonEnviron() {
599534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  char **envp = environ;
600534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  for (; *envp; ++envp) {
601534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov    __msan_unpoison(envp, sizeof(*envp));
602534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov    __msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
603534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  }
604534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  // Trailing NULL pointer.
605534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  __msan_unpoison(envp, sizeof(*envp));
606534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov}
607534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
608534e2ba5188e1a74b340f9507755806357835f62Evgeniy StepanovINTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
609534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  ENSURE_MSAN_INITED();
610534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  int res = REAL(setenv)(name, value, overwrite);
611534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  if (!res) UnpoisonEnviron();
612534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  return res;
613534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov}
614534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
615534e2ba5188e1a74b340f9507755806357835f62Evgeniy StepanovINTERCEPTOR(int, putenv, char *string) {
616534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  ENSURE_MSAN_INITED();
617534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  int res = REAL(putenv)(string);
618534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  if (!res) UnpoisonEnviron();
619534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  return res;
620534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov}
621534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
62278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
62378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
62478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__fxstat)(magic, fd, buf);
62578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6269358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
62778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
62878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
62978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
63078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
63178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
63278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__fxstat64)(magic, fd, buf);
63378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
63578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
63678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
63778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
638bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy StepanovINTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
639bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov            int flags) {
640bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  ENSURE_MSAN_INITED();
641bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);
642bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
643bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  return res;
644bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov}
645bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov
646bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy StepanovINTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
647bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov            int flags) {
648bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  ENSURE_MSAN_INITED();
649bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);
650bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
651bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  return res;
652bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov}
653bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov
65478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __xstat, int magic, char *path, void *buf) {
65578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
65678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__xstat)(magic, path, buf);
65778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6589358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
65978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
66078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
66178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
66278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) {
66378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
66478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__xstat64)(magic, path, buf);
66578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
66778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
66878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
66978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
67078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) {
67178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
67278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__lxstat)(magic, path, buf);
67378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6749358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
67578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
67678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
67778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
67878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) {
67978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
68078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__lxstat64)(magic, path, buf);
68178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
68378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
68478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
68578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
68678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, pipe, int pipefd[2]) {
68778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (msan_init_is_running)
68878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return REAL(pipe)(pipefd);
68978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
69078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(pipe)(pipefd);
69178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
69278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(pipefd, sizeof(int[2]));
69378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
69478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
69578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
696134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy StepanovINTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
697134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  ENSURE_MSAN_INITED();
698134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  int res = REAL(pipe2)(pipefd, flags);
699134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  if (!res)
700134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov    __msan_unpoison(pipefd, sizeof(int[2]));
701134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  return res;
702134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov}
703134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov
704134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy StepanovINTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
705134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  ENSURE_MSAN_INITED();
706134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  int res = REAL(socketpair)(domain, type, protocol, sv);
707134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  if (!res)
708134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov    __msan_unpoison(sv, sizeof(int[2]));
709134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  return res;
710134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov}
711134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov
71278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
71378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
71478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(fgets)(s, size, stream);
71578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res)
71678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(s, REAL(strlen)(s) + 1);
71778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
71878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
71978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
72078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
72178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
72278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(fgets_unlocked)(s, size, stream);
72378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res)
72478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(s, REAL(strlen)(s) + 1);
72578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
72678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
72778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
72878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, getrlimit, int resource, void *rlim) {
72978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (msan_init_is_running)
73078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return REAL(getrlimit)(resource, rlim);
73178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
73278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(getrlimit)(resource, rlim);
73378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
7349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
73578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
73678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
73778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
73878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
73978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (msan_init_is_running)
74078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return REAL(getrlimit64)(resource, rlim);
74178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
74278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(getrlimit64)(resource, rlim);
74378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
7449358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
74578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
74678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
74778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
74878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, uname, void *utsname) {
74978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
75078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(uname)(utsname);
75178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res) {
7529358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
75378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
75478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
75578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
75678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
75795d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy StepanovINTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
75895d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  ENSURE_MSAN_INITED();
75995d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  int res = REAL(gethostname)(name, len);
76095d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  if (!res) {
76195d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov    SIZE_T real_len = REAL(strnlen)(name, len);
76295d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov    if (real_len < len)
76395d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov      ++real_len;
76495d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov    __msan_unpoison(name, real_len);
76595d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  }
76695d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  return res;
76795d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov}
76895d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov
76978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
77078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    int timeout) {
77178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
77278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
77378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0) {
7749358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
77578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
77678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
77778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
77878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
77978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
78078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    int timeout, void *sigmask) {
78178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
78278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
78378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0) {
7849358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
78578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
78678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
78778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
78878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
7896afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
79078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
7916afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(recv)(fd, buf, len, flags);
79278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
79378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(buf, res);
79478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
79578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
79678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
7976afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
7989666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov            void *srcaddr, int *addrlen) {
79978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
8007b719dfce8178bdfbcd8a24893153ef82ab70be5Evgeniy Stepanov  SIZE_T srcaddr_sz;
8019666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (srcaddr) srcaddr_sz = *addrlen;
8026afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
8037b719dfce8178bdfbcd8a24893153ef82ab70be5Evgeniy Stepanov  if (res > 0) {
80478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(buf, res);
8057b719dfce8178bdfbcd8a24893153ef82ab70be5Evgeniy Stepanov    if (srcaddr) {
8069666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov      SIZE_T sz = *addrlen;
8077b719dfce8178bdfbcd8a24893153ef82ab70be5Evgeniy Stepanov      __msan_unpoison(srcaddr, (sz < srcaddr_sz) ? sz : srcaddr_sz);
8087b719dfce8178bdfbcd8a24893153ef82ab70be5Evgeniy Stepanov    }
8097b719dfce8178bdfbcd8a24893153ef82ab70be5Evgeniy Stepanov  }
81078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
81178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
81278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
8136afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
814967e07eccfec5e013df5f77b7dd906abfa6b60d9Kostya Serebryany  if (CallocShouldReturnNullDueToOverflow(size, nmemb))
815967e07eccfec5e013df5f77b7dd906abfa6b60d9Kostya Serebryany    return AllocatorReturnNull();
81678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
81778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!msan_inited) {
81878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
8196afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    const SIZE_T kCallocPoolSize = 1024;
82078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    static uptr calloc_memory_for_dlsym[kCallocPoolSize];
8216afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    static SIZE_T allocated;
8226afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
82378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    void *mem = (void*)&calloc_memory_for_dlsym[allocated];
82478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    allocated += size_in_words;
82578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    CHECK(allocated < kCallocPoolSize);
82678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return mem;
82778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
82878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return MsanReallocate(&stack, 0, nmemb * size, sizeof(u64), true);
82978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
83078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
8316afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
83278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
83378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
83478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
83578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
8366afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, malloc, SIZE_T size) {
83778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
83878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return MsanReallocate(&stack, 0, size, sizeof(u64), false);
83978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
84078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
84111347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_allocated_memory(const void* data, uptr size) {
842887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
843887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov  if (flags()->poison_in_malloc)
844887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov    __msan_poison(data, size);
845887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov  if (__msan_get_track_origins()) {
846887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov    u32 stack_id = StackDepotPut(stack.trace, stack.size);
8472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    u32 id;
8482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ChainedOriginDepotPut(stack_id, Origin::kHeapRoot, &id);
8492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __msan_set_origin(data, size, Origin(id, 1).raw_id());
850887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov  }
851887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov}
852887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov
8536afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
8546afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany            int fd, OFF_T offset) {
85578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
8562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (addr && !MEM_IS_APP(addr)) {
8572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (flags & map_fixed) {
8582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      *__errno_location() = errno_EINVAL;
8592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      return (void *)-1;
8602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
8612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      addr = 0;
8622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
8632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
86478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
86578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res != (void*)-1)
86678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
86778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
86878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
86978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
8706afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
8716afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany            int fd, OFF64_T offset) {
87278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
8732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (addr && !MEM_IS_APP(addr)) {
8742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (flags & map_fixed) {
8752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      *__errno_location() = errno_EINVAL;
8762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      return (void *)-1;
8772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
8782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      addr = 0;
8792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
8802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
88178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
88278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res != (void*)-1)
88378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
88478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
88578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
88678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
887e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanovstruct dlinfo {
888e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  char *dli_fname;
889e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  void *dli_fbase;
890e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  char *dli_sname;
891e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  void *dli_saddr;
892e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov};
893e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
894e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovINTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
895e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  ENSURE_MSAN_INITED();
896e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  int res = REAL(dladdr)(addr, info);
897e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  if (res != 0) {
898e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov    __msan_unpoison(info, sizeof(*info));
899e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov    if (info->dli_fname)
900e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov      __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
901e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov    if (info->dli_sname)
902e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov      __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
903e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  }
904e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  return res;
905e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
906e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
9072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(char *, dlerror, int fake) {
908ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov  ENSURE_MSAN_INITED();
9092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char *res = REAL(dlerror)(fake);
910ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov  if (res != 0) __msan_unpoison(res, REAL(strlen)(res) + 1);
911ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov  return res;
912ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov}
913ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov
9141aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanovtypedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
9151aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanov                                  void *data);
9162bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanovstruct dl_iterate_phdr_data {
9172bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  dl_iterate_phdr_cb callback;
9182bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  void *data;
9192bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov};
9202bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov
9211aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanovstatic int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
9221aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanov                                   void *data) {
9231aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanov  if (info) {
9242bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov    __msan_unpoison(info, size);
9251aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanov    if (info->dlpi_name)
9261aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanov      __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
9271aad6b5444207887ecea2b9e87526585d1ce0592Evgeniy Stepanov  }
9282bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
929c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonov  UnpoisonParam(3);
9302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(cbdata->callback)(info, size, cbdata->data);
9312bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov}
9322bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov
9332bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy StepanovINTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
9342bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  ENSURE_MSAN_INITED();
9352bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  EnterLoader();
9362bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  dl_iterate_phdr_data cbdata;
9372bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  cbdata.callback = callback;
9382bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  cbdata.data = data;
9392bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
9402bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  ExitLoader();
9412bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  return res;
9422bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov}
9432bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov
944e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovINTERCEPTOR(int, getrusage, int who, void *usage) {
945e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  ENSURE_MSAN_INITED();
946e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  int res = REAL(getrusage)(who, usage);
947e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  if (res == 0) {
9489358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
949e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  }
950e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  return res;
951e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
952e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
9532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesclass SignalHandlerScope {
9542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines public:
9552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SignalHandlerScope() {
9562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (MsanThread *t = GetCurrentThread())
9572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      t->EnterSignalHandler();
9582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
9592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ~SignalHandlerScope() {
9602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (MsanThread *t = GetCurrentThread())
9612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      t->LeaveSignalHandler();
9622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
9632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
9642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
965e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov// sigactions_mu guarantees atomicity of sigaction() and signal() calls.
966e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov// Access to sigactions[] is gone with relaxed atomics to avoid data race with
967e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov// the signal handler.
96806658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovconst int kMaxSignals = 1024;
969e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovstatic atomic_uintptr_t sigactions[kMaxSignals];
97006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovstatic StaticSpinMutex sigactions_mu;
97106658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
97206658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovstatic void SignalHandler(int signo) {
9732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SignalHandlerScope signal_handler_scope;
9740e38a67cd2d877e8680d65878c86c9e7e4fa4b1dEvgeniy Stepanov  ScopedThreadLocalStateBackup stlsb;
97591659d56bab07fb82ac0edad18c04b333680fd62Evgeniy Stepanov  UnpoisonParam(1);
97691659d56bab07fb82ac0edad18c04b333680fd62Evgeniy Stepanov
977a27bdf70ca24202dce21cf7c1a387aeaa400d889Kostya Serebryany  typedef void (*signal_cb)(int x);
978e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov  signal_cb cb =
979e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov      (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
9802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  IndirectExternCall(cb)(signo);
98106658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov}
98206658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
98306658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovstatic void SignalAction(int signo, void *si, void *uc) {
9842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SignalHandlerScope signal_handler_scope;
9850e38a67cd2d877e8680d65878c86c9e7e4fa4b1dEvgeniy Stepanov  ScopedThreadLocalStateBackup stlsb;
986c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonov  UnpoisonParam(3);
987b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov  __msan_unpoison(si, sizeof(__sanitizer_sigaction));
988072770202bb1002172abe9a4b1eeb7f2d2fb004fEvgeniy Stepanov  __msan_unpoison(uc, __sanitizer::ucontext_t_sz);
98906658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
99006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  typedef void (*sigaction_cb)(int, void *, void *);
991e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov  sigaction_cb cb =
992e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov      (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
9932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  IndirectExternCall(cb)(signo, si, uc);
99406658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov}
99506658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
99606658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy StepanovINTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
99706658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov            __sanitizer_sigaction *oldact) {
998e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  ENSURE_MSAN_INITED();
999583025ddc52988cdcedb5dee57e0d66a0c586340Kostya Serebryany  // FIXME: check that *act is unpoisoned.
1000e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  // That requires intercepting all of sigemptyset, sigfillset, etc.
1001a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  int res;
1002a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  if (flags()->wrap_signals) {
1003a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    SpinMutexLock lock(&sigactions_mu);
1004a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    CHECK_LT(signo, kMaxSignals);
1005e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov    uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
1006a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    __sanitizer_sigaction new_act;
1007a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    __sanitizer_sigaction *pnew_act = act ? &new_act : 0;
1008a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    if (act) {
1009b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov      internal_memcpy(pnew_act, act, sizeof(__sanitizer_sigaction));
10102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      uptr cb = (uptr)pnew_act->sigaction;
1011b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov      uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
1012b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov                        ? (uptr)SignalAction
1013b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov                        : (uptr)SignalHandler;
1014a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
1015e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov        atomic_store(&sigactions[signo], cb, memory_order_relaxed);
10162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;
1017a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov      }
101806658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov    }
1019a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    res = REAL(sigaction)(signo, pnew_act, oldact);
1020a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    if (res == 0 && oldact) {
10212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      uptr cb = (uptr)oldact->sigaction;
1022cd3049da150124156502b1a8c05e4c4887786cc5Evgeniy Stepanov      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
10232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        oldact->sigaction = (void (*)(int, void *, void *))old_cb;
1024cd3049da150124156502b1a8c05e4c4887786cc5Evgeniy Stepanov      }
1025a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    }
1026a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  } else {
1027a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    res = REAL(sigaction)(signo, act, oldact);
102806658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  }
1029a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov
103006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  if (res == 0 && oldact) {
1031b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov    __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
1032e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1033e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1034e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1035e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
103606658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy StepanovINTERCEPTOR(int, signal, int signo, uptr cb) {
103706658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  ENSURE_MSAN_INITED();
1038a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  if (flags()->wrap_signals) {
1039a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    CHECK_LT(signo, kMaxSignals);
1040a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    SpinMutexLock lock(&sigactions_mu);
1041a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
1042e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov      atomic_store(&sigactions[signo], cb, memory_order_relaxed);
1043a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov      cb = (uptr) SignalHandler;
1044a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    }
1045a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    return REAL(signal)(signo, cb);
1046a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  } else {
1047a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    return REAL(signal)(signo, cb);
104806658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  }
104906658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov}
105006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
105110fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanovextern "C" int pthread_attr_init(void *attr);
105210fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanovextern "C" int pthread_attr_destroy(void *attr);
10537c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
10547c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanovstatic void *MsanThreadStartFunc(void *arg) {
10552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MsanThread *t = (MsanThread *)arg;
10562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SetCurrentThread(t);
10572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return t->ThreadStart();
10587c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov}
105910fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov
106010fd3227546d17c7411241a45ebc143b2031c78dEvgeniy StepanovINTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
106110fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov            void * param) {
106210fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  ENSURE_MSAN_INITED(); // for GetTlsSize()
106310fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  __sanitizer_pthread_attr_t myattr;
106410fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  if (attr == 0) {
106510fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov    pthread_attr_init(&myattr);
106610fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov    attr = &myattr;
106710fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  }
1068b9bf700ae7fe59e25976e0abe9636150f3a39cd2Evgeniy Stepanov
10692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  AdjustStackSize(attr);
107010fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov
10712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MsanThread *t = MsanThread::Create(callback, param);
10727c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
10732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);
10747c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
107510fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  if (attr == &myattr)
107610fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov    pthread_attr_destroy(&myattr);
1077e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
1078e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    __msan_unpoison(th, __sanitizer::pthread_t_sz);
1079e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
108010fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  return res;
108110fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov}
108210fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov
1083eaca82cf249021afa31dbc970278f2f28ea2a1aaTimur IskhodzhanovINTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
1084eaca82cf249021afa31dbc970278f2f28ea2a1aaTimur Iskhodzhanov            void (*dtor)(void *value)) {
10852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);
1086737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  ENSURE_MSAN_INITED();
1087737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  int res = REAL(pthread_key_create)(key, dtor);
1088737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  if (!res && key)
1089737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov    __msan_unpoison(key, sizeof(*key));
1090737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  return res;
1091737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov}
1092737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov
10936567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy StepanovINTERCEPTOR(int, pthread_join, void *th, void **retval) {
10946567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  ENSURE_MSAN_INITED();
10956567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  int res = REAL(pthread_join)(th, retval);
10966567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  if (!res && retval)
10976567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov    __msan_unpoison(retval, sizeof(*retval));
10986567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  return res;
10996567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov}
11006567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov
11017b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanovextern char *tzname[2];
11027b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov
11032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, tzset, int fake) {
11047b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  ENSURE_MSAN_INITED();
11052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(tzset)(fake);
11067b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  if (tzname[0])
11077b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov    __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);
11087b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  if (tzname[1])
11097b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov    __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);
11107b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  return;
11117b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov}
11127b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov
1113cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanovstruct MSanAtExitRecord {
1114cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  void (*func)(void *arg);
1115cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  void *arg;
1116cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov};
1117cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov
1118cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanovvoid MSanAtExitWrapper(void *arg) {
1119cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  UnpoisonParam(1);
1120cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
11212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  IndirectExternCall(r->func)(r->arg);
1122cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  InternalFree(r);
1123cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov}
1124cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov
1125cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov// Unpoison argument shadow for C++ module destructors.
1126cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy StepanovINTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
1127cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov            void *dso_handle) {
1128cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
1129cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  ENSURE_MSAN_INITED();
1130cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  MSanAtExitRecord *r =
1131cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov      (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
1132cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  r->func = func;
1133cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  r->arg = arg;
1134cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
1135cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov}
1136cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov
1137f3603890015c130420def39d67a02c2fdafc6f84Evgeniy StepanovDECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf)
1138f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov
1139f3603890015c130420def39d67a02c2fdafc6f84Evgeniy StepanovINTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
1140f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  ENSURE_MSAN_INITED();
1141f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  void *p = REAL(shmat)(shmid, shmaddr, shmflg);
1142f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  if (p != (void *)-1) {
1143f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    __sanitizer_shmid_ds ds;
1144f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);
1145f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    if (!res) {
1146f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov      __msan_unpoison(p, ds.shm_segsz);
1147f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    }
1148f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  }
1149f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  return p;
1150f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov}
1151f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov
1152548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov// Linux kernel has a bug that leads to kernel deadlock if a process
1153548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov// maps TBs of memory and then calls mlock().
1154548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanovstatic void MlockIsUnsupported() {
1155548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  static atomic_uint8_t printed;
1156548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  if (atomic_exchange(&printed, 1, memory_order_relaxed))
1157548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov    return;
11582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  VPrintf(1,
11592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          "INFO: MemorySanitizer ignores mlock/mlockall/munlock/munlockall\n");
1160548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1161548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov
1162548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy StepanovINTERCEPTOR(int, mlock, const void *addr, uptr len) {
1163548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  MlockIsUnsupported();
1164548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  return 0;
1165548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1166548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov
1167548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy StepanovINTERCEPTOR(int, munlock, const void *addr, uptr len) {
1168548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  MlockIsUnsupported();
1169548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  return 0;
1170548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1171548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov
1172548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy StepanovINTERCEPTOR(int, mlockall, int flags) {
1173548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  MlockIsUnsupported();
1174548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  return 0;
1175548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1176548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov
1177548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy StepanovINTERCEPTOR(int, munlockall, void) {
1178548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  MlockIsUnsupported();
1179548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov  return 0;
1180548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1181f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov
1182447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovstruct MSanInterceptorContext {
1183447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  bool in_interceptor_scope;
1184447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov};
1185447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
11868cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukovnamespace __msan {
11878cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukov
11888cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukovint OnExit() {
118914dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  // FIXME: ask frontend whether we need to return failure.
119014dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  return 0;
119114dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov}
119214dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov
11938cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukov}  // namespace __msan
11948cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukov
1195a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov// A version of CHECK_UNPOISONED using a saved scope value. Used in common
11965b2afc3e655f32c8b9d4b7c8b0ad31681f16cf06Evgeniy Stepanov// interceptors.
1197341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define CHECK_UNPOISONED_CTX(ctx, x, n)                         \
1198341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  do {                                                          \
1199341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
1200341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      CHECK_UNPOISONED_0(x, n);                                 \
1201341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  } while (0)
1202447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
12032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define MSAN_INTERCEPT_FUNC(name)                                       \
12042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  do {                                                                  \
12052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                     \
12062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \
1207a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  } while (0)
1208a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1209a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
12102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count)  \
12113fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  UnpoisonParam(count)
1212996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
1213447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  __msan_unpoison(ptr, size)
1214447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
1215341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  CHECK_UNPOISONED_CTX(ctx, ptr, size)
12162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \
12170586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov  __msan_unpoison(ptr, size)
12181161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                  \
12191161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  if (msan_init_is_running) return REAL(func)(__VA_ARGS__);       \
12201161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  MSanInterceptorContext msan_ctx = {IsInInterceptorScope()};     \
12211161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  ctx = (void *)&msan_ctx;                                        \
12221161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  (void)ctx;                                                      \
12231161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  InterceptorScope interceptor_scope;                             \
12241161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */  \
1225447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  ENSURE_MSAN_INITED();
1226447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
1227447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  do {                                         \
122882a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov  } while (false)
12299d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
12309d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  do {                                         \
12319d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  } while (false)
12329d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
12339d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  do {                                                      \
12349d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  } while (false)
123582a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
12369d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  do {                                                \
12379d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  } while (false)  // FIXME
12385cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
12395cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  do {                                                         \
12405cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  } while (false)  // FIXME
1241e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
124214dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
12432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map)                       \
12442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!__msan_has_dynamic_component() && map) {                                \
12452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    /* If msandr didn't clear the shadow before the initializers ran, we do */ \
12462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    /* it ourselves afterwards. */                                             \
12472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ForEachMappedRegion((link_map *)map, __msan_unpoison);                     \
12482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12504f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_interceptors.inc"
1251c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany
12522887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
12536b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
12546b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  do {                                       \
12556b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  } while (false)
12566b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
12576b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  do {                                       \
12586b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  } while (false)
12592887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
12602887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#include "sanitizer_common/sanitizer_common_syscalls.inc"
12612887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
126278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// static
12636afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryanyvoid *fast_memset(void *ptr, int c, SIZE_T n) {
126478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  // hack until we have a really fast internal_memset
126578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (sizeof(uptr) == 8 &&
126678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov      (n % 8) == 0 &&
12675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      ((uptr)ptr % 8) == 0) {
12685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    uptr c8 = (unsigned)c & 0xFF;
12695d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    c8 = (c8 << 8) | c8;
12705d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    c8 = (c8 << 16) | c8;
12715d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    c8 = (c8 << 32) | c8;
127278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    uptr *p = (uptr*)ptr;
12736afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    for (SIZE_T i = 0; i < n / 8; i++)
12745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      p[i] = c8;
127578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return ptr;
127678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
127778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return internal_memset(ptr, c, n);
127878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
127978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
128078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// static
12816afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryanyvoid *fast_memcpy(void *dst, const void *src, SIZE_T n) {
128278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  // Same hack as in fast_memset above.
128378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (sizeof(uptr) == 8 &&
128478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov      (n % 8) == 0 &&
128578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov      ((uptr)dst % 8) == 0 &&
128678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov      ((uptr)src % 8) == 0) {
128778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    uptr *d = (uptr*)dst;
128878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    uptr *s = (uptr*)src;
12896afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    for (SIZE_T i = 0; i < n / 8; i++)
129078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov      d[i] = s[i];
129178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return dst;
129278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
129378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return internal_memcpy(dst, src, n);
129478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
129578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
12962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void PoisonShadow(uptr ptr, uptr size, u8 value) {
12972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr PageSize = GetPageSizeCached();
12982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr shadow_beg = MEM_TO_SHADOW(ptr);
12992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr shadow_end = MEM_TO_SHADOW(ptr + size);
13002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (value ||
13012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
13022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    fast_memset((void*)shadow_beg, value, shadow_end - shadow_beg);
13032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } else {
13042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    uptr page_beg = RoundUpTo(shadow_beg, PageSize);
13052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    uptr page_end = RoundDownTo(shadow_end, PageSize);
13062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (page_beg >= page_end) {
13082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      fast_memset((void *)shadow_beg, 0, shadow_end - shadow_beg);
13092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
13102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (page_beg != shadow_beg) {
13112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        fast_memset((void *)shadow_beg, 0, page_beg - shadow_beg);
13122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
13132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (page_end != shadow_end) {
13142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        fast_memset((void *)page_end, 0, shadow_end - page_end);
13152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
13162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      MmapFixedNoReserve(page_beg, page_end - page_beg);
13172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
13182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
13192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
132178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// These interface functions reside here so that they can use
132278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// fast_memset, etc.
132311347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_unpoison(const void *a, uptr size) {
132478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(a)) return;
13252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  PoisonShadow((uptr)a, size, 0);
132678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
132778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
132811347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_poison(const void *a, uptr size) {
132978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(a)) return;
13302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  PoisonShadow((uptr)a, size,
13312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines               __msan::flags()->poison_heap_with_zeroes ? 0 : -1);
133278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
133378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
133478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_poison_stack(void *a, uptr size) {
133578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(a)) return;
13362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  PoisonShadow((uptr)a, size,
13372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines               __msan::flags()->poison_stack_with_zeroes ? 0 : -1);
133878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
133978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
134078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_clear_and_unpoison(void *a, uptr size) {
134178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  fast_memset(a, 0, size);
13422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  PoisonShadow((uptr)a, size, 0);
13432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
13462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!msan_inited) return internal_memcpy(dest, src, n);
13472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(memcpy)(dest, src, n);
13482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();
13492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
13502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = fast_memcpy(dest, src, n);
13512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyPoison(dest, src, n, &stack);
13522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
13532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__msan_memset(void *s, int c, SIZE_T n) {
13562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!msan_inited) return internal_memset(s, c, n);
13572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(memset)(s, c, n);
13582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();
13592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = fast_memset(s, c, n);
13602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(s, n);
13612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
136278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
136378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
13642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__msan_memmove(void *dest, const void *src, SIZE_T n) {
13652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!msan_inited) return internal_memmove(dest, src, n);
13662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(memmove)(dest, src, n);
13672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();
13682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
13692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(memmove)(dest, src, n);
13702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MovePoison(dest, src, n, &stack);
13712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
13722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __msan_unpoison_string(const char* s) {
13752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!MEM_IS_APP(s)) return;
13762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(s, REAL(strlen)(s) + 1);
13772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __msan {
13802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesu32 GetOriginIfPoisoned(uptr addr, uptr size) {
13822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unsigned char *s = (unsigned char *)MEM_TO_SHADOW(addr);
1383450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  for (uptr i = 0; i < size; ++i)
1384450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov    if (s[i])
13854197fa23ada9682343a15b68dde08c0249db172aEvgeniy Stepanov      return *(u32 *)SHADOW_TO_ORIGIN((s + i) & ~3UL);
1386450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  return 0;
1387450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov}
1388450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov
13892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size,
13902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                         u32 src_origin) {
13912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr dst_s = MEM_TO_SHADOW(addr);
13922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr src_s = src_shadow;
13932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr src_s_end = src_s + size;
13942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (; src_s < src_s_end; ++dst_s, ++src_s)
13962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (*(u8 *)src_s) *(u32 *)SHADOW_TO_ORIGIN(dst_s &~3UL) = src_origin;
13972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack) {
140078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!__msan_get_track_origins()) return;
140178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;
14022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1403450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  uptr d = (uptr)dst;
1404450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  uptr beg = d & ~3UL;
1405450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  // Copy left unaligned origin if that memory is poisoned.
1406450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  if (beg < d) {
14075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    u32 o = GetOriginIfPoisoned((uptr)src, d - beg);
14082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (o) {
14092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
14104197fa23ada9682343a15b68dde08c0249db172aEvgeniy Stepanov      *(u32 *)MEM_TO_ORIGIN(beg) = o;
14112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1412450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov    beg += 4;
1413450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  }
1414450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov
14155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  uptr end = (d + size) & ~3UL;
14165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // If both ends fall into the same 4-byte slot, we are done.
14175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (end < beg) return;
14185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1419450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  // Copy right unaligned origin if that memory is poisoned.
14205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (end < d + size) {
14215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    u32 o = GetOriginIfPoisoned((uptr)src + (end - d), (d + size) - end);
14222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (o) {
14232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
14245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      *(u32 *)MEM_TO_ORIGIN(end) = o;
14252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1426450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  }
1427450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov
1428450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  if (beg < end) {
1429450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov    // Align src up.
1430450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov    uptr s = ((uptr)src + 3) & ~3UL;
14312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // FIXME: factor out to msan_copy_origin_aligned
14322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (__msan_get_track_origins() > 1) {
14332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      u32 *src = (u32 *)MEM_TO_ORIGIN(s);
14342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      u32 *src_s = (u32 *)MEM_TO_SHADOW(s);
14355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg));
14362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      u32 *dst = (u32 *)MEM_TO_ORIGIN(beg);
14372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      u32 src_o = 0;
14382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      u32 dst_o = 0;
14392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      for (; src < src_end; ++src, ++src_s, ++dst) {
14402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        if (!*src_s) continue;
14412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        if (*src != src_o) {
14422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          src_o = *src;
14432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          dst_o = ChainOrigin(src_o, stack);
14442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        }
14452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        *dst = dst_o;
14462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      }
14472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
14482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      fast_memcpy((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
14492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                  end - beg);
14502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1451450eee655289a622ab9acf87d863f38991b184c9Evgeniy Stepanov  }
145278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
145378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
14542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid MovePoison(void *dst, const void *src, uptr size, StackTrace *stack) {
145578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(dst)) return;
145678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(src)) return;
14572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (src == dst) return;
14582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  internal_memmove((void *)MEM_TO_SHADOW((uptr)dst),
14592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                   (void *)MEM_TO_SHADOW((uptr)src), size);
14602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyOrigin(dst, src, size, stack);
146178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
146278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
14632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack) {
146478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(dst)) return;
146578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(src)) return;
14662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  fast_memcpy((void *)MEM_TO_SHADOW((uptr)dst),
14672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines              (void *)MEM_TO_SHADOW((uptr)src), size);
14682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CopyOrigin(dst, src, size, stack);
146978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
147078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
147178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid InitializeInterceptors() {
147278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  static int inited = 0;
147378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_EQ(inited, 0);
14742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  InitializeCommonInterceptors();
1475c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany
14768028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(mmap);
14778028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(mmap64);
14788028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(posix_memalign);
147997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  INTERCEPT_FUNCTION(memalign);
14805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__libc_memalign);
148197160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  INTERCEPT_FUNCTION(valloc);
148297160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  INTERCEPT_FUNCTION(pvalloc);
14838028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(malloc);
14848028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(calloc);
14858028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(realloc);
14868028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(free);
14872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(cfree);
14882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(malloc_usable_size);
14892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(mallinfo);
14902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(mallopt);
14912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(malloc_stats);
14928028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fread);
14938028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fread_unlocked);
14948028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(readlink);
14958028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(memcpy);
14965492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  INTERCEPT_FUNCTION(memccpy);
1497353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  INTERCEPT_FUNCTION(mempcpy);
14988028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(memset);
14998028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(memmove);
1500ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(bcopy);
15018028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wmemset);
15028028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wmemcpy);
1503353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  INTERCEPT_FUNCTION(wmempcpy);
15048028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wmemmove);
15058028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strcpy);  // NOLINT
15064bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  INTERCEPT_FUNCTION(stpcpy);  // NOLINT
15078028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strdup);
15088aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  INTERCEPT_FUNCTION(__strdup);
15098aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  INTERCEPT_FUNCTION(strndup);
15108aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  INTERCEPT_FUNCTION(__strndup);
15118028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strncpy);  // NOLINT
15128028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strlen);
15138028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strnlen);
15148028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(gcvt);
15158028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strcat);  // NOLINT
15168028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strncat);  // NOLINT
15175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(strtod);
15185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(strtof);
15195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(strtold);
15208028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strtol);
15218028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strtoll);
15228028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strtoul);
15238028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strtoull);
15243f4beff5efdd0d30844ca8b270876f7d59a608e7Evgeniy Stepanov  INTERCEPT_FUNCTION(strtod_l);
15253f4beff5efdd0d30844ca8b270876f7d59a608e7Evgeniy Stepanov  INTERCEPT_FUNCTION(__strtod_l);
15265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtod_internal);
15273f4beff5efdd0d30844ca8b270876f7d59a608e7Evgeniy Stepanov  INTERCEPT_FUNCTION(strtof_l);
15283f4beff5efdd0d30844ca8b270876f7d59a608e7Evgeniy Stepanov  INTERCEPT_FUNCTION(__strtof_l);
15295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtof_internal);
15303f4beff5efdd0d30844ca8b270876f7d59a608e7Evgeniy Stepanov  INTERCEPT_FUNCTION(strtold_l);
15313f4beff5efdd0d30844ca8b270876f7d59a608e7Evgeniy Stepanov  INTERCEPT_FUNCTION(__strtold_l);
15325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtold_internal);
15332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strtol_l);
15345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtol_l);
15355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtol_internal);
15362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strtoll_l);
15375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtoll_l);
15385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtoll_internal);
15392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strtoul_l);
15405d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtoul_l);
15415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtoul_internal);
15422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strtoull_l);
15435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtoull_l);
15445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPT_FUNCTION(__strtoull_internal);
15458028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(vswprintf);
15468028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(swprintf);
15472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strxfrm);
15482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strxfrm_l);
15498028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strftime);
15502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strftime_l);
15512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(__strftime_l);
15522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(wcsftime);
15532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(wcsftime_l);
15542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(__wcsftime_l);
1555801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INTERCEPT_FUNCTION(mbtowc);
1556801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INTERCEPT_FUNCTION(mbrtowc);
15578028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcslen);
15588028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcschr);
15598028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcscpy);
15608028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcscmp);
15618028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcstod);
15628028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(getenv);
1563534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  INTERCEPT_FUNCTION(setenv);
1564534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  INTERCEPT_FUNCTION(putenv);
15658028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(gettimeofday);
15668028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fcvt);
15678028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(__fxstat);
1568bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  INTERCEPT_FUNCTION(__fxstatat);
15698028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(__xstat);
15708028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(__lxstat);
15718028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(__fxstat64);
1572bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  INTERCEPT_FUNCTION(__fxstatat64);
15738028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(__xstat64);
15748028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(__lxstat64);
15758028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(pipe);
1576134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  INTERCEPT_FUNCTION(pipe2);
1577134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  INTERCEPT_FUNCTION(socketpair);
15788028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fgets);
15798028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fgets_unlocked);
15808028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(getrlimit);
15818028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(getrlimit64);
15828028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(uname);
158395d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostname);
15848028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(epoll_wait);
15858028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(epoll_pwait);
15868028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(recv);
15878028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(recvfrom);
1588e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  INTERCEPT_FUNCTION(dladdr);
1589ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov  INTERCEPT_FUNCTION(dlerror);
15902bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  INTERCEPT_FUNCTION(dl_iterate_phdr);
1591e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  INTERCEPT_FUNCTION(getrusage);
1592e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(sigaction);
159306658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  INTERCEPT_FUNCTION(signal);
159410fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  INTERCEPT_FUNCTION(pthread_create);
1595737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  INTERCEPT_FUNCTION(pthread_key_create);
15966567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  INTERCEPT_FUNCTION(pthread_join);
15977b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  INTERCEPT_FUNCTION(tzset);
1598cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  INTERCEPT_FUNCTION(__cxa_atexit);
1599f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  INTERCEPT_FUNCTION(shmat);
16007c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
160178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  inited = 1;
160278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
160378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}  // namespace __msan
1604