Home | History | Annotate | Download | only in msan
      1 //===-- msan_interceptors.cc ----------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of MemorySanitizer.
     11 //
     12 // Interceptors for standard library functions.
     13 //
     14 // FIXME: move as many interceptors as possible into
     15 // sanitizer_common/sanitizer_common_interceptors.h
     16 //===----------------------------------------------------------------------===//
     17 
     18 #include "msan.h"
     19 #include "msan_chained_origin_depot.h"
     20 #include "msan_origin.h"
     21 #include "msan_thread.h"
     22 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
     23 #include "sanitizer_common/sanitizer_allocator.h"
     24 #include "sanitizer_common/sanitizer_allocator_interface.h"
     25 #include "sanitizer_common/sanitizer_allocator_internal.h"
     26 #include "sanitizer_common/sanitizer_atomic.h"
     27 #include "sanitizer_common/sanitizer_common.h"
     28 #include "sanitizer_common/sanitizer_interception.h"
     29 #include "sanitizer_common/sanitizer_stackdepot.h"
     30 #include "sanitizer_common/sanitizer_libc.h"
     31 #include "sanitizer_common/sanitizer_linux.h"
     32 #include "sanitizer_common/sanitizer_tls_get_addr.h"
     33 
     34 #include <stdarg.h>
     35 // ACHTUNG! No other system header includes in this file.
     36 // Ideally, we should get rid of stdarg.h as well.
     37 
     38 using namespace __msan;
     39 
     40 using __sanitizer::memory_order;
     41 using __sanitizer::atomic_load;
     42 using __sanitizer::atomic_store;
     43 using __sanitizer::atomic_uintptr_t;
     44 
     45 // True if this is a nested interceptor.
     46 static THREADLOCAL int in_interceptor_scope;
     47 
     48 extern "C" int *__errno_location(void);
     49 
     50 struct InterceptorScope {
     51   InterceptorScope() { ++in_interceptor_scope; }
     52   ~InterceptorScope() { --in_interceptor_scope; }
     53 };
     54 
     55 bool IsInInterceptorScope() {
     56   return in_interceptor_scope;
     57 }
     58 
     59 #define ENSURE_MSAN_INITED() do { \
     60   CHECK(!msan_init_is_running); \
     61   if (!msan_inited) { \
     62     __msan_init(); \
     63   } \
     64 } while (0)
     65 
     66 // Check that [x, x+n) range is unpoisoned.
     67 #define CHECK_UNPOISONED_0(x, n)                                             \
     68   do {                                                                       \
     69     sptr offset = __msan_test_shadow(x, n);                                  \
     70     if (__msan::IsInSymbolizer()) break;                                     \
     71     if (offset >= 0 && __msan::flags()->report_umrs) {                       \
     72       GET_CALLER_PC_BP_SP;                                                   \
     73       (void) sp;                                                             \
     74       ReportUMRInsideAddressRange(__func__, x, n, offset);                   \
     75       __msan::PrintWarningWithOrigin(pc, bp,                                 \
     76                                      __msan_get_origin((char *)x + offset)); \
     77       if (__msan::flags()->halt_on_error) {                                  \
     78         Printf("Exiting\n");                                                 \
     79         Die();                                                               \
     80       }                                                                      \
     81     }                                                                        \
     82   } while (0)
     83 
     84 // Check that [x, x+n) range is unpoisoned unless we are in a nested
     85 // interceptor.
     86 #define CHECK_UNPOISONED(x, n)                             \
     87   do {                                                     \
     88     if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
     89   } while (0);
     90 
     91 static void *fast_memset(void *ptr, int c, SIZE_T n);
     92 static void *fast_memcpy(void *dst, const void *src, SIZE_T n);
     93 
     94 INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
     95   ENSURE_MSAN_INITED();
     96   SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
     97   if (res > 0)
     98     __msan_unpoison(ptr, res *size);
     99   return res;
    100 }
    101 
    102 INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
    103             void *file) {
    104   ENSURE_MSAN_INITED();
    105   SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
    106   if (res > 0)
    107     __msan_unpoison(ptr, res *size);
    108   return res;
    109 }
    110 
    111 INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
    112   ENSURE_MSAN_INITED();
    113   SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
    114   if (res > 0)
    115     __msan_unpoison(buf, res);
    116   return res;
    117 }
    118 
    119 INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
    120   return __msan_memcpy(dest, src, n);
    121 }
    122 
    123 INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
    124   return (char *)__msan_memcpy(dest, src, n) + n;
    125 }
    126 
    127 INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
    128   ENSURE_MSAN_INITED();
    129   void *res = REAL(memccpy)(dest, src, c, n);
    130   CHECK(!res || (res >= dest && res <= (char *)dest + n));
    131   SIZE_T sz = res ? (char *)res - (char *)dest : n;
    132   CHECK_UNPOISONED(src, sz);
    133   __msan_unpoison(dest, sz);
    134   return res;
    135 }
    136 
    137 INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
    138   return __msan_memmove(dest, src, n);
    139 }
    140 
    141 INTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
    142   return __msan_memset(s, c, n);
    143 }
    144 
    145 INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
    146   return __msan_memmove(dest, src, n);
    147 }
    148 
    149 INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
    150   GET_MALLOC_STACK_TRACE;
    151   CHECK_EQ(alignment & (alignment - 1), 0);
    152   CHECK_NE(memptr, 0);
    153   *memptr = MsanReallocate(&stack, 0, size, alignment, false);
    154   CHECK_NE(*memptr, 0);
    155   __msan_unpoison(memptr, sizeof(*memptr));
    156   return 0;
    157 }
    158 
    159 INTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) {
    160   GET_MALLOC_STACK_TRACE;
    161   CHECK_EQ(boundary & (boundary - 1), 0);
    162   void *ptr = MsanReallocate(&stack, 0, size, boundary, false);
    163   return ptr;
    164 }
    165 
    166 INTERCEPTOR(void *, aligned_alloc, SIZE_T boundary, SIZE_T size) {
    167   GET_MALLOC_STACK_TRACE;
    168   CHECK_EQ(boundary & (boundary - 1), 0);
    169   void *ptr = MsanReallocate(&stack, 0, size, boundary, false);
    170   return ptr;
    171 }
    172 
    173 INTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) {
    174   GET_MALLOC_STACK_TRACE;
    175   CHECK_EQ(boundary & (boundary - 1), 0);
    176   void *ptr = MsanReallocate(&stack, 0, size, boundary, false);
    177   DTLS_on_libc_memalign(ptr, size * boundary);
    178   return ptr;
    179 }
    180 
    181 INTERCEPTOR(void *, valloc, SIZE_T size) {
    182   GET_MALLOC_STACK_TRACE;
    183   void *ptr = MsanReallocate(&stack, 0, size, GetPageSizeCached(), false);
    184   return ptr;
    185 }
    186 
    187 INTERCEPTOR(void *, pvalloc, SIZE_T size) {
    188   GET_MALLOC_STACK_TRACE;
    189   uptr PageSize = GetPageSizeCached();
    190   size = RoundUpTo(size, PageSize);
    191   if (size == 0) {
    192     // pvalloc(0) should allocate one page.
    193     size = PageSize;
    194   }
    195   void *ptr = MsanReallocate(&stack, 0, size, PageSize, false);
    196   return ptr;
    197 }
    198 
    199 INTERCEPTOR(void, free, void *ptr) {
    200   GET_MALLOC_STACK_TRACE;
    201   if (ptr == 0) return;
    202   MsanDeallocate(&stack, ptr);
    203 }
    204 
    205 INTERCEPTOR(void, cfree, void *ptr) {
    206   GET_MALLOC_STACK_TRACE;
    207   if (ptr == 0) return;
    208   MsanDeallocate(&stack, ptr);
    209 }
    210 
    211 INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
    212   return __sanitizer_get_allocated_size(ptr);
    213 }
    214 
    215 // This function actually returns a struct by value, but we can't unpoison a
    216 // temporary! The following is equivalent on all supported platforms, and we
    217 // have a test to confirm that.
    218 INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
    219   REAL(memset)(sret, 0, sizeof(*sret));
    220   __msan_unpoison(sret, sizeof(*sret));
    221 }
    222 
    223 INTERCEPTOR(int, mallopt, int cmd, int value) {
    224   return -1;
    225 }
    226 
    227 INTERCEPTOR(void, malloc_stats, void) {
    228   // FIXME: implement, but don't call REAL(malloc_stats)!
    229 }
    230 
    231 INTERCEPTOR(SIZE_T, strlen, const char *s) {
    232   ENSURE_MSAN_INITED();
    233   SIZE_T res = REAL(strlen)(s);
    234   CHECK_UNPOISONED(s, res + 1);
    235   return res;
    236 }
    237 
    238 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {
    239   ENSURE_MSAN_INITED();
    240   SIZE_T res = REAL(strnlen)(s, n);
    241   SIZE_T scan_size = (res == n) ? res : res + 1;
    242   CHECK_UNPOISONED(s, scan_size);
    243   return res;
    244 }
    245 
    246 // FIXME: Add stricter shadow checks in str* interceptors (ex.: strcpy should
    247 // check the shadow of the terminating \0 byte).
    248 
    249 INTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
    250   ENSURE_MSAN_INITED();
    251   GET_STORE_STACK_TRACE;
    252   SIZE_T n = REAL(strlen)(src);
    253   char *res = REAL(strcpy)(dest, src);  // NOLINT
    254   CopyPoison(dest, src, n + 1, &stack);
    255   return res;
    256 }
    257 
    258 INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
    259   ENSURE_MSAN_INITED();
    260   GET_STORE_STACK_TRACE;
    261   SIZE_T copy_size = REAL(strnlen)(src, n);
    262   if (copy_size < n)
    263     copy_size++;  // trailing \0
    264   char *res = REAL(strncpy)(dest, src, n);  // NOLINT
    265   CopyPoison(dest, src, copy_size, &stack);
    266   return res;
    267 }
    268 
    269 INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
    270   ENSURE_MSAN_INITED();
    271   GET_STORE_STACK_TRACE;
    272   SIZE_T n = REAL(strlen)(src);
    273   char *res = REAL(stpcpy)(dest, src);  // NOLINT
    274   CopyPoison(dest, src, n + 1, &stack);
    275   return res;
    276 }
    277 
    278 INTERCEPTOR(char *, strdup, char *src) {
    279   ENSURE_MSAN_INITED();
    280   GET_STORE_STACK_TRACE;
    281   SIZE_T n = REAL(strlen)(src);
    282   char *res = REAL(strdup)(src);
    283   CopyPoison(res, src, n + 1, &stack);
    284   return res;
    285 }
    286 
    287 INTERCEPTOR(char *, __strdup, char *src) {
    288   ENSURE_MSAN_INITED();
    289   GET_STORE_STACK_TRACE;
    290   SIZE_T n = REAL(strlen)(src);
    291   char *res = REAL(__strdup)(src);
    292   CopyPoison(res, src, n + 1, &stack);
    293   return res;
    294 }
    295 
    296 INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
    297   ENSURE_MSAN_INITED();
    298   GET_STORE_STACK_TRACE;
    299   SIZE_T copy_size = REAL(strnlen)(src, n);
    300   char *res = REAL(strndup)(src, n);
    301   CopyPoison(res, src, copy_size, &stack);
    302   __msan_unpoison(res + copy_size, 1); // \0
    303   return res;
    304 }
    305 
    306 INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
    307   ENSURE_MSAN_INITED();
    308   GET_STORE_STACK_TRACE;
    309   SIZE_T copy_size = REAL(strnlen)(src, n);
    310   char *res = REAL(__strndup)(src, n);
    311   CopyPoison(res, src, copy_size, &stack);
    312   __msan_unpoison(res + copy_size, 1); // \0
    313   return res;
    314 }
    315 
    316 INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
    317   ENSURE_MSAN_INITED();
    318   char *res = REAL(gcvt)(number, ndigit, buf);
    319   // DynamoRio tool will take care of unpoisoning gcvt result for us.
    320   if (!__msan_has_dynamic_component()) {
    321     SIZE_T n = REAL(strlen)(buf);
    322     __msan_unpoison(buf, n + 1);
    323   }
    324   return res;
    325 }
    326 
    327 INTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
    328   ENSURE_MSAN_INITED();
    329   GET_STORE_STACK_TRACE;
    330   SIZE_T src_size = REAL(strlen)(src);
    331   SIZE_T dest_size = REAL(strlen)(dest);
    332   char *res = REAL(strcat)(dest, src);  // NOLINT
    333   CopyPoison(dest + dest_size, src, src_size + 1, &stack);
    334   return res;
    335 }
    336 
    337 INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
    338   ENSURE_MSAN_INITED();
    339   GET_STORE_STACK_TRACE;
    340   SIZE_T dest_size = REAL(strlen)(dest);
    341   SIZE_T copy_size = REAL(strnlen)(src, n);
    342   char *res = REAL(strncat)(dest, src, n);  // NOLINT
    343   CopyPoison(dest + dest_size, src, copy_size, &stack);
    344   __msan_unpoison(dest + dest_size + copy_size, 1); // \0
    345   return res;
    346 }
    347 
    348 // Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
    349 // deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
    350 #define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
    351   ENSURE_MSAN_INITED();                             \
    352   ret_type res = REAL(func)(__VA_ARGS__);           \
    353   if (!__msan_has_dynamic_component()) {            \
    354     __msan_unpoison(endptr, sizeof(*endptr));       \
    355   }                                                 \
    356   return res;
    357 
    358 #define INTERCEPTOR_STRTO(ret_type, func)                        \
    359   INTERCEPTOR(ret_type, func, const char *nptr, char **endptr) { \
    360     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr);        \
    361   }
    362 
    363 #define INTERCEPTOR_STRTO_BASE(ret_type, func)                             \
    364   INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base) { \
    365     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base);            \
    366   }
    367 
    368 #define INTERCEPTOR_STRTO_LOC(ret_type, func)                               \
    369   INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, void *loc) { \
    370     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc);              \
    371   }
    372 
    373 #define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func)                       \
    374   INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base, \
    375               void *loc) {                                               \
    376     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc);     \
    377   }
    378 
    379 INTERCEPTOR_STRTO(double, strtod)                                    // NOLINT
    380 INTERCEPTOR_STRTO(float, strtof)                                     // NOLINT
    381 INTERCEPTOR_STRTO(long double, strtold)                              // NOLINT
    382 INTERCEPTOR_STRTO_BASE(long, strtol)                                 // NOLINT
    383 INTERCEPTOR_STRTO_BASE(long long, strtoll)                           // NOLINT
    384 INTERCEPTOR_STRTO_BASE(unsigned long, strtoul)                       // NOLINT
    385 INTERCEPTOR_STRTO_BASE(unsigned long long, strtoull)                 // NOLINT
    386 INTERCEPTOR_STRTO_LOC(double, strtod_l)                              // NOLINT
    387 INTERCEPTOR_STRTO_LOC(double, __strtod_l)                            // NOLINT
    388 INTERCEPTOR_STRTO_LOC(double, __strtod_internal)                     // NOLINT
    389 INTERCEPTOR_STRTO_LOC(float, strtof_l)                               // NOLINT
    390 INTERCEPTOR_STRTO_LOC(float, __strtof_l)                             // NOLINT
    391 INTERCEPTOR_STRTO_LOC(float, __strtof_internal)                      // NOLINT
    392 INTERCEPTOR_STRTO_LOC(long double, strtold_l)                        // NOLINT
    393 INTERCEPTOR_STRTO_LOC(long double, __strtold_l)                      // NOLINT
    394 INTERCEPTOR_STRTO_LOC(long double, __strtold_internal)               // NOLINT
    395 INTERCEPTOR_STRTO_BASE_LOC(long, strtol_l)                           // NOLINT
    396 INTERCEPTOR_STRTO_BASE_LOC(long, __strtol_l)                         // NOLINT
    397 INTERCEPTOR_STRTO_BASE_LOC(long, __strtol_internal)                  // NOLINT
    398 INTERCEPTOR_STRTO_BASE_LOC(long long, strtoll_l)                     // NOLINT
    399 INTERCEPTOR_STRTO_BASE_LOC(long long, __strtoll_l)                   // NOLINT
    400 INTERCEPTOR_STRTO_BASE_LOC(long long, __strtoll_internal)            // NOLINT
    401 INTERCEPTOR_STRTO_BASE_LOC(unsigned long, strtoul_l)                 // NOLINT
    402 INTERCEPTOR_STRTO_BASE_LOC(unsigned long, __strtoul_l)               // NOLINT
    403 INTERCEPTOR_STRTO_BASE_LOC(unsigned long, __strtoul_internal)        // NOLINT
    404 INTERCEPTOR_STRTO_BASE_LOC(unsigned long long, strtoull_l)           // NOLINT
    405 INTERCEPTOR_STRTO_BASE_LOC(unsigned long long, __strtoull_l)         // NOLINT
    406 INTERCEPTOR_STRTO_BASE_LOC(unsigned long long, __strtoull_internal)  // NOLINT
    407 
    408 // FIXME: support *wprintf in common format interceptors.
    409 INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
    410   ENSURE_MSAN_INITED();
    411   int res = REAL(vswprintf)(str, size, format, ap);
    412   if (res >= 0 && !__msan_has_dynamic_component()) {
    413     __msan_unpoison(str, 4 * (res + 1));
    414   }
    415   return res;
    416 }
    417 
    418 INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
    419   ENSURE_MSAN_INITED();
    420   va_list ap;
    421   va_start(ap, format);
    422   int res = vswprintf(str, size, format, ap);
    423   va_end(ap);
    424   return res;
    425 }
    426 
    427 INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {
    428   ENSURE_MSAN_INITED();
    429   CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
    430   SIZE_T res = REAL(strxfrm)(dest, src, n);
    431   if (res < n) __msan_unpoison(dest, res + 1);
    432   return res;
    433 }
    434 
    435 INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
    436             void *loc) {
    437   ENSURE_MSAN_INITED();
    438   CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
    439   SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);
    440   if (res < n) __msan_unpoison(dest, res + 1);
    441   return res;
    442 }
    443 
    444 #define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
    445   ENSURE_MSAN_INITED();                                              \
    446   ret_type res = REAL(func)(s, __VA_ARGS__);                         \
    447   if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1));          \
    448   return res;
    449 
    450 INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
    451             __sanitizer_tm *tm) {
    452   INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);
    453 }
    454 
    455 INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
    456             __sanitizer_tm *tm, void *loc) {
    457   INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
    458 }
    459 
    460 INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
    461             __sanitizer_tm *tm, void *loc) {
    462   INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
    463                             loc);
    464 }
    465 
    466 INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
    467             __sanitizer_tm *tm) {
    468   INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);
    469 }
    470 
    471 INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
    472             __sanitizer_tm *tm, void *loc) {
    473   INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,
    474                             loc);
    475 }
    476 
    477 INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
    478             __sanitizer_tm *tm, void *loc) {
    479   INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
    480                             loc);
    481 }
    482 
    483 INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
    484   ENSURE_MSAN_INITED();
    485   int res = REAL(mbtowc)(dest, src, n);
    486   if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
    487   return res;
    488 }
    489 
    490 INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
    491   ENSURE_MSAN_INITED();
    492   SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
    493   if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
    494   return res;
    495 }
    496 
    497 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
    498   ENSURE_MSAN_INITED();
    499   SIZE_T res = REAL(wcslen)(s);
    500   CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
    501   return res;
    502 }
    503 
    504 // wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
    505 INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
    506   ENSURE_MSAN_INITED();
    507   wchar_t *res = REAL(wcschr)(s, wc, ps);
    508   return res;
    509 }
    510 
    511 // wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
    512 INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
    513   ENSURE_MSAN_INITED();
    514   GET_STORE_STACK_TRACE;
    515   wchar_t *res = REAL(wcscpy)(dest, src);
    516   CopyPoison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1), &stack);
    517   return res;
    518 }
    519 
    520 // wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
    521 INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
    522   ENSURE_MSAN_INITED();
    523   GET_STORE_STACK_TRACE;
    524   wchar_t *res = REAL(wmemcpy)(dest, src, n);
    525   CopyPoison(dest, src, n * sizeof(wchar_t), &stack);
    526   return res;
    527 }
    528 
    529 INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
    530   ENSURE_MSAN_INITED();
    531   GET_STORE_STACK_TRACE;
    532   wchar_t *res = REAL(wmempcpy)(dest, src, n);
    533   CopyPoison(dest, src, n * sizeof(wchar_t), &stack);
    534   return res;
    535 }
    536 
    537 INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
    538   CHECK(MEM_IS_APP(s));
    539   ENSURE_MSAN_INITED();
    540   wchar_t *res = (wchar_t *)fast_memset(s, c, n * sizeof(wchar_t));
    541   __msan_unpoison(s, n * sizeof(wchar_t));
    542   return res;
    543 }
    544 
    545 INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
    546   ENSURE_MSAN_INITED();
    547   GET_STORE_STACK_TRACE;
    548   wchar_t *res = REAL(wmemmove)(dest, src, n);
    549   MovePoison(dest, src, n * sizeof(wchar_t), &stack);
    550   return res;
    551 }
    552 
    553 INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
    554   ENSURE_MSAN_INITED();
    555   int res = REAL(wcscmp)(s1, s2);
    556   return res;
    557 }
    558 
    559 INTERCEPTOR(double, wcstod, const wchar_t *nptr, wchar_t **endptr) {
    560   ENSURE_MSAN_INITED();
    561   double res = REAL(wcstod)(nptr, endptr);
    562   __msan_unpoison(endptr, sizeof(*endptr));
    563   return res;
    564 }
    565 
    566 INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
    567   ENSURE_MSAN_INITED();
    568   int res = REAL(gettimeofday)(tv, tz);
    569   if (tv)
    570     __msan_unpoison(tv, 16);
    571   if (tz)
    572     __msan_unpoison(tz, 8);
    573   return res;
    574 }
    575 
    576 INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
    577   ENSURE_MSAN_INITED();
    578   char *res = REAL(fcvt)(x, a, b, c);
    579   if (!__msan_has_dynamic_component()) {
    580     __msan_unpoison(b, sizeof(*b));
    581     __msan_unpoison(c, sizeof(*c));
    582   }
    583   return res;
    584 }
    585 
    586 INTERCEPTOR(char *, getenv, char *name) {
    587   ENSURE_MSAN_INITED();
    588   char *res = REAL(getenv)(name);
    589   if (!__msan_has_dynamic_component()) {
    590     if (res)
    591       __msan_unpoison(res, REAL(strlen)(res) + 1);
    592   }
    593   return res;
    594 }
    595 
    596 extern char **environ;
    597 
    598 static void UnpoisonEnviron() {
    599   char **envp = environ;
    600   for (; *envp; ++envp) {
    601     __msan_unpoison(envp, sizeof(*envp));
    602     __msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
    603   }
    604   // Trailing NULL pointer.
    605   __msan_unpoison(envp, sizeof(*envp));
    606 }
    607 
    608 INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
    609   ENSURE_MSAN_INITED();
    610   int res = REAL(setenv)(name, value, overwrite);
    611   if (!res) UnpoisonEnviron();
    612   return res;
    613 }
    614 
    615 INTERCEPTOR(int, putenv, char *string) {
    616   ENSURE_MSAN_INITED();
    617   int res = REAL(putenv)(string);
    618   if (!res) UnpoisonEnviron();
    619   return res;
    620 }
    621 
    622 INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
    623   ENSURE_MSAN_INITED();
    624   int res = REAL(__fxstat)(magic, fd, buf);
    625   if (!res)
    626     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    627   return res;
    628 }
    629 
    630 INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
    631   ENSURE_MSAN_INITED();
    632   int res = REAL(__fxstat64)(magic, fd, buf);
    633   if (!res)
    634     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
    635   return res;
    636 }
    637 
    638 INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
    639             int flags) {
    640   ENSURE_MSAN_INITED();
    641   int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);
    642   if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    643   return res;
    644 }
    645 
    646 INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
    647             int flags) {
    648   ENSURE_MSAN_INITED();
    649   int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);
    650   if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
    651   return res;
    652 }
    653 
    654 INTERCEPTOR(int, __xstat, int magic, char *path, void *buf) {
    655   ENSURE_MSAN_INITED();
    656   int res = REAL(__xstat)(magic, path, buf);
    657   if (!res)
    658     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    659   return res;
    660 }
    661 
    662 INTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) {
    663   ENSURE_MSAN_INITED();
    664   int res = REAL(__xstat64)(magic, path, buf);
    665   if (!res)
    666     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
    667   return res;
    668 }
    669 
    670 INTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) {
    671   ENSURE_MSAN_INITED();
    672   int res = REAL(__lxstat)(magic, path, buf);
    673   if (!res)
    674     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    675   return res;
    676 }
    677 
    678 INTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) {
    679   ENSURE_MSAN_INITED();
    680   int res = REAL(__lxstat64)(magic, path, buf);
    681   if (!res)
    682     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
    683   return res;
    684 }
    685 
    686 INTERCEPTOR(int, pipe, int pipefd[2]) {
    687   if (msan_init_is_running)
    688     return REAL(pipe)(pipefd);
    689   ENSURE_MSAN_INITED();
    690   int res = REAL(pipe)(pipefd);
    691   if (!res)
    692     __msan_unpoison(pipefd, sizeof(int[2]));
    693   return res;
    694 }
    695 
    696 INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
    697   ENSURE_MSAN_INITED();
    698   int res = REAL(pipe2)(pipefd, flags);
    699   if (!res)
    700     __msan_unpoison(pipefd, sizeof(int[2]));
    701   return res;
    702 }
    703 
    704 INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
    705   ENSURE_MSAN_INITED();
    706   int res = REAL(socketpair)(domain, type, protocol, sv);
    707   if (!res)
    708     __msan_unpoison(sv, sizeof(int[2]));
    709   return res;
    710 }
    711 
    712 INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
    713   ENSURE_MSAN_INITED();
    714   char *res = REAL(fgets)(s, size, stream);
    715   if (res)
    716     __msan_unpoison(s, REAL(strlen)(s) + 1);
    717   return res;
    718 }
    719 
    720 INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
    721   ENSURE_MSAN_INITED();
    722   char *res = REAL(fgets_unlocked)(s, size, stream);
    723   if (res)
    724     __msan_unpoison(s, REAL(strlen)(s) + 1);
    725   return res;
    726 }
    727 
    728 INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
    729   if (msan_init_is_running)
    730     return REAL(getrlimit)(resource, rlim);
    731   ENSURE_MSAN_INITED();
    732   int res = REAL(getrlimit)(resource, rlim);
    733   if (!res)
    734     __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
    735   return res;
    736 }
    737 
    738 INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
    739   if (msan_init_is_running)
    740     return REAL(getrlimit64)(resource, rlim);
    741   ENSURE_MSAN_INITED();
    742   int res = REAL(getrlimit64)(resource, rlim);
    743   if (!res)
    744     __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
    745   return res;
    746 }
    747 
    748 INTERCEPTOR(int, uname, void *utsname) {
    749   ENSURE_MSAN_INITED();
    750   int res = REAL(uname)(utsname);
    751   if (!res) {
    752     __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
    753   }
    754   return res;
    755 }
    756 
    757 INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
    758   ENSURE_MSAN_INITED();
    759   int res = REAL(gethostname)(name, len);
    760   if (!res) {
    761     SIZE_T real_len = REAL(strnlen)(name, len);
    762     if (real_len < len)
    763       ++real_len;
    764     __msan_unpoison(name, real_len);
    765   }
    766   return res;
    767 }
    768 
    769 INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
    770     int timeout) {
    771   ENSURE_MSAN_INITED();
    772   int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
    773   if (res > 0) {
    774     __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
    775   }
    776   return res;
    777 }
    778 
    779 INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
    780     int timeout, void *sigmask) {
    781   ENSURE_MSAN_INITED();
    782   int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
    783   if (res > 0) {
    784     __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
    785   }
    786   return res;
    787 }
    788 
    789 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
    790   ENSURE_MSAN_INITED();
    791   SSIZE_T res = REAL(recv)(fd, buf, len, flags);
    792   if (res > 0)
    793     __msan_unpoison(buf, res);
    794   return res;
    795 }
    796 
    797 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
    798             void *srcaddr, int *addrlen) {
    799   ENSURE_MSAN_INITED();
    800   SIZE_T srcaddr_sz;
    801   if (srcaddr) srcaddr_sz = *addrlen;
    802   SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
    803   if (res > 0) {
    804     __msan_unpoison(buf, res);
    805     if (srcaddr) {
    806       SIZE_T sz = *addrlen;
    807       __msan_unpoison(srcaddr, (sz < srcaddr_sz) ? sz : srcaddr_sz);
    808     }
    809   }
    810   return res;
    811 }
    812 
    813 INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
    814   if (CallocShouldReturnNullDueToOverflow(size, nmemb))
    815     return AllocatorReturnNull();
    816   GET_MALLOC_STACK_TRACE;
    817   if (!msan_inited) {
    818     // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
    819     const SIZE_T kCallocPoolSize = 1024;
    820     static uptr calloc_memory_for_dlsym[kCallocPoolSize];
    821     static SIZE_T allocated;
    822     SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
    823     void *mem = (void*)&calloc_memory_for_dlsym[allocated];
    824     allocated += size_in_words;
    825     CHECK(allocated < kCallocPoolSize);
    826     return mem;
    827   }
    828   return MsanReallocate(&stack, 0, nmemb * size, sizeof(u64), true);
    829 }
    830 
    831 INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
    832   GET_MALLOC_STACK_TRACE;
    833   return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
    834 }
    835 
    836 INTERCEPTOR(void *, malloc, SIZE_T size) {
    837   GET_MALLOC_STACK_TRACE;
    838   return MsanReallocate(&stack, 0, size, sizeof(u64), false);
    839 }
    840 
    841 void __msan_allocated_memory(const void* data, uptr size) {
    842   GET_MALLOC_STACK_TRACE;
    843   if (flags()->poison_in_malloc)
    844     __msan_poison(data, size);
    845   if (__msan_get_track_origins()) {
    846     u32 stack_id = StackDepotPut(stack.trace, stack.size);
    847     u32 id;
    848     ChainedOriginDepotPut(stack_id, Origin::kHeapRoot, &id);
    849     __msan_set_origin(data, size, Origin(id, 1).raw_id());
    850   }
    851 }
    852 
    853 INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
    854             int fd, OFF_T offset) {
    855   ENSURE_MSAN_INITED();
    856   if (addr && !MEM_IS_APP(addr)) {
    857     if (flags & map_fixed) {
    858       *__errno_location() = errno_EINVAL;
    859       return (void *)-1;
    860     } else {
    861       addr = 0;
    862     }
    863   }
    864   void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
    865   if (res != (void*)-1)
    866     __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
    867   return res;
    868 }
    869 
    870 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
    871             int fd, OFF64_T offset) {
    872   ENSURE_MSAN_INITED();
    873   if (addr && !MEM_IS_APP(addr)) {
    874     if (flags & map_fixed) {
    875       *__errno_location() = errno_EINVAL;
    876       return (void *)-1;
    877     } else {
    878       addr = 0;
    879     }
    880   }
    881   void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
    882   if (res != (void*)-1)
    883     __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
    884   return res;
    885 }
    886 
    887 struct dlinfo {
    888   char *dli_fname;
    889   void *dli_fbase;
    890   char *dli_sname;
    891   void *dli_saddr;
    892 };
    893 
    894 INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
    895   ENSURE_MSAN_INITED();
    896   int res = REAL(dladdr)(addr, info);
    897   if (res != 0) {
    898     __msan_unpoison(info, sizeof(*info));
    899     if (info->dli_fname)
    900       __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
    901     if (info->dli_sname)
    902       __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
    903   }
    904   return res;
    905 }
    906 
    907 INTERCEPTOR(char *, dlerror, int fake) {
    908   ENSURE_MSAN_INITED();
    909   char *res = REAL(dlerror)(fake);
    910   if (res != 0) __msan_unpoison(res, REAL(strlen)(res) + 1);
    911   return res;
    912 }
    913 
    914 typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
    915                                   void *data);
    916 struct dl_iterate_phdr_data {
    917   dl_iterate_phdr_cb callback;
    918   void *data;
    919 };
    920 
    921 static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
    922                                    void *data) {
    923   if (info) {
    924     __msan_unpoison(info, size);
    925     if (info->dlpi_name)
    926       __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
    927   }
    928   dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
    929   UnpoisonParam(3);
    930   return IndirectExternCall(cbdata->callback)(info, size, cbdata->data);
    931 }
    932 
    933 INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
    934   ENSURE_MSAN_INITED();
    935   EnterLoader();
    936   dl_iterate_phdr_data cbdata;
    937   cbdata.callback = callback;
    938   cbdata.data = data;
    939   int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
    940   ExitLoader();
    941   return res;
    942 }
    943 
    944 INTERCEPTOR(int, getrusage, int who, void *usage) {
    945   ENSURE_MSAN_INITED();
    946   int res = REAL(getrusage)(who, usage);
    947   if (res == 0) {
    948     __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
    949   }
    950   return res;
    951 }
    952 
    953 class SignalHandlerScope {
    954  public:
    955   SignalHandlerScope() {
    956     if (MsanThread *t = GetCurrentThread())
    957       t->EnterSignalHandler();
    958   }
    959   ~SignalHandlerScope() {
    960     if (MsanThread *t = GetCurrentThread())
    961       t->LeaveSignalHandler();
    962   }
    963 };
    964 
    965 // sigactions_mu guarantees atomicity of sigaction() and signal() calls.
    966 // Access to sigactions[] is gone with relaxed atomics to avoid data race with
    967 // the signal handler.
    968 const int kMaxSignals = 1024;
    969 static atomic_uintptr_t sigactions[kMaxSignals];
    970 static StaticSpinMutex sigactions_mu;
    971 
    972 static void SignalHandler(int signo) {
    973   SignalHandlerScope signal_handler_scope;
    974   ScopedThreadLocalStateBackup stlsb;
    975   UnpoisonParam(1);
    976 
    977   typedef void (*signal_cb)(int x);
    978   signal_cb cb =
    979       (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
    980   IndirectExternCall(cb)(signo);
    981 }
    982 
    983 static void SignalAction(int signo, void *si, void *uc) {
    984   SignalHandlerScope signal_handler_scope;
    985   ScopedThreadLocalStateBackup stlsb;
    986   UnpoisonParam(3);
    987   __msan_unpoison(si, sizeof(__sanitizer_sigaction));
    988   __msan_unpoison(uc, __sanitizer::ucontext_t_sz);
    989 
    990   typedef void (*sigaction_cb)(int, void *, void *);
    991   sigaction_cb cb =
    992       (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
    993   IndirectExternCall(cb)(signo, si, uc);
    994 }
    995 
    996 INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
    997             __sanitizer_sigaction *oldact) {
    998   ENSURE_MSAN_INITED();
    999   // FIXME: check that *act is unpoisoned.
   1000   // That requires intercepting all of sigemptyset, sigfillset, etc.
   1001   int res;
   1002   if (flags()->wrap_signals) {
   1003     SpinMutexLock lock(&sigactions_mu);
   1004     CHECK_LT(signo, kMaxSignals);
   1005     uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
   1006     __sanitizer_sigaction new_act;
   1007     __sanitizer_sigaction *pnew_act = act ? &new_act : 0;
   1008     if (act) {
   1009       internal_memcpy(pnew_act, act, sizeof(__sanitizer_sigaction));
   1010       uptr cb = (uptr)pnew_act->sigaction;
   1011       uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
   1012                         ? (uptr)SignalAction
   1013                         : (uptr)SignalHandler;
   1014       if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
   1015         atomic_store(&sigactions[signo], cb, memory_order_relaxed);
   1016         pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;
   1017       }
   1018     }
   1019     res = REAL(sigaction)(signo, pnew_act, oldact);
   1020     if (res == 0 && oldact) {
   1021       uptr cb = (uptr)oldact->sigaction;
   1022       if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
   1023         oldact->sigaction = (void (*)(int, void *, void *))old_cb;
   1024       }
   1025     }
   1026   } else {
   1027     res = REAL(sigaction)(signo, act, oldact);
   1028   }
   1029 
   1030   if (res == 0 && oldact) {
   1031     __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
   1032   }
   1033   return res;
   1034 }
   1035 
   1036 INTERCEPTOR(int, signal, int signo, uptr cb) {
   1037   ENSURE_MSAN_INITED();
   1038   if (flags()->wrap_signals) {
   1039     CHECK_LT(signo, kMaxSignals);
   1040     SpinMutexLock lock(&sigactions_mu);
   1041     if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
   1042       atomic_store(&sigactions[signo], cb, memory_order_relaxed);
   1043       cb = (uptr) SignalHandler;
   1044     }
   1045     return REAL(signal)(signo, cb);
   1046   } else {
   1047     return REAL(signal)(signo, cb);
   1048   }
   1049 }
   1050 
   1051 extern "C" int pthread_attr_init(void *attr);
   1052 extern "C" int pthread_attr_destroy(void *attr);
   1053 
   1054 static void *MsanThreadStartFunc(void *arg) {
   1055   MsanThread *t = (MsanThread *)arg;
   1056   SetCurrentThread(t);
   1057   return t->ThreadStart();
   1058 }
   1059 
   1060 INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
   1061             void * param) {
   1062   ENSURE_MSAN_INITED(); // for GetTlsSize()
   1063   __sanitizer_pthread_attr_t myattr;
   1064   if (attr == 0) {
   1065     pthread_attr_init(&myattr);
   1066     attr = &myattr;
   1067   }
   1068 
   1069   AdjustStackSize(attr);
   1070 
   1071   MsanThread *t = MsanThread::Create(callback, param);
   1072 
   1073   int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);
   1074 
   1075   if (attr == &myattr)
   1076     pthread_attr_destroy(&myattr);
   1077   if (!res) {
   1078     __msan_unpoison(th, __sanitizer::pthread_t_sz);
   1079   }
   1080   return res;
   1081 }
   1082 
   1083 INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
   1084             void (*dtor)(void *value)) {
   1085   if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);
   1086   ENSURE_MSAN_INITED();
   1087   int res = REAL(pthread_key_create)(key, dtor);
   1088   if (!res && key)
   1089     __msan_unpoison(key, sizeof(*key));
   1090   return res;
   1091 }
   1092 
   1093 INTERCEPTOR(int, pthread_join, void *th, void **retval) {
   1094   ENSURE_MSAN_INITED();
   1095   int res = REAL(pthread_join)(th, retval);
   1096   if (!res && retval)
   1097     __msan_unpoison(retval, sizeof(*retval));
   1098   return res;
   1099 }
   1100 
   1101 extern char *tzname[2];
   1102 
   1103 INTERCEPTOR(void, tzset, int fake) {
   1104   ENSURE_MSAN_INITED();
   1105   REAL(tzset)(fake);
   1106   if (tzname[0])
   1107     __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);
   1108   if (tzname[1])
   1109     __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);
   1110   return;
   1111 }
   1112 
   1113 struct MSanAtExitRecord {
   1114   void (*func)(void *arg);
   1115   void *arg;
   1116 };
   1117 
   1118 void MSanAtExitWrapper(void *arg) {
   1119   UnpoisonParam(1);
   1120   MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
   1121   IndirectExternCall(r->func)(r->arg);
   1122   InternalFree(r);
   1123 }
   1124 
   1125 // Unpoison argument shadow for C++ module destructors.
   1126 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
   1127             void *dso_handle) {
   1128   if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
   1129   ENSURE_MSAN_INITED();
   1130   MSanAtExitRecord *r =
   1131       (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
   1132   r->func = func;
   1133   r->arg = arg;
   1134   return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
   1135 }
   1136 
   1137 DECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf)
   1138 
   1139 INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
   1140   ENSURE_MSAN_INITED();
   1141   void *p = REAL(shmat)(shmid, shmaddr, shmflg);
   1142   if (p != (void *)-1) {
   1143     __sanitizer_shmid_ds ds;
   1144     int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);
   1145     if (!res) {
   1146       __msan_unpoison(p, ds.shm_segsz);
   1147     }
   1148   }
   1149   return p;
   1150 }
   1151 
   1152 // Linux kernel has a bug that leads to kernel deadlock if a process
   1153 // maps TBs of memory and then calls mlock().
   1154 static void MlockIsUnsupported() {
   1155   static atomic_uint8_t printed;
   1156   if (atomic_exchange(&printed, 1, memory_order_relaxed))
   1157     return;
   1158   VPrintf(1,
   1159           "INFO: MemorySanitizer ignores mlock/mlockall/munlock/munlockall\n");
   1160 }
   1161 
   1162 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
   1163   MlockIsUnsupported();
   1164   return 0;
   1165 }
   1166 
   1167 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
   1168   MlockIsUnsupported();
   1169   return 0;
   1170 }
   1171 
   1172 INTERCEPTOR(int, mlockall, int flags) {
   1173   MlockIsUnsupported();
   1174   return 0;
   1175 }
   1176 
   1177 INTERCEPTOR(int, munlockall, void) {
   1178   MlockIsUnsupported();
   1179   return 0;
   1180 }
   1181 
   1182 struct MSanInterceptorContext {
   1183   bool in_interceptor_scope;
   1184 };
   1185 
   1186 namespace __msan {
   1187 
   1188 int OnExit() {
   1189   // FIXME: ask frontend whether we need to return failure.
   1190   return 0;
   1191 }
   1192 
   1193 }  // namespace __msan
   1194 
   1195 // A version of CHECK_UNPOISONED using a saved scope value. Used in common
   1196 // interceptors.
   1197 #define CHECK_UNPOISONED_CTX(ctx, x, n)                         \
   1198   do {                                                          \
   1199     if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
   1200       CHECK_UNPOISONED_0(x, n);                                 \
   1201   } while (0)
   1202 
   1203 #define MSAN_INTERCEPT_FUNC(name)                                       \
   1204   do {                                                                  \
   1205     if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                     \
   1206       VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \
   1207   } while (0)
   1208 
   1209 #define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
   1210 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count)  \
   1211   UnpoisonParam(count)
   1212 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
   1213   __msan_unpoison(ptr, size)
   1214 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
   1215   CHECK_UNPOISONED_CTX(ctx, ptr, size)
   1216 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \
   1217   __msan_unpoison(ptr, size)
   1218 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                  \
   1219   if (msan_init_is_running) return REAL(func)(__VA_ARGS__);       \
   1220   MSanInterceptorContext msan_ctx = {IsInInterceptorScope()};     \
   1221   ctx = (void *)&msan_ctx;                                        \
   1222   (void)ctx;                                                      \
   1223   InterceptorScope interceptor_scope;                             \
   1224   __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */  \
   1225   ENSURE_MSAN_INITED();
   1226 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
   1227   do {                                         \
   1228   } while (false)
   1229 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
   1230   do {                                         \
   1231   } while (false)
   1232 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
   1233   do {                                                      \
   1234   } while (false)
   1235 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
   1236   do {                                                \
   1237   } while (false)  // FIXME
   1238 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
   1239   do {                                                         \
   1240   } while (false)  // FIXME
   1241 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
   1242 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
   1243 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map)                       \
   1244   if (!__msan_has_dynamic_component() && map) {                                \
   1245     /* If msandr didn't clear the shadow before the initializers ran, we do */ \
   1246     /* it ourselves afterwards. */                                             \
   1247     ForEachMappedRegion((link_map *)map, __msan_unpoison);                     \
   1248   }
   1249 
   1250 #include "sanitizer_common/sanitizer_common_interceptors.inc"
   1251 
   1252 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
   1253 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
   1254   do {                                       \
   1255   } while (false)
   1256 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
   1257   do {                                       \
   1258   } while (false)
   1259 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
   1260 #include "sanitizer_common/sanitizer_common_syscalls.inc"
   1261 
   1262 // static
   1263 void *fast_memset(void *ptr, int c, SIZE_T n) {
   1264   // hack until we have a really fast internal_memset
   1265   if (sizeof(uptr) == 8 &&
   1266       (n % 8) == 0 &&
   1267       ((uptr)ptr % 8) == 0) {
   1268     uptr c8 = (unsigned)c & 0xFF;
   1269     c8 = (c8 << 8) | c8;
   1270     c8 = (c8 << 16) | c8;
   1271     c8 = (c8 << 32) | c8;
   1272     uptr *p = (uptr*)ptr;
   1273     for (SIZE_T i = 0; i < n / 8; i++)
   1274       p[i] = c8;
   1275     return ptr;
   1276   }
   1277   return internal_memset(ptr, c, n);
   1278 }
   1279 
   1280 // static
   1281 void *fast_memcpy(void *dst, const void *src, SIZE_T n) {
   1282   // Same hack as in fast_memset above.
   1283   if (sizeof(uptr) == 8 &&
   1284       (n % 8) == 0 &&
   1285       ((uptr)dst % 8) == 0 &&
   1286       ((uptr)src % 8) == 0) {
   1287     uptr *d = (uptr*)dst;
   1288     uptr *s = (uptr*)src;
   1289     for (SIZE_T i = 0; i < n / 8; i++)
   1290       d[i] = s[i];
   1291     return dst;
   1292   }
   1293   return internal_memcpy(dst, src, n);
   1294 }
   1295 
   1296 static void PoisonShadow(uptr ptr, uptr size, u8 value) {
   1297   uptr PageSize = GetPageSizeCached();
   1298   uptr shadow_beg = MEM_TO_SHADOW(ptr);
   1299   uptr shadow_end = MEM_TO_SHADOW(ptr + size);
   1300   if (value ||
   1301       shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
   1302     fast_memset((void*)shadow_beg, value, shadow_end - shadow_beg);
   1303   } else {
   1304     uptr page_beg = RoundUpTo(shadow_beg, PageSize);
   1305     uptr page_end = RoundDownTo(shadow_end, PageSize);
   1306 
   1307     if (page_beg >= page_end) {
   1308       fast_memset((void *)shadow_beg, 0, shadow_end - shadow_beg);
   1309     } else {
   1310       if (page_beg != shadow_beg) {
   1311         fast_memset((void *)shadow_beg, 0, page_beg - shadow_beg);
   1312       }
   1313       if (page_end != shadow_end) {
   1314         fast_memset((void *)page_end, 0, shadow_end - page_end);
   1315       }
   1316       MmapFixedNoReserve(page_beg, page_end - page_beg);
   1317     }
   1318   }
   1319 }
   1320 
   1321 // These interface functions reside here so that they can use
   1322 // fast_memset, etc.
   1323 void __msan_unpoison(const void *a, uptr size) {
   1324   if (!MEM_IS_APP(a)) return;
   1325   PoisonShadow((uptr)a, size, 0);
   1326 }
   1327 
   1328 void __msan_poison(const void *a, uptr size) {
   1329   if (!MEM_IS_APP(a)) return;
   1330   PoisonShadow((uptr)a, size,
   1331                __msan::flags()->poison_heap_with_zeroes ? 0 : -1);
   1332 }
   1333 
   1334 void __msan_poison_stack(void *a, uptr size) {
   1335   if (!MEM_IS_APP(a)) return;
   1336   PoisonShadow((uptr)a, size,
   1337                __msan::flags()->poison_stack_with_zeroes ? 0 : -1);
   1338 }
   1339 
   1340 void __msan_clear_and_unpoison(void *a, uptr size) {
   1341   fast_memset(a, 0, size);
   1342   PoisonShadow((uptr)a, size, 0);
   1343 }
   1344 
   1345 void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
   1346   if (!msan_inited) return internal_memcpy(dest, src, n);
   1347   if (msan_init_is_running) return REAL(memcpy)(dest, src, n);
   1348   ENSURE_MSAN_INITED();
   1349   GET_STORE_STACK_TRACE;
   1350   void *res = fast_memcpy(dest, src, n);
   1351   CopyPoison(dest, src, n, &stack);
   1352   return res;
   1353 }
   1354 
   1355 void *__msan_memset(void *s, int c, SIZE_T n) {
   1356   if (!msan_inited) return internal_memset(s, c, n);
   1357   if (msan_init_is_running) return REAL(memset)(s, c, n);
   1358   ENSURE_MSAN_INITED();
   1359   void *res = fast_memset(s, c, n);
   1360   __msan_unpoison(s, n);
   1361   return res;
   1362 }
   1363 
   1364 void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
   1365   if (!msan_inited) return internal_memmove(dest, src, n);
   1366   if (msan_init_is_running) return REAL(memmove)(dest, src, n);
   1367   ENSURE_MSAN_INITED();
   1368   GET_STORE_STACK_TRACE;
   1369   void *res = REAL(memmove)(dest, src, n);
   1370   MovePoison(dest, src, n, &stack);
   1371   return res;
   1372 }
   1373 
   1374 void __msan_unpoison_string(const char* s) {
   1375   if (!MEM_IS_APP(s)) return;
   1376   __msan_unpoison(s, REAL(strlen)(s) + 1);
   1377 }
   1378 
   1379 namespace __msan {
   1380 
   1381 u32 GetOriginIfPoisoned(uptr addr, uptr size) {
   1382   unsigned char *s = (unsigned char *)MEM_TO_SHADOW(addr);
   1383   for (uptr i = 0; i < size; ++i)
   1384     if (s[i])
   1385       return *(u32 *)SHADOW_TO_ORIGIN((s + i) & ~3UL);
   1386   return 0;
   1387 }
   1388 
   1389 void SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size,
   1390                          u32 src_origin) {
   1391   uptr dst_s = MEM_TO_SHADOW(addr);
   1392   uptr src_s = src_shadow;
   1393   uptr src_s_end = src_s + size;
   1394 
   1395   for (; src_s < src_s_end; ++dst_s, ++src_s)
   1396     if (*(u8 *)src_s) *(u32 *)SHADOW_TO_ORIGIN(dst_s &~3UL) = src_origin;
   1397 }
   1398 
   1399 void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack) {
   1400   if (!__msan_get_track_origins()) return;
   1401   if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;
   1402 
   1403   uptr d = (uptr)dst;
   1404   uptr beg = d & ~3UL;
   1405   // Copy left unaligned origin if that memory is poisoned.
   1406   if (beg < d) {
   1407     u32 o = GetOriginIfPoisoned((uptr)src, d - beg);
   1408     if (o) {
   1409       if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
   1410       *(u32 *)MEM_TO_ORIGIN(beg) = o;
   1411     }
   1412     beg += 4;
   1413   }
   1414 
   1415   uptr end = (d + size) & ~3UL;
   1416   // If both ends fall into the same 4-byte slot, we are done.
   1417   if (end < beg) return;
   1418 
   1419   // Copy right unaligned origin if that memory is poisoned.
   1420   if (end < d + size) {
   1421     u32 o = GetOriginIfPoisoned((uptr)src + (end - d), (d + size) - end);
   1422     if (o) {
   1423       if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
   1424       *(u32 *)MEM_TO_ORIGIN(end) = o;
   1425     }
   1426   }
   1427 
   1428   if (beg < end) {
   1429     // Align src up.
   1430     uptr s = ((uptr)src + 3) & ~3UL;
   1431     // FIXME: factor out to msan_copy_origin_aligned
   1432     if (__msan_get_track_origins() > 1) {
   1433       u32 *src = (u32 *)MEM_TO_ORIGIN(s);
   1434       u32 *src_s = (u32 *)MEM_TO_SHADOW(s);
   1435       u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg));
   1436       u32 *dst = (u32 *)MEM_TO_ORIGIN(beg);
   1437       u32 src_o = 0;
   1438       u32 dst_o = 0;
   1439       for (; src < src_end; ++src, ++src_s, ++dst) {
   1440         if (!*src_s) continue;
   1441         if (*src != src_o) {
   1442           src_o = *src;
   1443           dst_o = ChainOrigin(src_o, stack);
   1444         }
   1445         *dst = dst_o;
   1446       }
   1447     } else {
   1448       fast_memcpy((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
   1449                   end - beg);
   1450     }
   1451   }
   1452 }
   1453 
   1454 void MovePoison(void *dst, const void *src, uptr size, StackTrace *stack) {
   1455   if (!MEM_IS_APP(dst)) return;
   1456   if (!MEM_IS_APP(src)) return;
   1457   if (src == dst) return;
   1458   internal_memmove((void *)MEM_TO_SHADOW((uptr)dst),
   1459                    (void *)MEM_TO_SHADOW((uptr)src), size);
   1460   CopyOrigin(dst, src, size, stack);
   1461 }
   1462 
   1463 void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack) {
   1464   if (!MEM_IS_APP(dst)) return;
   1465   if (!MEM_IS_APP(src)) return;
   1466   fast_memcpy((void *)MEM_TO_SHADOW((uptr)dst),
   1467               (void *)MEM_TO_SHADOW((uptr)src), size);
   1468   CopyOrigin(dst, src, size, stack);
   1469 }
   1470 
   1471 void InitializeInterceptors() {
   1472   static int inited = 0;
   1473   CHECK_EQ(inited, 0);
   1474   InitializeCommonInterceptors();
   1475 
   1476   INTERCEPT_FUNCTION(mmap);
   1477   INTERCEPT_FUNCTION(mmap64);
   1478   INTERCEPT_FUNCTION(posix_memalign);
   1479   INTERCEPT_FUNCTION(memalign);
   1480   INTERCEPT_FUNCTION(__libc_memalign);
   1481   INTERCEPT_FUNCTION(valloc);
   1482   INTERCEPT_FUNCTION(pvalloc);
   1483   INTERCEPT_FUNCTION(malloc);
   1484   INTERCEPT_FUNCTION(calloc);
   1485   INTERCEPT_FUNCTION(realloc);
   1486   INTERCEPT_FUNCTION(free);
   1487   INTERCEPT_FUNCTION(cfree);
   1488   INTERCEPT_FUNCTION(malloc_usable_size);
   1489   INTERCEPT_FUNCTION(mallinfo);
   1490   INTERCEPT_FUNCTION(mallopt);
   1491   INTERCEPT_FUNCTION(malloc_stats);
   1492   INTERCEPT_FUNCTION(fread);
   1493   INTERCEPT_FUNCTION(fread_unlocked);
   1494   INTERCEPT_FUNCTION(readlink);
   1495   INTERCEPT_FUNCTION(memcpy);
   1496   INTERCEPT_FUNCTION(memccpy);
   1497   INTERCEPT_FUNCTION(mempcpy);
   1498   INTERCEPT_FUNCTION(memset);
   1499   INTERCEPT_FUNCTION(memmove);
   1500   INTERCEPT_FUNCTION(bcopy);
   1501   INTERCEPT_FUNCTION(wmemset);
   1502   INTERCEPT_FUNCTION(wmemcpy);
   1503   INTERCEPT_FUNCTION(wmempcpy);
   1504   INTERCEPT_FUNCTION(wmemmove);
   1505   INTERCEPT_FUNCTION(strcpy);  // NOLINT
   1506   INTERCEPT_FUNCTION(stpcpy);  // NOLINT
   1507   INTERCEPT_FUNCTION(strdup);
   1508   INTERCEPT_FUNCTION(__strdup);
   1509   INTERCEPT_FUNCTION(strndup);
   1510   INTERCEPT_FUNCTION(__strndup);
   1511   INTERCEPT_FUNCTION(strncpy);  // NOLINT
   1512   INTERCEPT_FUNCTION(strlen);
   1513   INTERCEPT_FUNCTION(strnlen);
   1514   INTERCEPT_FUNCTION(gcvt);
   1515   INTERCEPT_FUNCTION(strcat);  // NOLINT
   1516   INTERCEPT_FUNCTION(strncat);  // NOLINT
   1517   INTERCEPT_FUNCTION(strtod);
   1518   INTERCEPT_FUNCTION(strtof);
   1519   INTERCEPT_FUNCTION(strtold);
   1520   INTERCEPT_FUNCTION(strtol);
   1521   INTERCEPT_FUNCTION(strtoll);
   1522   INTERCEPT_FUNCTION(strtoul);
   1523   INTERCEPT_FUNCTION(strtoull);
   1524   INTERCEPT_FUNCTION(strtod_l);
   1525   INTERCEPT_FUNCTION(__strtod_l);
   1526   INTERCEPT_FUNCTION(__strtod_internal);
   1527   INTERCEPT_FUNCTION(strtof_l);
   1528   INTERCEPT_FUNCTION(__strtof_l);
   1529   INTERCEPT_FUNCTION(__strtof_internal);
   1530   INTERCEPT_FUNCTION(strtold_l);
   1531   INTERCEPT_FUNCTION(__strtold_l);
   1532   INTERCEPT_FUNCTION(__strtold_internal);
   1533   INTERCEPT_FUNCTION(strtol_l);
   1534   INTERCEPT_FUNCTION(__strtol_l);
   1535   INTERCEPT_FUNCTION(__strtol_internal);
   1536   INTERCEPT_FUNCTION(strtoll_l);
   1537   INTERCEPT_FUNCTION(__strtoll_l);
   1538   INTERCEPT_FUNCTION(__strtoll_internal);
   1539   INTERCEPT_FUNCTION(strtoul_l);
   1540   INTERCEPT_FUNCTION(__strtoul_l);
   1541   INTERCEPT_FUNCTION(__strtoul_internal);
   1542   INTERCEPT_FUNCTION(strtoull_l);
   1543   INTERCEPT_FUNCTION(__strtoull_l);
   1544   INTERCEPT_FUNCTION(__strtoull_internal);
   1545   INTERCEPT_FUNCTION(vswprintf);
   1546   INTERCEPT_FUNCTION(swprintf);
   1547   INTERCEPT_FUNCTION(strxfrm);
   1548   INTERCEPT_FUNCTION(strxfrm_l);
   1549   INTERCEPT_FUNCTION(strftime);
   1550   INTERCEPT_FUNCTION(strftime_l);
   1551   INTERCEPT_FUNCTION(__strftime_l);
   1552   INTERCEPT_FUNCTION(wcsftime);
   1553   INTERCEPT_FUNCTION(wcsftime_l);
   1554   INTERCEPT_FUNCTION(__wcsftime_l);
   1555   INTERCEPT_FUNCTION(mbtowc);
   1556   INTERCEPT_FUNCTION(mbrtowc);
   1557   INTERCEPT_FUNCTION(wcslen);
   1558   INTERCEPT_FUNCTION(wcschr);
   1559   INTERCEPT_FUNCTION(wcscpy);
   1560   INTERCEPT_FUNCTION(wcscmp);
   1561   INTERCEPT_FUNCTION(wcstod);
   1562   INTERCEPT_FUNCTION(getenv);
   1563   INTERCEPT_FUNCTION(setenv);
   1564   INTERCEPT_FUNCTION(putenv);
   1565   INTERCEPT_FUNCTION(gettimeofday);
   1566   INTERCEPT_FUNCTION(fcvt);
   1567   INTERCEPT_FUNCTION(__fxstat);
   1568   INTERCEPT_FUNCTION(__fxstatat);
   1569   INTERCEPT_FUNCTION(__xstat);
   1570   INTERCEPT_FUNCTION(__lxstat);
   1571   INTERCEPT_FUNCTION(__fxstat64);
   1572   INTERCEPT_FUNCTION(__fxstatat64);
   1573   INTERCEPT_FUNCTION(__xstat64);
   1574   INTERCEPT_FUNCTION(__lxstat64);
   1575   INTERCEPT_FUNCTION(pipe);
   1576   INTERCEPT_FUNCTION(pipe2);
   1577   INTERCEPT_FUNCTION(socketpair);
   1578   INTERCEPT_FUNCTION(fgets);
   1579   INTERCEPT_FUNCTION(fgets_unlocked);
   1580   INTERCEPT_FUNCTION(getrlimit);
   1581   INTERCEPT_FUNCTION(getrlimit64);
   1582   INTERCEPT_FUNCTION(uname);
   1583   INTERCEPT_FUNCTION(gethostname);
   1584   INTERCEPT_FUNCTION(epoll_wait);
   1585   INTERCEPT_FUNCTION(epoll_pwait);
   1586   INTERCEPT_FUNCTION(recv);
   1587   INTERCEPT_FUNCTION(recvfrom);
   1588   INTERCEPT_FUNCTION(dladdr);
   1589   INTERCEPT_FUNCTION(dlerror);
   1590   INTERCEPT_FUNCTION(dl_iterate_phdr);
   1591   INTERCEPT_FUNCTION(getrusage);
   1592   INTERCEPT_FUNCTION(sigaction);
   1593   INTERCEPT_FUNCTION(signal);
   1594   INTERCEPT_FUNCTION(pthread_create);
   1595   INTERCEPT_FUNCTION(pthread_key_create);
   1596   INTERCEPT_FUNCTION(pthread_join);
   1597   INTERCEPT_FUNCTION(tzset);
   1598   INTERCEPT_FUNCTION(__cxa_atexit);
   1599   INTERCEPT_FUNCTION(shmat);
   1600 
   1601   inited = 1;
   1602 }
   1603 }  // namespace __msan
   1604