Home | History | Annotate | Line # | Download | only in sanitizer_common
      1 //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
      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 // Common function interceptors for tools like AddressSanitizer,
     11 // ThreadSanitizer, MemorySanitizer, etc.
     12 //
     13 // This file should be included into the tool's interceptor file,
     14 // which has to define its own macros:
     15 //   COMMON_INTERCEPTOR_ENTER
     16 //   COMMON_INTERCEPTOR_ENTER_NOIGNORE
     17 //   COMMON_INTERCEPTOR_READ_RANGE
     18 //   COMMON_INTERCEPTOR_WRITE_RANGE
     19 //   COMMON_INTERCEPTOR_INITIALIZE_RANGE
     20 //   COMMON_INTERCEPTOR_DIR_ACQUIRE
     21 //   COMMON_INTERCEPTOR_FD_ACQUIRE
     22 //   COMMON_INTERCEPTOR_FD_RELEASE
     23 //   COMMON_INTERCEPTOR_FD_ACCESS
     24 //   COMMON_INTERCEPTOR_SET_THREAD_NAME
     25 //   COMMON_INTERCEPTOR_ON_DLOPEN
     26 //   COMMON_INTERCEPTOR_ON_EXIT
     27 //   COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
     28 //   COMMON_INTERCEPTOR_MUTEX_POST_LOCK
     29 //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
     30 //   COMMON_INTERCEPTOR_MUTEX_REPAIR
     31 //   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
     32 //   COMMON_INTERCEPTOR_HANDLE_RECVMSG
     33 //   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
     34 //   COMMON_INTERCEPTOR_MEMSET_IMPL
     35 //   COMMON_INTERCEPTOR_MEMMOVE_IMPL
     36 //   COMMON_INTERCEPTOR_MEMCPY_IMPL
     37 //   COMMON_INTERCEPTOR_MMAP_IMPL
     38 //   COMMON_INTERCEPTOR_COPY_STRING
     39 //   COMMON_INTERCEPTOR_STRNDUP_IMPL
     40 //===----------------------------------------------------------------------===//
     41 
     42 #include "interception/interception.h"
     43 #include "sanitizer_addrhashmap.h"
     44 #include "sanitizer_errno.h"
     45 #include "sanitizer_placement_new.h"
     46 #include "sanitizer_platform_interceptors.h"
     47 #include "sanitizer_symbolizer.h"
     48 #include "sanitizer_tls_get_addr.h"
     49 
     50 #include <stdarg.h>
     51 
     52 #if SANITIZER_INTERCEPTOR_HOOKS
     53 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__);
     54 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
     55   SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {}
     56 #else
     57 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
     58 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
     59 
     60 #endif  // SANITIZER_INTERCEPTOR_HOOKS
     61 
     62 #if SANITIZER_WINDOWS && !defined(va_copy)
     63 #define va_copy(dst, src) ((dst) = (src))
     64 #endif // _WIN32
     65 
     66 #if SANITIZER_FREEBSD
     67 #define pthread_setname_np pthread_set_name_np
     68 #define inet_aton __inet_aton
     69 #define inet_pton __inet_pton
     70 #define iconv __bsd_iconv
     71 #endif
     72 
     73 #if SANITIZER_NETBSD
     74 #define clock_getres __clock_getres50
     75 #define clock_gettime __clock_gettime50
     76 #define clock_settime __clock_settime50
     77 #define ctime __ctime50
     78 #define ctime_r __ctime_r50
     79 #define devname __devname50
     80 #define fgetpos __fgetpos50
     81 #define fsetpos __fsetpos50
     82 #define fts_children __fts_children60
     83 #define fts_close __fts_close60
     84 #define fts_open __fts_open60
     85 #define fts_read __fts_read60
     86 #define fts_set __fts_set60
     87 #define getitimer __getitimer50
     88 #define getmntinfo __getmntinfo13
     89 #define getpwent __getpwent50
     90 #define getpwnam __getpwnam50
     91 #define getpwnam_r __getpwnam_r50
     92 #define getpwuid __getpwuid50
     93 #define getpwuid_r __getpwuid_r50
     94 #define getutent __getutent50
     95 #define getutxent __getutxent50
     96 #define getutxid __getutxid50
     97 #define getutxline __getutxline50
     98 #define glob __glob30
     99 #define gmtime __gmtime50
    100 #define gmtime_r __gmtime_r50
    101 #define localtime __locatime50
    102 #define localtime_r __localtime_r50
    103 #define mktime __mktime50
    104 #define lstat __lstat50
    105 #define opendir __opendir30
    106 #define readdir __readdir30
    107 #define readdir_r __readdir_r30
    108 #define scandir __scandir30
    109 #define setitimer __setitimer50
    110 #define setlocale __setlocale50
    111 #define shmctl __shmctl50
    112 #define sigemptyset __sigemptyset14
    113 #define sigfillset __sigfillset14
    114 #define sigpending __sigpending14
    115 #define sigprocmask __sigprocmask14
    116 #define sigtimedwait __sigtimedwait50
    117 #define stat __stat50
    118 #define time __time50
    119 #define times __times13
    120 #define unvis __unvis50
    121 #define wait3 __wait350
    122 #define wait4 __wait450
    123 extern const unsigned short *_ctype_tab_;
    124 extern const short *_toupper_tab_;
    125 extern const short *_tolower_tab_;
    126 #endif
    127 
    128 // Platform-specific options.
    129 #if SANITIZER_MAC
    130 namespace __sanitizer {
    131 bool PlatformHasDifferentMemcpyAndMemmove();
    132 }
    133 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \
    134   (__sanitizer::PlatformHasDifferentMemcpyAndMemmove())
    135 #elif SANITIZER_WINDOWS64
    136 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false
    137 #else
    138 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true
    139 #endif  // SANITIZER_MAC
    140 
    141 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
    142 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
    143 #endif
    144 
    145 #ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
    146 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
    147 #endif
    148 
    149 #ifndef COMMON_INTERCEPTOR_FD_ACCESS
    150 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
    151 #endif
    152 
    153 #ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
    154 #define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {}
    155 #endif
    156 
    157 #ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK
    158 #define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {}
    159 #endif
    160 
    161 #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
    162 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
    163 #endif
    164 
    165 #ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
    166 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
    167 #endif
    168 
    169 #ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
    170 #define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
    171 #endif
    172 
    173 #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
    174 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
    175 #endif
    176 
    177 #ifndef COMMON_INTERCEPTOR_FILE_OPEN
    178 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
    179 #endif
    180 
    181 #ifndef COMMON_INTERCEPTOR_FILE_CLOSE
    182 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
    183 #endif
    184 
    185 #ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
    186 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
    187 #endif
    188 
    189 #ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
    190 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
    191 #endif
    192 
    193 #ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
    194 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
    195   COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
    196 #endif
    197 
    198 #ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
    199 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
    200 #endif
    201 
    202 #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
    203     COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
    204       common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) )
    205 
    206 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
    207 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
    208   CheckNoDeepBind(filename, flag);
    209 #endif
    210 
    211 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
    212 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
    213 #endif
    214 
    215 #ifndef COMMON_INTERCEPTOR_ACQUIRE
    216 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
    217 #endif
    218 
    219 #ifndef COMMON_INTERCEPTOR_RELEASE
    220 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
    221 #endif
    222 
    223 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
    224 #define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
    225 #endif
    226 
    227 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
    228 #define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
    229 #endif
    230 
    231 #ifdef SANITIZER_NLDBL_VERSION
    232 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
    233     COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
    234 #else
    235 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
    236     COMMON_INTERCEPT_FUNCTION(fn)
    237 #endif
    238 
    239 #ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
    240 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
    241   {                                                       \
    242     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)        \
    243       return internal_memset(dst, v, size);               \
    244     COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);  \
    245     if (common_flags()->intercept_intrin)                 \
    246       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);     \
    247     return REAL(memset)(dst, v, size);                    \
    248   }
    249 #endif
    250 
    251 #ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL
    252 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \
    253   {                                                          \
    254     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)           \
    255       return internal_memmove(dst, src, size);               \
    256     COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);  \
    257     if (common_flags()->intercept_intrin) {                  \
    258       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);        \
    259       COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);         \
    260     }                                                        \
    261     return REAL(memmove)(dst, src, size);                    \
    262   }
    263 #endif
    264 
    265 #ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL
    266 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \
    267   {                                                         \
    268     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {        \
    269       return internal_memmove(dst, src, size);              \
    270     }                                                       \
    271     COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);  \
    272     if (common_flags()->intercept_intrin) {                 \
    273       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);       \
    274       COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);        \
    275     }                                                       \
    276     return REAL(memcpy)(dst, src, size);                    \
    277   }
    278 #endif
    279 
    280 #ifndef COMMON_INTERCEPTOR_MMAP_IMPL
    281 #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
    282                                      off)                                  \
    283   { return REAL(mmap)(addr, sz, prot, flags, fd, off); }
    284 #endif
    285 
    286 #ifndef COMMON_INTERCEPTOR_COPY_STRING
    287 #define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
    288 #endif
    289 
    290 #ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
    291 #define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size)                         \
    292   COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size);                            \
    293   uptr copy_length = internal_strnlen(s, size);                               \
    294   char *new_mem = (char *)WRAP(malloc)(copy_length + 1);                      \
    295   if (common_flags()->intercept_strndup) {                                    \
    296     COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1));       \
    297   }                                                                           \
    298   COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length);               \
    299   internal_memcpy(new_mem, s, copy_length);                                   \
    300   new_mem[copy_length] = '\0';                                                \
    301   return new_mem;
    302 #endif
    303 
    304 struct FileMetadata {
    305   // For open_memstream().
    306   char **addr;
    307   SIZE_T *size;
    308 };
    309 
    310 struct CommonInterceptorMetadata {
    311   enum {
    312     CIMT_INVALID = 0,
    313     CIMT_FILE
    314   } type;
    315   union {
    316     FileMetadata file;
    317   };
    318 };
    319 
    320 typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
    321 
    322 static MetadataHashMap *interceptor_metadata_map;
    323 
    324 #if SI_POSIX
    325 UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
    326                                           const FileMetadata &file) {
    327   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
    328   CHECK(h.created());
    329   h->type = CommonInterceptorMetadata::CIMT_FILE;
    330   h->file = file;
    331 }
    332 
    333 UNUSED static const FileMetadata *GetInterceptorMetadata(
    334     __sanitizer_FILE *addr) {
    335   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
    336                             /* remove */ false,
    337                             /* create */ false);
    338   if (addr && h.exists()) {
    339     CHECK(!h.created());
    340     CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
    341     return &h->file;
    342   } else {
    343     return 0;
    344   }
    345 }
    346 
    347 UNUSED static void DeleteInterceptorMetadata(void *addr) {
    348   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
    349   CHECK(h.exists());
    350 }
    351 #endif  // SI_POSIX
    352 
    353 #if SANITIZER_INTERCEPT_STRLEN
    354 INTERCEPTOR(SIZE_T, strlen, const char *s) {
    355   // Sometimes strlen is called prior to InitializeCommonInterceptors,
    356   // in which case the REAL(strlen) typically used in
    357   // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
    358   // to handle that.
    359   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    360     return internal_strlen(s);
    361   void *ctx;
    362   COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
    363   SIZE_T result = REAL(strlen)(s);
    364   if (common_flags()->intercept_strlen)
    365     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
    366   return result;
    367 }
    368 #define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
    369 #else
    370 #define INIT_STRLEN
    371 #endif
    372 
    373 #if SANITIZER_INTERCEPT_STRNLEN
    374 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
    375   void *ctx;
    376   COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
    377   SIZE_T length = REAL(strnlen)(s, maxlen);
    378   if (common_flags()->intercept_strlen)
    379     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
    380   return length;
    381 }
    382 #define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
    383 #else
    384 #define INIT_STRNLEN
    385 #endif
    386 
    387 #if SANITIZER_INTERCEPT_STRNDUP
    388 INTERCEPTOR(char*, strndup, const char *s, uptr size) {
    389   void *ctx;
    390   COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
    391 }
    392 #define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
    393 #else
    394 #define INIT_STRNDUP
    395 #endif // SANITIZER_INTERCEPT_STRNDUP
    396 
    397 #if SANITIZER_INTERCEPT___STRNDUP
    398 INTERCEPTOR(char*, __strndup, const char *s, uptr size) {
    399   void *ctx;
    400   COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
    401 }
    402 #define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
    403 #else
    404 #define INIT___STRNDUP
    405 #endif // SANITIZER_INTERCEPT___STRNDUP
    406 
    407 #if SANITIZER_INTERCEPT_TEXTDOMAIN
    408 INTERCEPTOR(char*, textdomain, const char *domainname) {
    409   void *ctx;
    410   COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
    411   if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
    412   char *domain = REAL(textdomain)(domainname);
    413   if (domain) {
    414     COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
    415   }
    416   return domain;
    417 }
    418 #define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
    419 #else
    420 #define INIT_TEXTDOMAIN
    421 #endif
    422 
    423 #if SANITIZER_INTERCEPT_STRCMP
    424 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
    425   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
    426 }
    427 
    428 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
    429                               const char *s1, const char *s2, int result)
    430 
    431 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
    432   void *ctx;
    433   COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
    434   unsigned char c1, c2;
    435   uptr i;
    436   for (i = 0;; i++) {
    437     c1 = (unsigned char)s1[i];
    438     c2 = (unsigned char)s2[i];
    439     if (c1 != c2 || c1 == '\0') break;
    440   }
    441   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
    442   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
    443   int result = CharCmpX(c1, c2);
    444   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
    445                              s2, result);
    446   return result;
    447 }
    448 
    449 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
    450                               const char *s1, const char *s2, uptr n,
    451                               int result)
    452 
    453 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
    454   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    455     return internal_strncmp(s1, s2, size);
    456   void *ctx;
    457   COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
    458   unsigned char c1 = 0, c2 = 0;
    459   uptr i;
    460   for (i = 0; i < size; i++) {
    461     c1 = (unsigned char)s1[i];
    462     c2 = (unsigned char)s2[i];
    463     if (c1 != c2 || c1 == '\0') break;
    464   }
    465   uptr i1 = i;
    466   uptr i2 = i;
    467   if (common_flags()->strict_string_checks) {
    468     for (; i1 < size && s1[i1]; i1++) {}
    469     for (; i2 < size && s2[i2]; i2++) {}
    470   }
    471   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
    472   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
    473   int result = CharCmpX(c1, c2);
    474   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
    475                              s2, size, result);
    476   return result;
    477 }
    478 
    479 #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
    480 #define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
    481 #else
    482 #define INIT_STRCMP
    483 #define INIT_STRNCMP
    484 #endif
    485 
    486 #if SANITIZER_INTERCEPT_STRCASECMP
    487 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
    488   int c1_low = ToLower(c1);
    489   int c2_low = ToLower(c2);
    490   return c1_low - c2_low;
    491 }
    492 
    493 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
    494                               const char *s1, const char *s2, int result)
    495 
    496 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
    497   void *ctx;
    498   COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
    499   unsigned char c1 = 0, c2 = 0;
    500   uptr i;
    501   for (i = 0;; i++) {
    502     c1 = (unsigned char)s1[i];
    503     c2 = (unsigned char)s2[i];
    504     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
    505   }
    506   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
    507   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
    508   int result = CharCaseCmp(c1, c2);
    509   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
    510                              s1, s2, result);
    511   return result;
    512 }
    513 
    514 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
    515                               const char *s1, const char *s2, uptr size,
    516                               int result)
    517 
    518 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) {
    519   void *ctx;
    520   COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);
    521   unsigned char c1 = 0, c2 = 0;
    522   uptr i;
    523   for (i = 0; i < size; i++) {
    524     c1 = (unsigned char)s1[i];
    525     c2 = (unsigned char)s2[i];
    526     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
    527   }
    528   uptr i1 = i;
    529   uptr i2 = i;
    530   if (common_flags()->strict_string_checks) {
    531     for (; i1 < size && s1[i1]; i1++) {}
    532     for (; i2 < size && s2[i2]; i2++) {}
    533   }
    534   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
    535   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
    536   int result = CharCaseCmp(c1, c2);
    537   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
    538                              s1, s2, size, result);
    539   return result;
    540 }
    541 
    542 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
    543 #define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
    544 #else
    545 #define INIT_STRCASECMP
    546 #define INIT_STRNCASECMP
    547 #endif
    548 
    549 #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
    550 static inline void StrstrCheck(void *ctx, char *r, const char *s1,
    551                                const char *s2) {
    552     uptr len1 = REAL(strlen)(s1);
    553     uptr len2 = REAL(strlen)(s2);
    554     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);
    555     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
    556 }
    557 #endif
    558 
    559 #if SANITIZER_INTERCEPT_STRSTR
    560 
    561 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
    562                               const char *s1, const char *s2, char *result)
    563 
    564 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
    565   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    566     return internal_strstr(s1, s2);
    567   void *ctx;
    568   COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
    569   char *r = REAL(strstr)(s1, s2);
    570   if (common_flags()->intercept_strstr)
    571     StrstrCheck(ctx, r, s1, s2);
    572   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
    573                              s2, r);
    574   return r;
    575 }
    576 
    577 #define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
    578 #else
    579 #define INIT_STRSTR
    580 #endif
    581 
    582 #if SANITIZER_INTERCEPT_STRCASESTR
    583 
    584 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
    585                               const char *s1, const char *s2, char *result)
    586 
    587 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
    588   void *ctx;
    589   COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
    590   char *r = REAL(strcasestr)(s1, s2);
    591   if (common_flags()->intercept_strstr)
    592     StrstrCheck(ctx, r, s1, s2);
    593   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
    594                              s1, s2, r);
    595   return r;
    596 }
    597 
    598 #define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
    599 #else
    600 #define INIT_STRCASESTR
    601 #endif
    602 
    603 #if SANITIZER_INTERCEPT_STRTOK
    604 
    605 INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {
    606   void *ctx;
    607   COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters);
    608   if (!common_flags()->intercept_strtok) {
    609     return REAL(strtok)(str, delimiters);
    610   }
    611   if (common_flags()->strict_string_checks) {
    612     // If strict_string_checks is enabled, we check the whole first argument
    613     // string on the first call (strtok saves this string in a static buffer
    614     // for subsequent calls). We do not need to check strtok's result.
    615     // As the delimiters can change, we check them every call.
    616     if (str != nullptr) {
    617       COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
    618     }
    619     COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters,
    620                                   REAL(strlen)(delimiters) + 1);
    621     return REAL(strtok)(str, delimiters);
    622   } else {
    623     // However, when strict_string_checks is disabled we cannot check the
    624     // whole string on the first call. Instead, we check the result string
    625     // which is guaranteed to be a NULL-terminated substring of the first
    626     // argument. We also conservatively check one character of str and the
    627     // delimiters.
    628     if (str != nullptr) {
    629       COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1);
    630     }
    631     COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1);
    632     char *result = REAL(strtok)(str, delimiters);
    633     if (result != nullptr) {
    634       COMMON_INTERCEPTOR_READ_RANGE(ctx, result, REAL(strlen)(result) + 1);
    635     } else if (str != nullptr) {
    636       // No delimiter were found, it's safe to assume that the entire str was
    637       // scanned.
    638       COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
    639     }
    640     return result;
    641   }
    642 }
    643 
    644 #define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok)
    645 #else
    646 #define INIT_STRTOK
    647 #endif
    648 
    649 #if SANITIZER_INTERCEPT_MEMMEM
    650 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
    651                               const void *s1, SIZE_T len1, const void *s2,
    652                               SIZE_T len2, void *result)
    653 
    654 INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
    655             SIZE_T len2) {
    656   void *ctx;
    657   COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
    658   void *r = REAL(memmem)(s1, len1, s2, len2);
    659   if (common_flags()->intercept_memmem) {
    660     COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
    661     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
    662   }
    663   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
    664                              s1, len1, s2, len2, r);
    665   return r;
    666 }
    667 
    668 #define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
    669 #else
    670 #define INIT_MEMMEM
    671 #endif  // SANITIZER_INTERCEPT_MEMMEM
    672 
    673 #if SANITIZER_INTERCEPT_STRCHR
    674 INTERCEPTOR(char*, strchr, const char *s, int c) {
    675   void *ctx;
    676   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    677     return internal_strchr(s, c);
    678   COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
    679   char *result = REAL(strchr)(s, c);
    680   if (common_flags()->intercept_strchr) {
    681     // Keep strlen as macro argument, as macro may ignore it.
    682     COMMON_INTERCEPTOR_READ_STRING(ctx, s,
    683       (result ? result - s : REAL(strlen)(s)) + 1);
    684   }
    685   return result;
    686 }
    687 #define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
    688 #else
    689 #define INIT_STRCHR
    690 #endif
    691 
    692 #if SANITIZER_INTERCEPT_STRCHRNUL
    693 INTERCEPTOR(char*, strchrnul, const char *s, int c) {
    694   void *ctx;
    695   COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
    696   char *result = REAL(strchrnul)(s, c);
    697   uptr len = result - s + 1;
    698   if (common_flags()->intercept_strchr)
    699     COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
    700   return result;
    701 }
    702 #define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
    703 #else
    704 #define INIT_STRCHRNUL
    705 #endif
    706 
    707 #if SANITIZER_INTERCEPT_STRRCHR
    708 INTERCEPTOR(char*, strrchr, const char *s, int c) {
    709   void *ctx;
    710   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    711     return internal_strrchr(s, c);
    712   COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
    713   if (common_flags()->intercept_strchr)
    714     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
    715   return REAL(strrchr)(s, c);
    716 }
    717 #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
    718 #else
    719 #define INIT_STRRCHR
    720 #endif
    721 
    722 #if SANITIZER_INTERCEPT_STRSPN
    723 INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
    724   void *ctx;
    725   COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
    726   SIZE_T r = REAL(strspn)(s1, s2);
    727   if (common_flags()->intercept_strspn) {
    728     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
    729     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
    730   }
    731   return r;
    732 }
    733 
    734 INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
    735   void *ctx;
    736   COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
    737   SIZE_T r = REAL(strcspn)(s1, s2);
    738   if (common_flags()->intercept_strspn) {
    739     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
    740     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
    741   }
    742   return r;
    743 }
    744 
    745 #define INIT_STRSPN \
    746   COMMON_INTERCEPT_FUNCTION(strspn); \
    747   COMMON_INTERCEPT_FUNCTION(strcspn);
    748 #else
    749 #define INIT_STRSPN
    750 #endif
    751 
    752 #if SANITIZER_INTERCEPT_STRPBRK
    753 INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
    754   void *ctx;
    755   COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
    756   char *r = REAL(strpbrk)(s1, s2);
    757   if (common_flags()->intercept_strpbrk) {
    758     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
    759     COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
    760         r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
    761   }
    762   return r;
    763 }
    764 
    765 #define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
    766 #else
    767 #define INIT_STRPBRK
    768 #endif
    769 
    770 #if SANITIZER_INTERCEPT_MEMSET
    771 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
    772   void *ctx;
    773   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size);
    774 }
    775 
    776 #define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
    777 #else
    778 #define INIT_MEMSET
    779 #endif
    780 
    781 #if SANITIZER_INTERCEPT_MEMMOVE
    782 INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {
    783   void *ctx;
    784   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
    785 }
    786 
    787 #define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
    788 #else
    789 #define INIT_MEMMOVE
    790 #endif
    791 
    792 #if SANITIZER_INTERCEPT_MEMCPY
    793 INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
    794   // On OS X, calling internal_memcpy here will cause memory corruptions,
    795   // because memcpy and memmove are actually aliases of the same
    796   // implementation.  We need to use internal_memmove here.
    797   // N.B.: If we switch this to internal_ we'll have to use internal_memmove
    798   // due to memcpy being an alias of memmove on OS X.
    799   void *ctx;
    800   if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
    801     COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
    802   } else {
    803     COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
    804   }
    805 }
    806 
    807 #define INIT_MEMCPY                                  \
    808   do {                                               \
    809     if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \
    810       COMMON_INTERCEPT_FUNCTION(memcpy);             \
    811     } else {                                         \
    812       ASSIGN_REAL(memcpy, memmove);                  \
    813     }                                                \
    814     CHECK(REAL(memcpy));                             \
    815   } while (false)
    816 
    817 #else
    818 #define INIT_MEMCPY
    819 #endif
    820 
    821 #if SANITIZER_INTERCEPT_MEMCMP
    822 
    823 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
    824                               const void *s1, const void *s2, uptr n,
    825                               int result)
    826 
    827 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
    828   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    829     return internal_memcmp(a1, a2, size);
    830   void *ctx;
    831   COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
    832   if (common_flags()->intercept_memcmp) {
    833     if (common_flags()->strict_memcmp) {
    834       // Check the entire regions even if the first bytes of the buffers are
    835       // different.
    836       COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
    837       COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
    838       // Fallthrough to REAL(memcmp) below.
    839     } else {
    840       unsigned char c1 = 0, c2 = 0;
    841       const unsigned char *s1 = (const unsigned char*)a1;
    842       const unsigned char *s2 = (const unsigned char*)a2;
    843       uptr i;
    844       for (i = 0; i < size; i++) {
    845         c1 = s1[i];
    846         c2 = s2[i];
    847         if (c1 != c2) break;
    848       }
    849       COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
    850       COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
    851       int r = CharCmpX(c1, c2);
    852       CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
    853                                  a1, a2, size, r);
    854       return r;
    855     }
    856   }
    857   int result = REAL(memcmp(a1, a2, size));
    858   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
    859                              a2, size, result);
    860   return result;
    861 }
    862 
    863 #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
    864 #else
    865 #define INIT_MEMCMP
    866 #endif
    867 
    868 #if SANITIZER_INTERCEPT_MEMCHR
    869 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
    870   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    871     return internal_memchr(s, c, n);
    872   void *ctx;
    873   COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
    874 #if SANITIZER_WINDOWS
    875   void *res;
    876   if (REAL(memchr)) {
    877     res = REAL(memchr)(s, c, n);
    878   } else {
    879     res = internal_memchr(s, c, n);
    880   }
    881 #else
    882   void *res = REAL(memchr)(s, c, n);
    883 #endif
    884   uptr len = res ? (char *)res - (const char *)s + 1 : n;
    885   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
    886   return res;
    887 }
    888 
    889 #define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
    890 #else
    891 #define INIT_MEMCHR
    892 #endif
    893 
    894 #if SANITIZER_INTERCEPT_MEMRCHR
    895 INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
    896   void *ctx;
    897   COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
    898   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
    899   return REAL(memrchr)(s, c, n);
    900 }
    901 
    902 #define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
    903 #else
    904 #define INIT_MEMRCHR
    905 #endif
    906 
    907 #if SANITIZER_INTERCEPT_FREXP
    908 INTERCEPTOR(double, frexp, double x, int *exp) {
    909   void *ctx;
    910   COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
    911   // Assuming frexp() always writes to |exp|.
    912   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
    913   double res = REAL(frexp)(x, exp);
    914   return res;
    915 }
    916 
    917 #define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
    918 #else
    919 #define INIT_FREXP
    920 #endif  // SANITIZER_INTERCEPT_FREXP
    921 
    922 #if SANITIZER_INTERCEPT_FREXPF_FREXPL
    923 INTERCEPTOR(float, frexpf, float x, int *exp) {
    924   void *ctx;
    925   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
    926   // FIXME: under ASan the call below may write to freed memory and corrupt
    927   // its metadata. See
    928   // https://github.com/google/sanitizers/issues/321.
    929   float res = REAL(frexpf)(x, exp);
    930   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
    931   return res;
    932 }
    933 
    934 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
    935   void *ctx;
    936   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
    937   // FIXME: under ASan the call below may write to freed memory and corrupt
    938   // its metadata. See
    939   // https://github.com/google/sanitizers/issues/321.
    940   long double res = REAL(frexpl)(x, exp);
    941   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
    942   return res;
    943 }
    944 
    945 #define INIT_FREXPF_FREXPL           \
    946   COMMON_INTERCEPT_FUNCTION(frexpf); \
    947   COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
    948 #else
    949 #define INIT_FREXPF_FREXPL
    950 #endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
    951 
    952 #if SI_POSIX
    953 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
    954                         SIZE_T iovlen, SIZE_T maxlen) {
    955   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
    956     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
    957     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
    958     maxlen -= sz;
    959   }
    960 }
    961 
    962 static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
    963                        SIZE_T iovlen, SIZE_T maxlen) {
    964   COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
    965   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
    966     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
    967     COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
    968     maxlen -= sz;
    969   }
    970 }
    971 #endif
    972 
    973 #if SANITIZER_INTERCEPT_READ
    974 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
    975   void *ctx;
    976   COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
    977   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    978   // FIXME: under ASan the call below may write to freed memory and corrupt
    979   // its metadata. See
    980   // https://github.com/google/sanitizers/issues/321.
    981   SSIZE_T res = REAL(read)(fd, ptr, count);
    982   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
    983   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    984   return res;
    985 }
    986 #define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
    987 #else
    988 #define INIT_READ
    989 #endif
    990 
    991 #if SANITIZER_INTERCEPT_FREAD
    992 INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
    993   // libc file streams can call user-supplied functions, see fopencookie.
    994   void *ctx;
    995   COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);
    996   // FIXME: under ASan the call below may write to freed memory and corrupt
    997   // its metadata. See
    998   // https://github.com/google/sanitizers/issues/321.
    999   SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
   1000   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);
   1001   return res;
   1002 }
   1003 #define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)
   1004 #else
   1005 #define INIT_FREAD
   1006 #endif
   1007 
   1008 #if SANITIZER_INTERCEPT_PREAD
   1009 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
   1010   void *ctx;
   1011   COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
   1012   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1013   // FIXME: under ASan the call below may write to freed memory and corrupt
   1014   // its metadata. See
   1015   // https://github.com/google/sanitizers/issues/321.
   1016   SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
   1017   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
   1018   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   1019   return res;
   1020 }
   1021 #define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
   1022 #else
   1023 #define INIT_PREAD
   1024 #endif
   1025 
   1026 #if SANITIZER_INTERCEPT_PREAD64
   1027 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
   1028   void *ctx;
   1029   COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
   1030   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1031   // FIXME: under ASan the call below may write to freed memory and corrupt
   1032   // its metadata. See
   1033   // https://github.com/google/sanitizers/issues/321.
   1034   SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
   1035   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
   1036   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   1037   return res;
   1038 }
   1039 #define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
   1040 #else
   1041 #define INIT_PREAD64
   1042 #endif
   1043 
   1044 #if SANITIZER_INTERCEPT_READV
   1045 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
   1046                         int iovcnt) {
   1047   void *ctx;
   1048   COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
   1049   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1050   SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
   1051   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
   1052   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   1053   return res;
   1054 }
   1055 #define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
   1056 #else
   1057 #define INIT_READV
   1058 #endif
   1059 
   1060 #if SANITIZER_INTERCEPT_PREADV
   1061 INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
   1062             OFF_T offset) {
   1063   void *ctx;
   1064   COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
   1065   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1066   SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
   1067   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
   1068   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   1069   return res;
   1070 }
   1071 #define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
   1072 #else
   1073 #define INIT_PREADV
   1074 #endif
   1075 
   1076 #if SANITIZER_INTERCEPT_PREADV64
   1077 INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
   1078             OFF64_T offset) {
   1079   void *ctx;
   1080   COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
   1081   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1082   SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
   1083   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
   1084   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   1085   return res;
   1086 }
   1087 #define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
   1088 #else
   1089 #define INIT_PREADV64
   1090 #endif
   1091 
   1092 #if SANITIZER_INTERCEPT_WRITE
   1093 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
   1094   void *ctx;
   1095   COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
   1096   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1097   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   1098   SSIZE_T res = REAL(write)(fd, ptr, count);
   1099   // FIXME: this check should be _before_ the call to REAL(write), not after
   1100   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
   1101   return res;
   1102 }
   1103 #define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
   1104 #else
   1105 #define INIT_WRITE
   1106 #endif
   1107 
   1108 #if SANITIZER_INTERCEPT_FWRITE
   1109 INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) {
   1110   // libc file streams can call user-supplied functions, see fopencookie.
   1111   void *ctx;
   1112   COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);
   1113   SIZE_T res = REAL(fwrite)(p, size, nmemb, file);
   1114   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);
   1115   return res;
   1116 }
   1117 #define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)
   1118 #else
   1119 #define INIT_FWRITE
   1120 #endif
   1121 
   1122 #if SANITIZER_INTERCEPT_PWRITE
   1123 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
   1124   void *ctx;
   1125   COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
   1126   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1127   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   1128   SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
   1129   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
   1130   return res;
   1131 }
   1132 #define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
   1133 #else
   1134 #define INIT_PWRITE
   1135 #endif
   1136 
   1137 #if SANITIZER_INTERCEPT_PWRITE64
   1138 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
   1139             OFF64_T offset) {
   1140   void *ctx;
   1141   COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
   1142   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1143   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   1144   SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
   1145   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
   1146   return res;
   1147 }
   1148 #define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
   1149 #else
   1150 #define INIT_PWRITE64
   1151 #endif
   1152 
   1153 #if SANITIZER_INTERCEPT_WRITEV
   1154 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
   1155                         int iovcnt) {
   1156   void *ctx;
   1157   COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
   1158   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1159   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   1160   SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
   1161   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
   1162   return res;
   1163 }
   1164 #define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
   1165 #else
   1166 #define INIT_WRITEV
   1167 #endif
   1168 
   1169 #if SANITIZER_INTERCEPT_PWRITEV
   1170 INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
   1171             OFF_T offset) {
   1172   void *ctx;
   1173   COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
   1174   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1175   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   1176   SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
   1177   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
   1178   return res;
   1179 }
   1180 #define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
   1181 #else
   1182 #define INIT_PWRITEV
   1183 #endif
   1184 
   1185 #if SANITIZER_INTERCEPT_PWRITEV64
   1186 INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
   1187             OFF64_T offset) {
   1188   void *ctx;
   1189   COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
   1190   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   1191   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   1192   SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
   1193   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
   1194   return res;
   1195 }
   1196 #define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
   1197 #else
   1198 #define INIT_PWRITEV64
   1199 #endif
   1200 
   1201 #if SANITIZER_INTERCEPT_FGETS
   1202 INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) {
   1203   // libc file streams can call user-supplied functions, see fopencookie.
   1204   void *ctx;
   1205   COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file);
   1206   // FIXME: under ASan the call below may write to freed memory and corrupt
   1207   // its metadata. See
   1208   // https://github.com/google/sanitizers/issues/321.
   1209   char *res = REAL(fgets)(s, size, file);
   1210   if (res)
   1211     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
   1212   return res;
   1213 }
   1214 #define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets)
   1215 #else
   1216 #define INIT_FGETS
   1217 #endif
   1218 
   1219 #if SANITIZER_INTERCEPT_FPUTS
   1220 INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {
   1221   // libc file streams can call user-supplied functions, see fopencookie.
   1222   void *ctx;
   1223   COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);
   1224   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
   1225   return REAL(fputs)(s, file);
   1226 }
   1227 #define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)
   1228 #else
   1229 #define INIT_FPUTS
   1230 #endif
   1231 
   1232 #if SANITIZER_INTERCEPT_PUTS
   1233 INTERCEPTOR(int, puts, char *s) {
   1234   // libc file streams can call user-supplied functions, see fopencookie.
   1235   void *ctx;
   1236   COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
   1237   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
   1238   return REAL(puts)(s);
   1239 }
   1240 #define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)
   1241 #else
   1242 #define INIT_PUTS
   1243 #endif
   1244 
   1245 #if SANITIZER_INTERCEPT_PRCTL
   1246 INTERCEPTOR(int, prctl, int option, unsigned long arg2,
   1247             unsigned long arg3,                        // NOLINT
   1248             unsigned long arg4, unsigned long arg5) {  // NOLINT
   1249   void *ctx;
   1250   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
   1251   static const int PR_SET_NAME = 15;
   1252   int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
   1253   if (option == PR_SET_NAME) {
   1254     char buff[16];
   1255     internal_strncpy(buff, (char *)arg2, 15);
   1256     buff[15] = 0;
   1257     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
   1258   }
   1259   return res;
   1260 }
   1261 #define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
   1262 #else
   1263 #define INIT_PRCTL
   1264 #endif  // SANITIZER_INTERCEPT_PRCTL
   1265 
   1266 #if SANITIZER_INTERCEPT_TIME
   1267 INTERCEPTOR(unsigned long, time, unsigned long *t) {
   1268   void *ctx;
   1269   COMMON_INTERCEPTOR_ENTER(ctx, time, t);
   1270   unsigned long local_t;
   1271   unsigned long res = REAL(time)(&local_t);
   1272   if (t && res != (unsigned long)-1) {
   1273     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
   1274     *t = local_t;
   1275   }
   1276   return res;
   1277 }
   1278 #define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
   1279 #else
   1280 #define INIT_TIME
   1281 #endif  // SANITIZER_INTERCEPT_TIME
   1282 
   1283 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
   1284 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
   1285   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
   1286 #if !SANITIZER_SOLARIS
   1287   if (tm->tm_zone) {
   1288     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
   1289     // can point to shared memory and tsan would report a data race.
   1290     COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
   1291                                         REAL(strlen(tm->tm_zone)) + 1);
   1292   }
   1293 #endif
   1294 }
   1295 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
   1296   void *ctx;
   1297   COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
   1298   __sanitizer_tm *res = REAL(localtime)(timep);
   1299   if (res) {
   1300     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1301     unpoison_tm(ctx, res);
   1302   }
   1303   return res;
   1304 }
   1305 INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
   1306   void *ctx;
   1307   COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
   1308   __sanitizer_tm *res = REAL(localtime_r)(timep, result);
   1309   if (res) {
   1310     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1311     unpoison_tm(ctx, res);
   1312   }
   1313   return res;
   1314 }
   1315 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
   1316   void *ctx;
   1317   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
   1318   __sanitizer_tm *res = REAL(gmtime)(timep);
   1319   if (res) {
   1320     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1321     unpoison_tm(ctx, res);
   1322   }
   1323   return res;
   1324 }
   1325 INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
   1326   void *ctx;
   1327   COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
   1328   __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
   1329   if (res) {
   1330     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1331     unpoison_tm(ctx, res);
   1332   }
   1333   return res;
   1334 }
   1335 INTERCEPTOR(char *, ctime, unsigned long *timep) {
   1336   void *ctx;
   1337   COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
   1338   // FIXME: under ASan the call below may write to freed memory and corrupt
   1339   // its metadata. See
   1340   // https://github.com/google/sanitizers/issues/321.
   1341   char *res = REAL(ctime)(timep);
   1342   if (res) {
   1343     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1344     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1345   }
   1346   return res;
   1347 }
   1348 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
   1349   void *ctx;
   1350   COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
   1351   // FIXME: under ASan the call below may write to freed memory and corrupt
   1352   // its metadata. See
   1353   // https://github.com/google/sanitizers/issues/321.
   1354   char *res = REAL(ctime_r)(timep, result);
   1355   if (res) {
   1356     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1357     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1358   }
   1359   return res;
   1360 }
   1361 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
   1362   void *ctx;
   1363   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
   1364   // FIXME: under ASan the call below may write to freed memory and corrupt
   1365   // its metadata. See
   1366   // https://github.com/google/sanitizers/issues/321.
   1367   char *res = REAL(asctime)(tm);
   1368   if (res) {
   1369     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
   1370     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1371   }
   1372   return res;
   1373 }
   1374 INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
   1375   void *ctx;
   1376   COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
   1377   // FIXME: under ASan the call below may write to freed memory and corrupt
   1378   // its metadata. See
   1379   // https://github.com/google/sanitizers/issues/321.
   1380   char *res = REAL(asctime_r)(tm, result);
   1381   if (res) {
   1382     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
   1383     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1384   }
   1385   return res;
   1386 }
   1387 INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
   1388   void *ctx;
   1389   COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
   1390   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
   1391   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
   1392   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
   1393   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
   1394   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
   1395   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
   1396   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
   1397   long res = REAL(mktime)(tm);
   1398   if (res != -1) unpoison_tm(ctx, tm);
   1399   return res;
   1400 }
   1401 #define INIT_LOCALTIME_AND_FRIENDS        \
   1402   COMMON_INTERCEPT_FUNCTION(localtime);   \
   1403   COMMON_INTERCEPT_FUNCTION(localtime_r); \
   1404   COMMON_INTERCEPT_FUNCTION(gmtime);      \
   1405   COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
   1406   COMMON_INTERCEPT_FUNCTION(ctime);       \
   1407   COMMON_INTERCEPT_FUNCTION(ctime_r);     \
   1408   COMMON_INTERCEPT_FUNCTION(asctime);     \
   1409   COMMON_INTERCEPT_FUNCTION(asctime_r);   \
   1410   COMMON_INTERCEPT_FUNCTION(mktime);
   1411 #else
   1412 #define INIT_LOCALTIME_AND_FRIENDS
   1413 #endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
   1414 
   1415 #if SANITIZER_INTERCEPT_STRPTIME
   1416 INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
   1417   void *ctx;
   1418   COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
   1419   if (format)
   1420     COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
   1421   // FIXME: under ASan the call below may write to freed memory and corrupt
   1422   // its metadata. See
   1423   // https://github.com/google/sanitizers/issues/321.
   1424   char *res = REAL(strptime)(s, format, tm);
   1425   COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
   1426   if (res && tm) {
   1427     // Do not call unpoison_tm here, because strptime does not, in fact,
   1428     // initialize the entire struct tm. For example, tm_zone pointer is left
   1429     // uninitialized.
   1430     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
   1431   }
   1432   return res;
   1433 }
   1434 #define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
   1435 #else
   1436 #define INIT_STRPTIME
   1437 #endif
   1438 
   1439 #if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
   1440 #include "sanitizer_common_interceptors_format.inc"
   1441 
   1442 #define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
   1443   {                                                                            \
   1444     void *ctx;                                                                 \
   1445     va_list ap;                                                                \
   1446     va_start(ap, format);                                                      \
   1447     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
   1448     int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
   1449     va_end(ap);                                                                \
   1450     return res;                                                                \
   1451   }
   1452 
   1453 #endif
   1454 
   1455 #if SANITIZER_INTERCEPT_SCANF
   1456 
   1457 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
   1458   {                                                                            \
   1459     void *ctx;                                                                 \
   1460     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
   1461     va_list aq;                                                                \
   1462     va_copy(aq, ap);                                                           \
   1463     int res = REAL(vname)(__VA_ARGS__);                                        \
   1464     if (res > 0)                                                               \
   1465       scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
   1466     va_end(aq);                                                                \
   1467     return res;                                                                \
   1468   }
   1469 
   1470 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
   1471 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
   1472 
   1473 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
   1474 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
   1475 
   1476 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
   1477 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
   1478 
   1479 #if SANITIZER_INTERCEPT_ISOC99_SCANF
   1480 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
   1481 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
   1482 
   1483 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
   1484             va_list ap)
   1485 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
   1486 
   1487 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
   1488 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
   1489 #endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
   1490 
   1491 INTERCEPTOR(int, scanf, const char *format, ...)
   1492 FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
   1493 
   1494 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
   1495 FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
   1496 
   1497 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
   1498 FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
   1499 
   1500 #if SANITIZER_INTERCEPT_ISOC99_SCANF
   1501 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
   1502 FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
   1503 
   1504 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
   1505 FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
   1506 
   1507 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
   1508 FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
   1509 #endif
   1510 
   1511 #endif
   1512 
   1513 #if SANITIZER_INTERCEPT_SCANF
   1514 #define INIT_SCANF                    \
   1515   COMMON_INTERCEPT_FUNCTION_LDBL(scanf);   \
   1516   COMMON_INTERCEPT_FUNCTION_LDBL(sscanf);  \
   1517   COMMON_INTERCEPT_FUNCTION_LDBL(fscanf);  \
   1518   COMMON_INTERCEPT_FUNCTION_LDBL(vscanf);  \
   1519   COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \
   1520   COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);
   1521 #else
   1522 #define INIT_SCANF
   1523 #endif
   1524 
   1525 #if SANITIZER_INTERCEPT_ISOC99_SCANF
   1526 #define INIT_ISOC99_SCANF                      \
   1527   COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
   1528   COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
   1529   COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
   1530   COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
   1531   COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
   1532   COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
   1533 #else
   1534 #define INIT_ISOC99_SCANF
   1535 #endif
   1536 
   1537 #if SANITIZER_INTERCEPT_PRINTF
   1538 
   1539 #define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
   1540   void *ctx;                                                                   \
   1541   COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
   1542   va_list aq;                                                                  \
   1543   va_copy(aq, ap);
   1544 
   1545 #define VPRINTF_INTERCEPTOR_RETURN()                                           \
   1546   va_end(aq);
   1547 
   1548 #define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
   1549   {                                                                            \
   1550     VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
   1551     if (common_flags()->check_printf)                                          \
   1552       printf_common(ctx, format, aq);                                          \
   1553     int res = REAL(vname)(__VA_ARGS__);                                        \
   1554     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1555     return res;                                                                \
   1556   }
   1557 
   1558 // FIXME: under ASan the REAL() call below may write to freed memory and
   1559 // corrupt its metadata. See
   1560 // https://github.com/google/sanitizers/issues/321.
   1561 #define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
   1562   {                                                                            \
   1563     VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
   1564     if (common_flags()->check_printf) {                                        \
   1565       printf_common(ctx, format, aq);                                          \
   1566     }                                                                          \
   1567     int res = REAL(vname)(str, __VA_ARGS__);                                   \
   1568     if (res >= 0) {                                                            \
   1569       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
   1570     }                                                                          \
   1571     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1572     return res;                                                                \
   1573   }
   1574 
   1575 // FIXME: under ASan the REAL() call below may write to freed memory and
   1576 // corrupt its metadata. See
   1577 // https://github.com/google/sanitizers/issues/321.
   1578 #define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
   1579   {                                                                            \
   1580     VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
   1581     if (common_flags()->check_printf) {                                        \
   1582       printf_common(ctx, format, aq);                                          \
   1583     }                                                                          \
   1584     int res = REAL(vname)(str, size, __VA_ARGS__);                             \
   1585     if (res >= 0) {                                                            \
   1586       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
   1587     }                                                                          \
   1588     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1589     return res;                                                                \
   1590   }
   1591 
   1592 // FIXME: under ASan the REAL() call below may write to freed memory and
   1593 // corrupt its metadata. See
   1594 // https://github.com/google/sanitizers/issues/321.
   1595 #define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
   1596   {                                                                            \
   1597     VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
   1598     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
   1599     if (common_flags()->check_printf) {                                        \
   1600       printf_common(ctx, format, aq);                                          \
   1601     }                                                                          \
   1602     int res = REAL(vname)(strp, __VA_ARGS__);                                  \
   1603     if (res >= 0) {                                                            \
   1604       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
   1605     }                                                                          \
   1606     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1607     return res;                                                                \
   1608   }
   1609 
   1610 INTERCEPTOR(int, vprintf, const char *format, va_list ap)
   1611 VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
   1612 
   1613 INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
   1614             va_list ap)
   1615 VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
   1616 
   1617 INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
   1618             va_list ap)
   1619 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
   1620 
   1621 #if SANITIZER_INTERCEPT___PRINTF_CHK
   1622 INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,
   1623             SIZE_T size_to, const char *format, va_list ap)
   1624 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
   1625 #endif
   1626 
   1627 #if SANITIZER_INTERCEPT_PRINTF_L
   1628 INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
   1629             const char *format, va_list ap)
   1630 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
   1631 
   1632 INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
   1633             const char *format, ...)
   1634 FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
   1635 #endif  // SANITIZER_INTERCEPT_PRINTF_L
   1636 
   1637 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
   1638 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
   1639 
   1640 #if SANITIZER_INTERCEPT___PRINTF_CHK
   1641 INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
   1642             const char *format, va_list ap)
   1643 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
   1644 #endif
   1645 
   1646 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
   1647 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
   1648 
   1649 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
   1650 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
   1651 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
   1652 
   1653 INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
   1654             const char *format, va_list ap)
   1655 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
   1656 
   1657 INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
   1658             va_list ap)
   1659 VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
   1660 
   1661 INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
   1662             va_list ap)
   1663 VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
   1664                           ap)
   1665 
   1666 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
   1667 
   1668 INTERCEPTOR(int, printf, const char *format, ...)
   1669 FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
   1670 
   1671 INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
   1672 FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
   1673 
   1674 #if SANITIZER_INTERCEPT___PRINTF_CHK
   1675 INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,
   1676             const char *format, ...)
   1677 FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)
   1678 #endif
   1679 
   1680 INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
   1681 FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
   1682 
   1683 #if SANITIZER_INTERCEPT___PRINTF_CHK
   1684 INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,
   1685             const char *format, ...) // NOLINT
   1686 FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT
   1687 #endif
   1688 
   1689 INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
   1690 FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
   1691 
   1692 #if SANITIZER_INTERCEPT___PRINTF_CHK
   1693 INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
   1694             SIZE_T size_to, const char *format, ...) // NOLINT
   1695 FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT
   1696 #endif
   1697 
   1698 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
   1699 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
   1700 
   1701 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
   1702 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
   1703 FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
   1704 
   1705 INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
   1706             ...)
   1707 FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
   1708 
   1709 INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
   1710 FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
   1711 
   1712 INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
   1713             const char *format, ...)
   1714 FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
   1715                         format)
   1716 
   1717 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
   1718 
   1719 #endif  // SANITIZER_INTERCEPT_PRINTF
   1720 
   1721 #if SANITIZER_INTERCEPT_PRINTF
   1722 #define INIT_PRINTF                     \
   1723   COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
   1724   COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
   1725   COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
   1726   COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
   1727   COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
   1728   COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
   1729   COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
   1730   COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
   1731   COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
   1732   COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
   1733 #else
   1734 #define INIT_PRINTF
   1735 #endif
   1736 
   1737 #if SANITIZER_INTERCEPT___PRINTF_CHK
   1738 #define INIT___PRINTF_CHK                     \
   1739   COMMON_INTERCEPT_FUNCTION(__sprintf_chk);   \
   1740   COMMON_INTERCEPT_FUNCTION(__snprintf_chk);  \
   1741   COMMON_INTERCEPT_FUNCTION(__vsprintf_chk);  \
   1742   COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \
   1743   COMMON_INTERCEPT_FUNCTION(__fprintf_chk);
   1744 #else
   1745 #define INIT___PRINTF_CHK
   1746 #endif
   1747 
   1748 #if SANITIZER_INTERCEPT_PRINTF_L
   1749 #define INIT_PRINTF_L                     \
   1750   COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
   1751   COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
   1752 #else
   1753 #define INIT_PRINTF_L
   1754 #endif
   1755 
   1756 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
   1757 #define INIT_ISOC99_PRINTF                       \
   1758   COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
   1759   COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
   1760   COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
   1761   COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
   1762   COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
   1763   COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
   1764   COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
   1765   COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
   1766 #else
   1767 #define INIT_ISOC99_PRINTF
   1768 #endif
   1769 
   1770 #if SANITIZER_INTERCEPT_IOCTL
   1771 #include "sanitizer_common_interceptors_ioctl.inc"
   1772 #include "sanitizer_interceptors_ioctl_netbsd.inc"
   1773 INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
   1774   // We need a frame pointer, because we call into ioctl_common_[pre|post] which
   1775   // can trigger a report and we need to be able to unwind through this
   1776   // function.  On Mac in debug mode we might not have a frame pointer, because
   1777   // ioctl_common_[pre|post] doesn't get inlined here.
   1778   ENABLE_FRAME_POINTER;
   1779 
   1780   void *ctx;
   1781   va_list ap;
   1782   va_start(ap, request);
   1783   void *arg = va_arg(ap, void *);
   1784   va_end(ap);
   1785   COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
   1786 
   1787   CHECK(ioctl_initialized);
   1788 
   1789   // Note: TSan does not use common flags, and they are zero-initialized.
   1790   // This effectively disables ioctl handling in TSan.
   1791   if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
   1792 
   1793   // Although request is unsigned long, the rest of the interceptor uses it
   1794   // as just "unsigned" to save space, because we know that all values fit in
   1795   // "unsigned" - they are compile-time constants.
   1796 
   1797   const ioctl_desc *desc = ioctl_lookup(request);
   1798   ioctl_desc decoded_desc;
   1799   if (!desc) {
   1800     VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
   1801     if (!ioctl_decode(request, &decoded_desc))
   1802       Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
   1803     else
   1804       desc = &decoded_desc;
   1805   }
   1806 
   1807   if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
   1808   int res = REAL(ioctl)(d, request, arg);
   1809   // FIXME: some ioctls have different return values for success and failure.
   1810   if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
   1811   return res;
   1812 }
   1813 #define INIT_IOCTL \
   1814   ioctl_init();    \
   1815   COMMON_INTERCEPT_FUNCTION(ioctl);
   1816 #else
   1817 #define INIT_IOCTL
   1818 #endif
   1819 
   1820 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
   1821     SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
   1822     SANITIZER_INTERCEPT_GETPWENT_R || \
   1823     SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS || \
   1824     SANITIZER_INTERCEPT_FGETPWENT_R || \
   1825     SANITIZER_INTERCEPT_FGETGRENT_R
   1826 static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
   1827   if (pwd) {
   1828     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
   1829     if (pwd->pw_name)
   1830       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
   1831                                           REAL(strlen)(pwd->pw_name) + 1);
   1832     if (pwd->pw_passwd)
   1833       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
   1834                                           REAL(strlen)(pwd->pw_passwd) + 1);
   1835 #if !SANITIZER_ANDROID
   1836     if (pwd->pw_gecos)
   1837       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
   1838                                           REAL(strlen)(pwd->pw_gecos) + 1);
   1839 #endif
   1840 #if SANITIZER_MAC
   1841     if (pwd->pw_class)
   1842       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
   1843                                           REAL(strlen)(pwd->pw_class) + 1);
   1844 #endif
   1845     if (pwd->pw_dir)
   1846       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
   1847                                           REAL(strlen)(pwd->pw_dir) + 1);
   1848     if (pwd->pw_shell)
   1849       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
   1850                                           REAL(strlen)(pwd->pw_shell) + 1);
   1851   }
   1852 }
   1853 
   1854 static void unpoison_group(void *ctx, __sanitizer_group *grp) {
   1855   if (grp) {
   1856     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
   1857     if (grp->gr_name)
   1858       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
   1859                                           REAL(strlen)(grp->gr_name) + 1);
   1860     if (grp->gr_passwd)
   1861       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
   1862                                           REAL(strlen)(grp->gr_passwd) + 1);
   1863     char **p = grp->gr_mem;
   1864     for (; *p; ++p) {
   1865       COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
   1866     }
   1867     COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
   1868                                         (p - grp->gr_mem + 1) * sizeof(*p));
   1869   }
   1870 }
   1871 #endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
   1872         // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
   1873         // SANITIZER_INTERCEPT_GETPWENT_R ||
   1874         // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
   1875 
   1876 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
   1877 INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
   1878   void *ctx;
   1879   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
   1880   if (name)
   1881     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1882   __sanitizer_passwd *res = REAL(getpwnam)(name);
   1883   if (res) unpoison_passwd(ctx, res);
   1884   return res;
   1885 }
   1886 INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
   1887   void *ctx;
   1888   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
   1889   __sanitizer_passwd *res = REAL(getpwuid)(uid);
   1890   if (res) unpoison_passwd(ctx, res);
   1891   return res;
   1892 }
   1893 INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
   1894   void *ctx;
   1895   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
   1896   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1897   __sanitizer_group *res = REAL(getgrnam)(name);
   1898   if (res) unpoison_group(ctx, res);
   1899   return res;
   1900 }
   1901 INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
   1902   void *ctx;
   1903   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
   1904   __sanitizer_group *res = REAL(getgrgid)(gid);
   1905   if (res) unpoison_group(ctx, res);
   1906   return res;
   1907 }
   1908 #define INIT_GETPWNAM_AND_FRIENDS      \
   1909   COMMON_INTERCEPT_FUNCTION(getpwnam); \
   1910   COMMON_INTERCEPT_FUNCTION(getpwuid); \
   1911   COMMON_INTERCEPT_FUNCTION(getgrnam); \
   1912   COMMON_INTERCEPT_FUNCTION(getgrgid);
   1913 #else
   1914 #define INIT_GETPWNAM_AND_FRIENDS
   1915 #endif
   1916 
   1917 #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
   1918 INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
   1919             char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
   1920   void *ctx;
   1921   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
   1922   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1923   // FIXME: under ASan the call below may write to freed memory and corrupt
   1924   // its metadata. See
   1925   // https://github.com/google/sanitizers/issues/321.
   1926   int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
   1927   if (!res) {
   1928     if (result && *result) unpoison_passwd(ctx, *result);
   1929     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1930   }
   1931   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1932   return res;
   1933 }
   1934 INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
   1935             SIZE_T buflen, __sanitizer_passwd **result) {
   1936   void *ctx;
   1937   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
   1938   // FIXME: under ASan the call below may write to freed memory and corrupt
   1939   // its metadata. See
   1940   // https://github.com/google/sanitizers/issues/321.
   1941   int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
   1942   if (!res) {
   1943     if (result && *result) unpoison_passwd(ctx, *result);
   1944     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1945   }
   1946   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1947   return res;
   1948 }
   1949 INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
   1950             char *buf, SIZE_T buflen, __sanitizer_group **result) {
   1951   void *ctx;
   1952   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
   1953   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1954   // FIXME: under ASan the call below may write to freed memory and corrupt
   1955   // its metadata. See
   1956   // https://github.com/google/sanitizers/issues/321.
   1957   int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
   1958   if (!res) {
   1959     if (result && *result) unpoison_group(ctx, *result);
   1960     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1961   }
   1962   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1963   return res;
   1964 }
   1965 INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
   1966             SIZE_T buflen, __sanitizer_group **result) {
   1967   void *ctx;
   1968   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
   1969   // FIXME: under ASan the call below may write to freed memory and corrupt
   1970   // its metadata. See
   1971   // https://github.com/google/sanitizers/issues/321.
   1972   int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
   1973   if (!res) {
   1974     if (result && *result) unpoison_group(ctx, *result);
   1975     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1976   }
   1977   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1978   return res;
   1979 }
   1980 #define INIT_GETPWNAM_R_AND_FRIENDS      \
   1981   COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
   1982   COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
   1983   COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
   1984   COMMON_INTERCEPT_FUNCTION(getgrgid_r);
   1985 #else
   1986 #define INIT_GETPWNAM_R_AND_FRIENDS
   1987 #endif
   1988 
   1989 #if SANITIZER_INTERCEPT_GETPWENT
   1990 INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
   1991   void *ctx;
   1992   COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
   1993   __sanitizer_passwd *res = REAL(getpwent)(dummy);
   1994   if (res) unpoison_passwd(ctx, res);
   1995   return res;
   1996 }
   1997 INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
   1998   void *ctx;
   1999   COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
   2000   __sanitizer_group *res = REAL(getgrent)(dummy);
   2001   if (res) unpoison_group(ctx, res);;
   2002   return res;
   2003 }
   2004 #define INIT_GETPWENT                  \
   2005   COMMON_INTERCEPT_FUNCTION(getpwent); \
   2006   COMMON_INTERCEPT_FUNCTION(getgrent);
   2007 #else
   2008 #define INIT_GETPWENT
   2009 #endif
   2010 
   2011 #if SANITIZER_INTERCEPT_FGETPWENT
   2012 INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
   2013   void *ctx;
   2014   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
   2015   __sanitizer_passwd *res = REAL(fgetpwent)(fp);
   2016   if (res) unpoison_passwd(ctx, res);
   2017   return res;
   2018 }
   2019 INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
   2020   void *ctx;
   2021   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
   2022   __sanitizer_group *res = REAL(fgetgrent)(fp);
   2023   if (res) unpoison_group(ctx, res);
   2024   return res;
   2025 }
   2026 #define INIT_FGETPWENT                  \
   2027   COMMON_INTERCEPT_FUNCTION(fgetpwent); \
   2028   COMMON_INTERCEPT_FUNCTION(fgetgrent);
   2029 #else
   2030 #define INIT_FGETPWENT
   2031 #endif
   2032 
   2033 #if SANITIZER_INTERCEPT_GETPWENT_R
   2034 INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
   2035             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
   2036   void *ctx;
   2037   COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
   2038   // FIXME: under ASan the call below may write to freed memory and corrupt
   2039   // its metadata. See
   2040   // https://github.com/google/sanitizers/issues/321.
   2041   int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
   2042   if (!res) {
   2043     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
   2044     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   2045   }
   2046   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   2047   return res;
   2048 }
   2049 INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
   2050             __sanitizer_group **pwbufp) {
   2051   void *ctx;
   2052   COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
   2053   // FIXME: under ASan the call below may write to freed memory and corrupt
   2054   // its metadata. See
   2055   // https://github.com/google/sanitizers/issues/321.
   2056   int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
   2057   if (!res) {
   2058     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
   2059     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   2060   }
   2061   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   2062   return res;
   2063 }
   2064 #define INIT_GETPWENT_R                   \
   2065   COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
   2066   COMMON_INTERCEPT_FUNCTION(getgrent_r);
   2067 #else
   2068 #define INIT_GETPWENT_R
   2069 #endif
   2070 
   2071 #if SANITIZER_INTERCEPT_FGETPWENT_R
   2072 INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
   2073             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
   2074   void *ctx;
   2075   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
   2076   // FIXME: under ASan the call below may write to freed memory and corrupt
   2077   // its metadata. See
   2078   // https://github.com/google/sanitizers/issues/321.
   2079   int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
   2080   if (!res) {
   2081     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
   2082     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   2083   }
   2084   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   2085   return res;
   2086 }
   2087 #define INIT_FGETPWENT_R                  \
   2088   COMMON_INTERCEPT_FUNCTION(fgetpwent_r);
   2089 #else
   2090 #define INIT_FGETPWENT_R
   2091 #endif
   2092 
   2093 #if SANITIZER_INTERCEPT_FGETGRENT_R
   2094 INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
   2095             SIZE_T buflen, __sanitizer_group **pwbufp) {
   2096   void *ctx;
   2097   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
   2098   // FIXME: under ASan the call below may write to freed memory and corrupt
   2099   // its metadata. See
   2100   // https://github.com/google/sanitizers/issues/321.
   2101   int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
   2102   if (!res) {
   2103     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
   2104     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   2105   }
   2106   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   2107   return res;
   2108 }
   2109 #define INIT_FGETGRENT_R                  \
   2110   COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
   2111 #else
   2112 #define INIT_FGETGRENT_R
   2113 #endif
   2114 
   2115 #if SANITIZER_INTERCEPT_SETPWENT
   2116 // The only thing these interceptors do is disable any nested interceptors.
   2117 // These functions may open nss modules and call uninstrumented functions from
   2118 // them, and we don't want things like strlen() to trigger.
   2119 INTERCEPTOR(void, setpwent, int dummy) {
   2120   void *ctx;
   2121   COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
   2122   REAL(setpwent)(dummy);
   2123 }
   2124 INTERCEPTOR(void, endpwent, int dummy) {
   2125   void *ctx;
   2126   COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
   2127   REAL(endpwent)(dummy);
   2128 }
   2129 INTERCEPTOR(void, setgrent, int dummy) {
   2130   void *ctx;
   2131   COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
   2132   REAL(setgrent)(dummy);
   2133 }
   2134 INTERCEPTOR(void, endgrent, int dummy) {
   2135   void *ctx;
   2136   COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
   2137   REAL(endgrent)(dummy);
   2138 }
   2139 #define INIT_SETPWENT                  \
   2140   COMMON_INTERCEPT_FUNCTION(setpwent); \
   2141   COMMON_INTERCEPT_FUNCTION(endpwent); \
   2142   COMMON_INTERCEPT_FUNCTION(setgrent); \
   2143   COMMON_INTERCEPT_FUNCTION(endgrent);
   2144 #else
   2145 #define INIT_SETPWENT
   2146 #endif
   2147 
   2148 #if SANITIZER_INTERCEPT_CLOCK_GETTIME
   2149 INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
   2150   void *ctx;
   2151   COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
   2152   // FIXME: under ASan the call below may write to freed memory and corrupt
   2153   // its metadata. See
   2154   // https://github.com/google/sanitizers/issues/321.
   2155   int res = REAL(clock_getres)(clk_id, tp);
   2156   if (!res && tp) {
   2157     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
   2158   }
   2159   return res;
   2160 }
   2161 INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
   2162   void *ctx;
   2163   COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
   2164   // FIXME: under ASan the call below may write to freed memory and corrupt
   2165   // its metadata. See
   2166   // https://github.com/google/sanitizers/issues/321.
   2167   int res = REAL(clock_gettime)(clk_id, tp);
   2168   if (!res) {
   2169     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
   2170   }
   2171   return res;
   2172 }
   2173 namespace __sanitizer {
   2174 extern "C" {
   2175 int real_clock_gettime(u32 clk_id, void *tp) {
   2176   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
   2177     return internal_clock_gettime(clk_id, tp);
   2178   return REAL(clock_gettime)(clk_id, tp);
   2179 }
   2180 }  // extern "C"
   2181 }  // namespace __sanitizer
   2182 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
   2183   void *ctx;
   2184   COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
   2185   COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
   2186   return REAL(clock_settime)(clk_id, tp);
   2187 }
   2188 #define INIT_CLOCK_GETTIME                  \
   2189   COMMON_INTERCEPT_FUNCTION(clock_getres);  \
   2190   COMMON_INTERCEPT_FUNCTION(clock_gettime); \
   2191   COMMON_INTERCEPT_FUNCTION(clock_settime);
   2192 #else
   2193 #define INIT_CLOCK_GETTIME
   2194 #endif
   2195 
   2196 #if SANITIZER_INTERCEPT_GETITIMER
   2197 INTERCEPTOR(int, getitimer, int which, void *curr_value) {
   2198   void *ctx;
   2199   COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
   2200   // FIXME: under ASan the call below may write to freed memory and corrupt
   2201   // its metadata. See
   2202   // https://github.com/google/sanitizers/issues/321.
   2203   int res = REAL(getitimer)(which, curr_value);
   2204   if (!res && curr_value) {
   2205     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
   2206   }
   2207   return res;
   2208 }
   2209 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
   2210   void *ctx;
   2211   COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
   2212   if (new_value) {
   2213     // itimerval can contain padding that may be legitimately uninitialized
   2214     const struct __sanitizer_itimerval *nv =
   2215         (const struct __sanitizer_itimerval *)new_value;
   2216     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,
   2217                                   sizeof(__sanitizer_time_t));
   2218     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,
   2219                                   sizeof(__sanitizer_suseconds_t));
   2220     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,
   2221                                   sizeof(__sanitizer_time_t));
   2222     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,
   2223                                   sizeof(__sanitizer_suseconds_t));
   2224   }
   2225   // FIXME: under ASan the call below may write to freed memory and corrupt
   2226   // its metadata. See
   2227   // https://github.com/google/sanitizers/issues/321.
   2228   int res = REAL(setitimer)(which, new_value, old_value);
   2229   if (!res && old_value) {
   2230     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
   2231   }
   2232   return res;
   2233 }
   2234 #define INIT_GETITIMER                  \
   2235   COMMON_INTERCEPT_FUNCTION(getitimer); \
   2236   COMMON_INTERCEPT_FUNCTION(setitimer);
   2237 #else
   2238 #define INIT_GETITIMER
   2239 #endif
   2240 
   2241 #if SANITIZER_INTERCEPT_GLOB
   2242 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
   2243   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
   2244   // +1 for NULL pointer at the end.
   2245   if (pglob->gl_pathv)
   2246     COMMON_INTERCEPTOR_WRITE_RANGE(
   2247         ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
   2248   for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
   2249     char *p = pglob->gl_pathv[i];
   2250     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
   2251   }
   2252 }
   2253 
   2254 #if SANITIZER_SOLARIS
   2255 INTERCEPTOR(int, glob, const char *pattern, int flags,
   2256             int (*errfunc)(const char *epath, int eerrno),
   2257             __sanitizer_glob_t *pglob) {
   2258   void *ctx;
   2259   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
   2260   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
   2261   int res = REAL(glob)(pattern, flags, errfunc, pglob);
   2262   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   2263   return res;
   2264 }
   2265 #else
   2266 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
   2267 
   2268 static void wrapped_gl_closedir(void *dir) {
   2269   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   2270   pglob_copy->gl_closedir(dir);
   2271 }
   2272 
   2273 static void *wrapped_gl_readdir(void *dir) {
   2274   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   2275   return pglob_copy->gl_readdir(dir);
   2276 }
   2277 
   2278 static void *wrapped_gl_opendir(const char *s) {
   2279   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   2280   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
   2281   return pglob_copy->gl_opendir(s);
   2282 }
   2283 
   2284 static int wrapped_gl_lstat(const char *s, void *st) {
   2285   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   2286   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
   2287   return pglob_copy->gl_lstat(s, st);
   2288 }
   2289 
   2290 static int wrapped_gl_stat(const char *s, void *st) {
   2291   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   2292   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
   2293   return pglob_copy->gl_stat(s, st);
   2294 }
   2295 
   2296 static const __sanitizer_glob_t kGlobCopy = {
   2297       0,                  0,                   0,
   2298       0,                  wrapped_gl_closedir, wrapped_gl_readdir,
   2299       wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
   2300 
   2301 INTERCEPTOR(int, glob, const char *pattern, int flags,
   2302             int (*errfunc)(const char *epath, int eerrno),
   2303             __sanitizer_glob_t *pglob) {
   2304   void *ctx;
   2305   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
   2306   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
   2307   __sanitizer_glob_t glob_copy;
   2308   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
   2309   if (flags & glob_altdirfunc) {
   2310     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   2311     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   2312     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   2313     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   2314     Swap(pglob->gl_stat, glob_copy.gl_stat);
   2315     pglob_copy = &glob_copy;
   2316   }
   2317   int res = REAL(glob)(pattern, flags, errfunc, pglob);
   2318   if (flags & glob_altdirfunc) {
   2319     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   2320     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   2321     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   2322     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   2323     Swap(pglob->gl_stat, glob_copy.gl_stat);
   2324   }
   2325   pglob_copy = 0;
   2326   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   2327   return res;
   2328 }
   2329 #endif  // SANITIZER_SOLARIS
   2330 #define INIT_GLOB                  \
   2331   COMMON_INTERCEPT_FUNCTION(glob);
   2332 #else  // SANITIZER_INTERCEPT_GLOB
   2333 #define INIT_GLOB
   2334 #endif  // SANITIZER_INTERCEPT_GLOB
   2335 
   2336 #if SANITIZER_INTERCEPT_GLOB64
   2337 INTERCEPTOR(int, glob64, const char *pattern, int flags,
   2338             int (*errfunc)(const char *epath, int eerrno),
   2339             __sanitizer_glob_t *pglob) {
   2340   void *ctx;
   2341   COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
   2342   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
   2343   __sanitizer_glob_t glob_copy;
   2344   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
   2345   if (flags & glob_altdirfunc) {
   2346     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   2347     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   2348     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   2349     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   2350     Swap(pglob->gl_stat, glob_copy.gl_stat);
   2351     pglob_copy = &glob_copy;
   2352   }
   2353   int res = REAL(glob64)(pattern, flags, errfunc, pglob);
   2354   if (flags & glob_altdirfunc) {
   2355     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   2356     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   2357     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   2358     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   2359     Swap(pglob->gl_stat, glob_copy.gl_stat);
   2360   }
   2361   pglob_copy = 0;
   2362   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   2363   return res;
   2364 }
   2365 #define INIT_GLOB64                \
   2366   COMMON_INTERCEPT_FUNCTION(glob64);
   2367 #else  // SANITIZER_INTERCEPT_GLOB64
   2368 #define INIT_GLOB64
   2369 #endif  // SANITIZER_INTERCEPT_GLOB64
   2370 
   2371 #if SANITIZER_INTERCEPT_WAIT
   2372 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
   2373 // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
   2374 // details.
   2375 INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
   2376   void *ctx;
   2377   COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
   2378   // FIXME: under ASan the call below may write to freed memory and corrupt
   2379   // its metadata. See
   2380   // https://github.com/google/sanitizers/issues/321.
   2381   int res = REAL(wait)(status);
   2382   if (res != -1 && status)
   2383     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   2384   return res;
   2385 }
   2386 // On FreeBSD id_t is always 64-bit wide.
   2387 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
   2388 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
   2389                         int options) {
   2390 #else
   2391 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
   2392                         int options) {
   2393 #endif
   2394   void *ctx;
   2395   COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
   2396   // FIXME: under ASan the call below may write to freed memory and corrupt
   2397   // its metadata. See
   2398   // https://github.com/google/sanitizers/issues/321.
   2399   int res = REAL(waitid)(idtype, id, infop, options);
   2400   if (res != -1 && infop)
   2401     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
   2402   return res;
   2403 }
   2404 INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
   2405   void *ctx;
   2406   COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
   2407   // FIXME: under ASan the call below may write to freed memory and corrupt
   2408   // its metadata. See
   2409   // https://github.com/google/sanitizers/issues/321.
   2410   int res = REAL(waitpid)(pid, status, options);
   2411   if (res != -1 && status)
   2412     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   2413   return res;
   2414 }
   2415 INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
   2416   void *ctx;
   2417   COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
   2418   // FIXME: under ASan the call below may write to freed memory and corrupt
   2419   // its metadata. See
   2420   // https://github.com/google/sanitizers/issues/321.
   2421   int res = REAL(wait3)(status, options, rusage);
   2422   if (res != -1) {
   2423     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   2424     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
   2425   }
   2426   return res;
   2427 }
   2428 #if SANITIZER_ANDROID
   2429 INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
   2430   void *ctx;
   2431   COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
   2432   // FIXME: under ASan the call below may write to freed memory and corrupt
   2433   // its metadata. See
   2434   // https://github.com/google/sanitizers/issues/321.
   2435   int res = REAL(__wait4)(pid, status, options, rusage);
   2436   if (res != -1) {
   2437     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   2438     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
   2439   }
   2440   return res;
   2441 }
   2442 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
   2443 #else
   2444 INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
   2445   void *ctx;
   2446   COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
   2447   // FIXME: under ASan the call below may write to freed memory and corrupt
   2448   // its metadata. See
   2449   // https://github.com/google/sanitizers/issues/321.
   2450   int res = REAL(wait4)(pid, status, options, rusage);
   2451   if (res != -1) {
   2452     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   2453     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
   2454   }
   2455   return res;
   2456 }
   2457 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
   2458 #endif  // SANITIZER_ANDROID
   2459 #define INIT_WAIT                     \
   2460   COMMON_INTERCEPT_FUNCTION(wait);    \
   2461   COMMON_INTERCEPT_FUNCTION(waitid);  \
   2462   COMMON_INTERCEPT_FUNCTION(waitpid); \
   2463   COMMON_INTERCEPT_FUNCTION(wait3);
   2464 #else
   2465 #define INIT_WAIT
   2466 #define INIT_WAIT4
   2467 #endif
   2468 
   2469 #if SANITIZER_INTERCEPT_INET
   2470 INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
   2471   void *ctx;
   2472   COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
   2473   uptr sz = __sanitizer_in_addr_sz(af);
   2474   if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
   2475   // FIXME: figure out read size based on the address family.
   2476   // FIXME: under ASan the call below may write to freed memory and corrupt
   2477   // its metadata. See
   2478   // https://github.com/google/sanitizers/issues/321.
   2479   char *res = REAL(inet_ntop)(af, src, dst, size);
   2480   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   2481   return res;
   2482 }
   2483 INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
   2484   void *ctx;
   2485   COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
   2486   COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
   2487   // FIXME: figure out read size based on the address family.
   2488   // FIXME: under ASan the call below may write to freed memory and corrupt
   2489   // its metadata. See
   2490   // https://github.com/google/sanitizers/issues/321.
   2491   int res = REAL(inet_pton)(af, src, dst);
   2492   if (res == 1) {
   2493     uptr sz = __sanitizer_in_addr_sz(af);
   2494     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
   2495   }
   2496   return res;
   2497 }
   2498 #define INIT_INET                       \
   2499   COMMON_INTERCEPT_FUNCTION(inet_ntop); \
   2500   COMMON_INTERCEPT_FUNCTION(inet_pton);
   2501 #else
   2502 #define INIT_INET
   2503 #endif
   2504 
   2505 #if SANITIZER_INTERCEPT_INET
   2506 INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
   2507   void *ctx;
   2508   COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
   2509   if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
   2510   // FIXME: under ASan the call below may write to freed memory and corrupt
   2511   // its metadata. See
   2512   // https://github.com/google/sanitizers/issues/321.
   2513   int res = REAL(inet_aton)(cp, dst);
   2514   if (res != 0) {
   2515     uptr sz = __sanitizer_in_addr_sz(af_inet);
   2516     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
   2517   }
   2518   return res;
   2519 }
   2520 #define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
   2521 #else
   2522 #define INIT_INET_ATON
   2523 #endif
   2524 
   2525 #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
   2526 INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
   2527   void *ctx;
   2528   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
   2529   // FIXME: under ASan the call below may write to freed memory and corrupt
   2530   // its metadata. See
   2531   // https://github.com/google/sanitizers/issues/321.
   2532   int res = REAL(pthread_getschedparam)(thread, policy, param);
   2533   if (res == 0) {
   2534     if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
   2535     if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
   2536   }
   2537   return res;
   2538 }
   2539 #define INIT_PTHREAD_GETSCHEDPARAM \
   2540   COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
   2541 #else
   2542 #define INIT_PTHREAD_GETSCHEDPARAM
   2543 #endif
   2544 
   2545 #if SANITIZER_INTERCEPT_GETADDRINFO
   2546 INTERCEPTOR(int, getaddrinfo, char *node, char *service,
   2547             struct __sanitizer_addrinfo *hints,
   2548             struct __sanitizer_addrinfo **out) {
   2549   void *ctx;
   2550   COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
   2551   if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
   2552   if (service)
   2553     COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
   2554   if (hints)
   2555     COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
   2556   // FIXME: under ASan the call below may write to freed memory and corrupt
   2557   // its metadata. See
   2558   // https://github.com/google/sanitizers/issues/321.
   2559   int res = REAL(getaddrinfo)(node, service, hints, out);
   2560   if (res == 0 && out) {
   2561     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
   2562     struct __sanitizer_addrinfo *p = *out;
   2563     while (p) {
   2564       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   2565       if (p->ai_addr)
   2566         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
   2567       if (p->ai_canonname)
   2568         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
   2569                                        REAL(strlen)(p->ai_canonname) + 1);
   2570       p = p->ai_next;
   2571     }
   2572   }
   2573   return res;
   2574 }
   2575 #define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
   2576 #else
   2577 #define INIT_GETADDRINFO
   2578 #endif
   2579 
   2580 #if SANITIZER_INTERCEPT_GETNAMEINFO
   2581 INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
   2582             unsigned hostlen, char *serv, unsigned servlen, int flags) {
   2583   void *ctx;
   2584   COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
   2585                            serv, servlen, flags);
   2586   // FIXME: consider adding READ_RANGE(sockaddr, salen)
   2587   // There is padding in in_addr that may make this too noisy
   2588   // FIXME: under ASan the call below may write to freed memory and corrupt
   2589   // its metadata. See
   2590   // https://github.com/google/sanitizers/issues/321.
   2591   int res =
   2592       REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
   2593   if (res == 0) {
   2594     if (host && hostlen)
   2595       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
   2596     if (serv && servlen)
   2597       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
   2598   }
   2599   return res;
   2600 }
   2601 #define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
   2602 #else
   2603 #define INIT_GETNAMEINFO
   2604 #endif
   2605 
   2606 #if SANITIZER_INTERCEPT_GETSOCKNAME
   2607 INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
   2608   void *ctx;
   2609   COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
   2610   COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2611   int addrlen_in = *addrlen;
   2612   // FIXME: under ASan the call below may write to freed memory and corrupt
   2613   // its metadata. See
   2614   // https://github.com/google/sanitizers/issues/321.
   2615   int res = REAL(getsockname)(sock_fd, addr, addrlen);
   2616   if (res == 0) {
   2617     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
   2618   }
   2619   return res;
   2620 }
   2621 #define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
   2622 #else
   2623 #define INIT_GETSOCKNAME
   2624 #endif
   2625 
   2626 #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
   2627 static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
   2628   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
   2629   if (h->h_name)
   2630     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
   2631   char **p = h->h_aliases;
   2632   while (*p) {
   2633     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
   2634     ++p;
   2635   }
   2636   COMMON_INTERCEPTOR_WRITE_RANGE(
   2637       ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
   2638   p = h->h_addr_list;
   2639   while (*p) {
   2640     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
   2641     ++p;
   2642   }
   2643   COMMON_INTERCEPTOR_WRITE_RANGE(
   2644       ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
   2645 }
   2646 #endif
   2647 
   2648 #if SANITIZER_INTERCEPT_GETHOSTBYNAME
   2649 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
   2650   void *ctx;
   2651   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
   2652   struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
   2653   if (res) write_hostent(ctx, res);
   2654   return res;
   2655 }
   2656 
   2657 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
   2658             int type) {
   2659   void *ctx;
   2660   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
   2661   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
   2662   struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
   2663   if (res) write_hostent(ctx, res);
   2664   return res;
   2665 }
   2666 
   2667 INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
   2668   void *ctx;
   2669   COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
   2670   struct __sanitizer_hostent *res = REAL(gethostent)(fake);
   2671   if (res) write_hostent(ctx, res);
   2672   return res;
   2673 }
   2674 #define INIT_GETHOSTBYNAME                  \
   2675   COMMON_INTERCEPT_FUNCTION(gethostent);    \
   2676   COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
   2677   COMMON_INTERCEPT_FUNCTION(gethostbyname);
   2678 #else
   2679 #define INIT_GETHOSTBYNAME
   2680 #endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME
   2681 
   2682 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2
   2683 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
   2684   void *ctx;
   2685   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
   2686   struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
   2687   if (res) write_hostent(ctx, res);
   2688   return res;
   2689 }
   2690 #define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
   2691 #else
   2692 #define INIT_GETHOSTBYNAME2
   2693 #endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME2
   2694 
   2695 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
   2696 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
   2697             char *buf, SIZE_T buflen, __sanitizer_hostent **result,
   2698             int *h_errnop) {
   2699   void *ctx;
   2700   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
   2701                            h_errnop);
   2702   // FIXME: under ASan the call below may write to freed memory and corrupt
   2703   // its metadata. See
   2704   // https://github.com/google/sanitizers/issues/321.
   2705   int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
   2706   if (result) {
   2707     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2708     if (res == 0 && *result) write_hostent(ctx, *result);
   2709   }
   2710   if (h_errnop)
   2711     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2712   return res;
   2713 }
   2714 #define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
   2715 #else
   2716 #define INIT_GETHOSTBYNAME_R
   2717 #endif
   2718 
   2719 #if SANITIZER_INTERCEPT_GETHOSTENT_R
   2720 INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
   2721             SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
   2722   void *ctx;
   2723   COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
   2724                            h_errnop);
   2725   // FIXME: under ASan the call below may write to freed memory and corrupt
   2726   // its metadata. See
   2727   // https://github.com/google/sanitizers/issues/321.
   2728   int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
   2729   if (result) {
   2730     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2731     if (res == 0 && *result) write_hostent(ctx, *result);
   2732   }
   2733   if (h_errnop)
   2734     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2735   return res;
   2736 }
   2737 #define INIT_GETHOSTENT_R                  \
   2738   COMMON_INTERCEPT_FUNCTION(gethostent_r);
   2739 #else
   2740 #define INIT_GETHOSTENT_R
   2741 #endif
   2742 
   2743 #if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
   2744 INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
   2745             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
   2746             __sanitizer_hostent **result, int *h_errnop) {
   2747   void *ctx;
   2748   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
   2749                            buflen, result, h_errnop);
   2750   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
   2751   // FIXME: under ASan the call below may write to freed memory and corrupt
   2752   // its metadata. See
   2753   // https://github.com/google/sanitizers/issues/321.
   2754   int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
   2755                                   h_errnop);
   2756   if (result) {
   2757     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2758     if (res == 0 && *result) write_hostent(ctx, *result);
   2759   }
   2760   if (h_errnop)
   2761     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2762   return res;
   2763 }
   2764 #define INIT_GETHOSTBYADDR_R                  \
   2765   COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
   2766 #else
   2767 #define INIT_GETHOSTBYADDR_R
   2768 #endif
   2769 
   2770 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
   2771 INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
   2772             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
   2773             __sanitizer_hostent **result, int *h_errnop) {
   2774   void *ctx;
   2775   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
   2776                            result, h_errnop);
   2777   // FIXME: under ASan the call below may write to freed memory and corrupt
   2778   // its metadata. See
   2779   // https://github.com/google/sanitizers/issues/321.
   2780   int res =
   2781       REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
   2782   if (result) {
   2783     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2784     if (res == 0 && *result) write_hostent(ctx, *result);
   2785   }
   2786   if (h_errnop)
   2787     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2788   return res;
   2789 }
   2790 #define INIT_GETHOSTBYNAME2_R                  \
   2791   COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
   2792 #else
   2793 #define INIT_GETHOSTBYNAME2_R
   2794 #endif
   2795 
   2796 #if SANITIZER_INTERCEPT_GETSOCKOPT
   2797 INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
   2798             int *optlen) {
   2799   void *ctx;
   2800   COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
   2801                            optlen);
   2802   if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
   2803   // FIXME: under ASan the call below may write to freed memory and corrupt
   2804   // its metadata. See
   2805   // https://github.com/google/sanitizers/issues/321.
   2806   int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
   2807   if (res == 0)
   2808     if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
   2809   return res;
   2810 }
   2811 #define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
   2812 #else
   2813 #define INIT_GETSOCKOPT
   2814 #endif
   2815 
   2816 #if SANITIZER_INTERCEPT_ACCEPT
   2817 INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
   2818   void *ctx;
   2819   COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
   2820   unsigned addrlen0 = 0;
   2821   if (addrlen) {
   2822     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2823     addrlen0 = *addrlen;
   2824   }
   2825   int fd2 = REAL(accept)(fd, addr, addrlen);
   2826   if (fd2 >= 0) {
   2827     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
   2828     if (addr && addrlen)
   2829       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
   2830   }
   2831   return fd2;
   2832 }
   2833 #define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
   2834 #else
   2835 #define INIT_ACCEPT
   2836 #endif
   2837 
   2838 #if SANITIZER_INTERCEPT_ACCEPT4
   2839 INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
   2840   void *ctx;
   2841   COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
   2842   unsigned addrlen0 = 0;
   2843   if (addrlen) {
   2844     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2845     addrlen0 = *addrlen;
   2846   }
   2847   // FIXME: under ASan the call below may write to freed memory and corrupt
   2848   // its metadata. See
   2849   // https://github.com/google/sanitizers/issues/321.
   2850   int fd2 = REAL(accept4)(fd, addr, addrlen, f);
   2851   if (fd2 >= 0) {
   2852     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
   2853     if (addr && addrlen)
   2854       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
   2855   }
   2856   return fd2;
   2857 }
   2858 #define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
   2859 #else
   2860 #define INIT_ACCEPT4
   2861 #endif
   2862 
   2863 #if SANITIZER_INTERCEPT_PACCEPT
   2864 INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,
   2865             __sanitizer_sigset_t *set, int f) {
   2866   void *ctx;
   2867   COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);
   2868   unsigned addrlen0 = 0;
   2869   if (addrlen) {
   2870     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2871     addrlen0 = *addrlen;
   2872   }
   2873   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
   2874   int fd2 = REAL(paccept)(fd, addr, addrlen, set, f);
   2875   if (fd2 >= 0) {
   2876     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
   2877     if (addr && addrlen)
   2878       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
   2879   }
   2880   return fd2;
   2881 }
   2882 #define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);
   2883 #else
   2884 #define INIT_PACCEPT
   2885 #endif
   2886 
   2887 #if SANITIZER_INTERCEPT_MODF
   2888 INTERCEPTOR(double, modf, double x, double *iptr) {
   2889   void *ctx;
   2890   COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
   2891   // FIXME: under ASan the call below may write to freed memory and corrupt
   2892   // its metadata. See
   2893   // https://github.com/google/sanitizers/issues/321.
   2894   double res = REAL(modf)(x, iptr);
   2895   if (iptr) {
   2896     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
   2897   }
   2898   return res;
   2899 }
   2900 INTERCEPTOR(float, modff, float x, float *iptr) {
   2901   void *ctx;
   2902   COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
   2903   // FIXME: under ASan the call below may write to freed memory and corrupt
   2904   // its metadata. See
   2905   // https://github.com/google/sanitizers/issues/321.
   2906   float res = REAL(modff)(x, iptr);
   2907   if (iptr) {
   2908     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
   2909   }
   2910   return res;
   2911 }
   2912 INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
   2913   void *ctx;
   2914   COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
   2915   // FIXME: under ASan the call below may write to freed memory and corrupt
   2916   // its metadata. See
   2917   // https://github.com/google/sanitizers/issues/321.
   2918   long double res = REAL(modfl)(x, iptr);
   2919   if (iptr) {
   2920     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
   2921   }
   2922   return res;
   2923 }
   2924 #define INIT_MODF                   \
   2925   COMMON_INTERCEPT_FUNCTION(modf);  \
   2926   COMMON_INTERCEPT_FUNCTION(modff); \
   2927   COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
   2928 #else
   2929 #define INIT_MODF
   2930 #endif
   2931 
   2932 #if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG
   2933 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
   2934                          SSIZE_T maxlen) {
   2935   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
   2936   if (msg->msg_name && msg->msg_namelen)
   2937     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
   2938   if (msg->msg_iov && msg->msg_iovlen)
   2939     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
   2940                                    sizeof(*msg->msg_iov) * msg->msg_iovlen);
   2941   write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
   2942   if (msg->msg_control && msg->msg_controllen)
   2943     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
   2944 }
   2945 #endif
   2946 
   2947 #if SANITIZER_INTERCEPT_RECVMSG
   2948 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
   2949             int flags) {
   2950   void *ctx;
   2951   COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
   2952   // FIXME: under ASan the call below may write to freed memory and corrupt
   2953   // its metadata. See
   2954   // https://github.com/google/sanitizers/issues/321.
   2955   SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
   2956   if (res >= 0) {
   2957     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   2958     if (msg) {
   2959       write_msghdr(ctx, msg, res);
   2960       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
   2961     }
   2962   }
   2963   return res;
   2964 }
   2965 #define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
   2966 #else
   2967 #define INIT_RECVMSG
   2968 #endif
   2969 
   2970 #if SANITIZER_INTERCEPT_RECVMMSG
   2971 INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
   2972             unsigned int vlen, int flags, void *timeout) {
   2973   void *ctx;
   2974   COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);
   2975   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
   2976   int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);
   2977   if (res >= 0) {
   2978     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   2979     for (int i = 0; i < res; ++i) {
   2980       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
   2981                                      sizeof(msgvec[i].msg_len));
   2982       write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
   2983       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);
   2984     }
   2985   }
   2986   return res;
   2987 }
   2988 #define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);
   2989 #else
   2990 #define INIT_RECVMMSG
   2991 #endif
   2992 
   2993 #if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG
   2994 static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
   2995   const unsigned kCmsgDataOffset =
   2996       RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
   2997 
   2998   char *p = (char *)control;
   2999   char *const control_end = p + controllen;
   3000   while (true) {
   3001     if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
   3002     __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
   3003     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
   3004 
   3005     if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
   3006 
   3007     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
   3008                                   sizeof(cmsg->cmsg_level));
   3009     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
   3010                                   sizeof(cmsg->cmsg_type));
   3011 
   3012     if (cmsg->cmsg_len > kCmsgDataOffset) {
   3013       char *data = p + kCmsgDataOffset;
   3014       unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
   3015       if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
   3016     }
   3017 
   3018     p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
   3019   }
   3020 }
   3021 
   3022 static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
   3023                         SSIZE_T maxlen) {
   3024 #define R(f) \
   3025   COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
   3026   R(name);
   3027   R(namelen);
   3028   R(iov);
   3029   R(iovlen);
   3030   R(control);
   3031   R(controllen);
   3032   R(flags);
   3033 #undef R
   3034   if (msg->msg_name && msg->msg_namelen)
   3035     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
   3036   if (msg->msg_iov && msg->msg_iovlen)
   3037     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
   3038                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
   3039   read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
   3040   if (msg->msg_control && msg->msg_controllen)
   3041     read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
   3042 }
   3043 #endif
   3044 
   3045 #if SANITIZER_INTERCEPT_SENDMSG
   3046 INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
   3047             int flags) {
   3048   void *ctx;
   3049   COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
   3050   if (fd >= 0) {
   3051     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   3052     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   3053   }
   3054   SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
   3055   if (common_flags()->intercept_send && res >= 0 && msg)
   3056     read_msghdr(ctx, msg, res);
   3057   return res;
   3058 }
   3059 #define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
   3060 #else
   3061 #define INIT_SENDMSG
   3062 #endif
   3063 
   3064 #if SANITIZER_INTERCEPT_SENDMMSG
   3065 INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
   3066             unsigned vlen, int flags) {
   3067   void *ctx;
   3068   COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);
   3069   if (fd >= 0) {
   3070     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   3071     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   3072   }
   3073   int res = REAL(sendmmsg)(fd, msgvec, vlen, flags);
   3074   if (res >= 0 && msgvec)
   3075     for (int i = 0; i < res; ++i) {
   3076       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
   3077                                      sizeof(msgvec[i].msg_len));
   3078       if (common_flags()->intercept_send)
   3079         read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
   3080     }
   3081   return res;
   3082 }
   3083 #define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);
   3084 #else
   3085 #define INIT_SENDMMSG
   3086 #endif
   3087 
   3088 #if SANITIZER_INTERCEPT_GETPEERNAME
   3089 INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
   3090   void *ctx;
   3091   COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
   3092   unsigned addr_sz;
   3093   if (addrlen) addr_sz = *addrlen;
   3094   // FIXME: under ASan the call below may write to freed memory and corrupt
   3095   // its metadata. See
   3096   // https://github.com/google/sanitizers/issues/321.
   3097   int res = REAL(getpeername)(sockfd, addr, addrlen);
   3098   if (!res && addr && addrlen)
   3099     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
   3100   return res;
   3101 }
   3102 #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
   3103 #else
   3104 #define INIT_GETPEERNAME
   3105 #endif
   3106 
   3107 #if SANITIZER_INTERCEPT_SYSINFO
   3108 INTERCEPTOR(int, sysinfo, void *info) {
   3109   void *ctx;
   3110   // FIXME: under ASan the call below may write to freed memory and corrupt
   3111   // its metadata. See
   3112   // https://github.com/google/sanitizers/issues/321.
   3113   COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
   3114   int res = REAL(sysinfo)(info);
   3115   if (!res && info)
   3116     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
   3117   return res;
   3118 }
   3119 #define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
   3120 #else
   3121 #define INIT_SYSINFO
   3122 #endif
   3123 
   3124 #if SANITIZER_INTERCEPT_READDIR
   3125 INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
   3126   void *ctx;
   3127   COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
   3128   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3129   __sanitizer_dirent *res = REAL(opendir)(path);
   3130   if (res)
   3131     COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
   3132   return res;
   3133 }
   3134 
   3135 INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
   3136   void *ctx;
   3137   COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
   3138   // FIXME: under ASan the call below may write to freed memory and corrupt
   3139   // its metadata. See
   3140   // https://github.com/google/sanitizers/issues/321.
   3141   __sanitizer_dirent *res = REAL(readdir)(dirp);
   3142   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
   3143   return res;
   3144 }
   3145 
   3146 INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
   3147             __sanitizer_dirent **result) {
   3148   void *ctx;
   3149   COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
   3150   // FIXME: under ASan the call below may write to freed memory and corrupt
   3151   // its metadata. See
   3152   // https://github.com/google/sanitizers/issues/321.
   3153   int res = REAL(readdir_r)(dirp, entry, result);
   3154   if (!res) {
   3155     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   3156     if (*result)
   3157       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
   3158   }
   3159   return res;
   3160 }
   3161 
   3162 #define INIT_READDIR                  \
   3163   COMMON_INTERCEPT_FUNCTION(opendir); \
   3164   COMMON_INTERCEPT_FUNCTION(readdir); \
   3165   COMMON_INTERCEPT_FUNCTION(readdir_r);
   3166 #else
   3167 #define INIT_READDIR
   3168 #endif
   3169 
   3170 #if SANITIZER_INTERCEPT_READDIR64
   3171 INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
   3172   void *ctx;
   3173   COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
   3174   // FIXME: under ASan the call below may write to freed memory and corrupt
   3175   // its metadata. See
   3176   // https://github.com/google/sanitizers/issues/321.
   3177   __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
   3178   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
   3179   return res;
   3180 }
   3181 
   3182 INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
   3183             __sanitizer_dirent64 **result) {
   3184   void *ctx;
   3185   COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
   3186   // FIXME: under ASan the call below may write to freed memory and corrupt
   3187   // its metadata. See
   3188   // https://github.com/google/sanitizers/issues/321.
   3189   int res = REAL(readdir64_r)(dirp, entry, result);
   3190   if (!res) {
   3191     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   3192     if (*result)
   3193       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
   3194   }
   3195   return res;
   3196 }
   3197 #define INIT_READDIR64                  \
   3198   COMMON_INTERCEPT_FUNCTION(readdir64); \
   3199   COMMON_INTERCEPT_FUNCTION(readdir64_r);
   3200 #else
   3201 #define INIT_READDIR64
   3202 #endif
   3203 
   3204 #if SANITIZER_INTERCEPT_PTRACE
   3205 INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
   3206   void *ctx;
   3207   COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
   3208   __sanitizer_iovec local_iovec;
   3209 
   3210   if (data) {
   3211     if (request == ptrace_setregs)
   3212       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
   3213     else if (request == ptrace_setfpregs)
   3214       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
   3215     else if (request == ptrace_setfpxregs)
   3216       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
   3217     else if (request == ptrace_setvfpregs)
   3218       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
   3219     else if (request == ptrace_setsiginfo)
   3220       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
   3221     // Some kernel might zero the iovec::iov_base in case of invalid
   3222     // write access.  In this case copy the invalid address for further
   3223     // inspection.
   3224     else if (request == ptrace_setregset || request == ptrace_getregset) {
   3225       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
   3226       COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
   3227       local_iovec = *iovec;
   3228       if (request == ptrace_setregset)
   3229         COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
   3230     }
   3231   }
   3232 
   3233   // FIXME: under ASan the call below may write to freed memory and corrupt
   3234   // its metadata. See
   3235   // https://github.com/google/sanitizers/issues/321.
   3236   uptr res = REAL(ptrace)(request, pid, addr, data);
   3237 
   3238   if (!res && data) {
   3239     // Note that PEEK* requests assign different meaning to the return value.
   3240     // This function does not handle them (nor does it need to).
   3241     if (request == ptrace_getregs)
   3242       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
   3243     else if (request == ptrace_getfpregs)
   3244       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
   3245     else if (request == ptrace_getfpxregs)
   3246       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
   3247     else if (request == ptrace_getvfpregs)
   3248       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
   3249     else if (request == ptrace_getsiginfo)
   3250       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
   3251     else if (request == ptrace_geteventmsg)
   3252       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
   3253     else if (request == ptrace_getregset) {
   3254       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
   3255       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
   3256       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
   3257                                      local_iovec.iov_len);
   3258     }
   3259   }
   3260   return res;
   3261 }
   3262 
   3263 #define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
   3264 #else
   3265 #define INIT_PTRACE
   3266 #endif
   3267 
   3268 #if SANITIZER_INTERCEPT_SETLOCALE
   3269 static void unpoison_ctype_arrays(void *ctx) {
   3270 #if SANITIZER_NETBSD
   3271   // These arrays contain 256 regular elements in unsigned char range + 1 EOF
   3272   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));
   3273   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));
   3274   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));
   3275 #endif
   3276 }
   3277 
   3278 INTERCEPTOR(char *, setlocale, int category, char *locale) {
   3279   void *ctx;
   3280   COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
   3281   if (locale)
   3282     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
   3283   char *res = REAL(setlocale)(category, locale);
   3284   if (res) {
   3285     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3286     unpoison_ctype_arrays(ctx);
   3287   }
   3288   return res;
   3289 }
   3290 
   3291 #define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
   3292 #else
   3293 #define INIT_SETLOCALE
   3294 #endif
   3295 
   3296 #if SANITIZER_INTERCEPT_GETCWD
   3297 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
   3298   void *ctx;
   3299   COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
   3300   // FIXME: under ASan the call below may write to freed memory and corrupt
   3301   // its metadata. See
   3302   // https://github.com/google/sanitizers/issues/321.
   3303   char *res = REAL(getcwd)(buf, size);
   3304   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3305   return res;
   3306 }
   3307 #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
   3308 #else
   3309 #define INIT_GETCWD
   3310 #endif
   3311 
   3312 #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
   3313 INTERCEPTOR(char *, get_current_dir_name, int fake) {
   3314   void *ctx;
   3315   COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
   3316   // FIXME: under ASan the call below may write to freed memory and corrupt
   3317   // its metadata. See
   3318   // https://github.com/google/sanitizers/issues/321.
   3319   char *res = REAL(get_current_dir_name)(fake);
   3320   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3321   return res;
   3322 }
   3323 
   3324 #define INIT_GET_CURRENT_DIR_NAME \
   3325   COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
   3326 #else
   3327 #define INIT_GET_CURRENT_DIR_NAME
   3328 #endif
   3329 
   3330 UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
   3331   CHECK(endptr);
   3332   if (nptr == *endptr) {
   3333     // No digits were found at strtol call, we need to find out the last
   3334     // symbol accessed by strtoll on our own.
   3335     // We get this symbol by skipping leading blanks and optional +/- sign.
   3336     while (IsSpace(*nptr)) nptr++;
   3337     if (*nptr == '+' || *nptr == '-') nptr++;
   3338     *endptr = const_cast<char *>(nptr);
   3339   }
   3340   CHECK(*endptr >= nptr);
   3341 }
   3342 
   3343 UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
   3344                              char **endptr, char *real_endptr, int base) {
   3345   if (endptr) {
   3346     *endptr = real_endptr;
   3347     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
   3348   }
   3349   // If base has unsupported value, strtol can exit with EINVAL
   3350   // without reading any characters. So do additional checks only
   3351   // if base is valid.
   3352   bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
   3353   if (is_valid_base) {
   3354     FixRealStrtolEndptr(nptr, &real_endptr);
   3355   }
   3356   COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
   3357                                  (real_endptr - nptr) + 1 : 0);
   3358 }
   3359 
   3360 
   3361 #if SANITIZER_INTERCEPT_STRTOIMAX
   3362 INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
   3363   void *ctx;
   3364   COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
   3365   // FIXME: under ASan the call below may write to freed memory and corrupt
   3366   // its metadata. See
   3367   // https://github.com/google/sanitizers/issues/321.
   3368   char *real_endptr;
   3369   INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
   3370   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
   3371   return res;
   3372 }
   3373 
   3374 INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
   3375   void *ctx;
   3376   COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
   3377   // FIXME: under ASan the call below may write to freed memory and corrupt
   3378   // its metadata. See
   3379   // https://github.com/google/sanitizers/issues/321.
   3380   char *real_endptr;
   3381   UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
   3382   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
   3383   return res;
   3384 }
   3385 
   3386 #define INIT_STRTOIMAX                  \
   3387   COMMON_INTERCEPT_FUNCTION(strtoimax); \
   3388   COMMON_INTERCEPT_FUNCTION(strtoumax);
   3389 #else
   3390 #define INIT_STRTOIMAX
   3391 #endif
   3392 
   3393 #if SANITIZER_INTERCEPT_MBSTOWCS
   3394 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
   3395   void *ctx;
   3396   COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
   3397   // FIXME: under ASan the call below may write to freed memory and corrupt
   3398   // its metadata. See
   3399   // https://github.com/google/sanitizers/issues/321.
   3400   SIZE_T res = REAL(mbstowcs)(dest, src, len);
   3401   if (res != (SIZE_T) - 1 && dest) {
   3402     SIZE_T write_cnt = res + (res < len);
   3403     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
   3404   }
   3405   return res;
   3406 }
   3407 
   3408 INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
   3409             void *ps) {
   3410   void *ctx;
   3411   COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
   3412   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   3413   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   3414   // FIXME: under ASan the call below may write to freed memory and corrupt
   3415   // its metadata. See
   3416   // https://github.com/google/sanitizers/issues/321.
   3417   SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
   3418   if (res != (SIZE_T)(-1) && dest && src) {
   3419     // This function, and several others, may or may not write the terminating
   3420     // \0 character. They write it iff they clear *src.
   3421     SIZE_T write_cnt = res + !*src;
   3422     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
   3423   }
   3424   return res;
   3425 }
   3426 
   3427 #define INIT_MBSTOWCS                  \
   3428   COMMON_INTERCEPT_FUNCTION(mbstowcs); \
   3429   COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
   3430 #else
   3431 #define INIT_MBSTOWCS
   3432 #endif
   3433 
   3434 #if SANITIZER_INTERCEPT_MBSNRTOWCS
   3435 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
   3436             SIZE_T len, void *ps) {
   3437   void *ctx;
   3438   COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
   3439   if (src) {
   3440     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   3441     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
   3442   }
   3443   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   3444   // FIXME: under ASan the call below may write to freed memory and corrupt
   3445   // its metadata. See
   3446   // https://github.com/google/sanitizers/issues/321.
   3447   SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
   3448   if (res != (SIZE_T)(-1) && dest && src) {
   3449     SIZE_T write_cnt = res + !*src;
   3450     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
   3451   }
   3452   return res;
   3453 }
   3454 
   3455 #define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
   3456 #else
   3457 #define INIT_MBSNRTOWCS
   3458 #endif
   3459 
   3460 #if SANITIZER_INTERCEPT_WCSTOMBS
   3461 INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
   3462   void *ctx;
   3463   COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
   3464   // FIXME: under ASan the call below may write to freed memory and corrupt
   3465   // its metadata. See
   3466   // https://github.com/google/sanitizers/issues/321.
   3467   SIZE_T res = REAL(wcstombs)(dest, src, len);
   3468   if (res != (SIZE_T) - 1 && dest) {
   3469     SIZE_T write_cnt = res + (res < len);
   3470     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   3471   }
   3472   return res;
   3473 }
   3474 
   3475 INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
   3476             void *ps) {
   3477   void *ctx;
   3478   COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
   3479   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   3480   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   3481   // FIXME: under ASan the call below may write to freed memory and corrupt
   3482   // its metadata. See
   3483   // https://github.com/google/sanitizers/issues/321.
   3484   SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
   3485   if (res != (SIZE_T) - 1 && dest && src) {
   3486     SIZE_T write_cnt = res + !*src;
   3487     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   3488   }
   3489   return res;
   3490 }
   3491 
   3492 #define INIT_WCSTOMBS                  \
   3493   COMMON_INTERCEPT_FUNCTION(wcstombs); \
   3494   COMMON_INTERCEPT_FUNCTION(wcsrtombs);
   3495 #else
   3496 #define INIT_WCSTOMBS
   3497 #endif
   3498 
   3499 #if SANITIZER_INTERCEPT_WCSNRTOMBS
   3500 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
   3501             SIZE_T len, void *ps) {
   3502   void *ctx;
   3503   COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
   3504   if (src) {
   3505     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   3506     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
   3507   }
   3508   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   3509   // FIXME: under ASan the call below may write to freed memory and corrupt
   3510   // its metadata. See
   3511   // https://github.com/google/sanitizers/issues/321.
   3512   SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
   3513   if (res != ((SIZE_T)-1) && dest && src) {
   3514     SIZE_T write_cnt = res + !*src;
   3515     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   3516   }
   3517   return res;
   3518 }
   3519 
   3520 #define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
   3521 #else
   3522 #define INIT_WCSNRTOMBS
   3523 #endif
   3524 
   3525 
   3526 #if SANITIZER_INTERCEPT_WCRTOMB
   3527 INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
   3528   void *ctx;
   3529   COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
   3530   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   3531   // FIXME: under ASan the call below may write to freed memory and corrupt
   3532   // its metadata. See
   3533   // https://github.com/google/sanitizers/issues/321.
   3534   SIZE_T res = REAL(wcrtomb)(dest, src, ps);
   3535   if (res != ((SIZE_T)-1) && dest) {
   3536     SIZE_T write_cnt = res;
   3537     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   3538   }
   3539   return res;
   3540 }
   3541 
   3542 #define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
   3543 #else
   3544 #define INIT_WCRTOMB
   3545 #endif
   3546 
   3547 #if SANITIZER_INTERCEPT_TCGETATTR
   3548 INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
   3549   void *ctx;
   3550   COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
   3551   // FIXME: under ASan the call below may write to freed memory and corrupt
   3552   // its metadata. See
   3553   // https://github.com/google/sanitizers/issues/321.
   3554   int res = REAL(tcgetattr)(fd, termios_p);
   3555   if (!res && termios_p)
   3556     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
   3557   return res;
   3558 }
   3559 
   3560 #define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
   3561 #else
   3562 #define INIT_TCGETATTR
   3563 #endif
   3564 
   3565 #if SANITIZER_INTERCEPT_REALPATH
   3566 INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
   3567   void *ctx;
   3568   COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
   3569   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3570 
   3571   // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
   3572   // version of a versioned symbol. For realpath(), this gives us something
   3573   // (called __old_realpath) that does not handle NULL in the second argument.
   3574   // Handle it as part of the interceptor.
   3575   char *allocated_path = nullptr;
   3576   if (!resolved_path)
   3577     allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
   3578 
   3579   char *res = REAL(realpath)(path, resolved_path);
   3580   if (allocated_path && !res) WRAP(free)(allocated_path);
   3581   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3582   return res;
   3583 }
   3584 #define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
   3585 #else
   3586 #define INIT_REALPATH
   3587 #endif
   3588 
   3589 #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
   3590 INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
   3591   void *ctx;
   3592   COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
   3593   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3594   char *res = REAL(canonicalize_file_name)(path);
   3595   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3596   return res;
   3597 }
   3598 #define INIT_CANONICALIZE_FILE_NAME \
   3599   COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
   3600 #else
   3601 #define INIT_CANONICALIZE_FILE_NAME
   3602 #endif
   3603 
   3604 #if SANITIZER_INTERCEPT_CONFSTR
   3605 INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
   3606   void *ctx;
   3607   COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
   3608   // FIXME: under ASan the call below may write to freed memory and corrupt
   3609   // its metadata. See
   3610   // https://github.com/google/sanitizers/issues/321.
   3611   SIZE_T res = REAL(confstr)(name, buf, len);
   3612   if (buf && res)
   3613     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
   3614   return res;
   3615 }
   3616 #define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
   3617 #else
   3618 #define INIT_CONFSTR
   3619 #endif
   3620 
   3621 #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
   3622 INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
   3623   void *ctx;
   3624   COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
   3625   // FIXME: under ASan the call below may write to freed memory and corrupt
   3626   // its metadata. See
   3627   // https://github.com/google/sanitizers/issues/321.
   3628   int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
   3629   if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
   3630   return res;
   3631 }
   3632 #define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
   3633 #else
   3634 #define INIT_SCHED_GETAFFINITY
   3635 #endif
   3636 
   3637 #if SANITIZER_INTERCEPT_SCHED_GETPARAM
   3638 INTERCEPTOR(int, sched_getparam, int pid, void *param) {
   3639   void *ctx;
   3640   COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
   3641   int res = REAL(sched_getparam)(pid, param);
   3642   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
   3643   return res;
   3644 }
   3645 #define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
   3646 #else
   3647 #define INIT_SCHED_GETPARAM
   3648 #endif
   3649 
   3650 #if SANITIZER_INTERCEPT_STRERROR
   3651 INTERCEPTOR(char *, strerror, int errnum) {
   3652   void *ctx;
   3653   COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
   3654   char *res = REAL(strerror)(errnum);
   3655   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   3656   return res;
   3657 }
   3658 #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
   3659 #else
   3660 #define INIT_STRERROR
   3661 #endif
   3662 
   3663 #if SANITIZER_INTERCEPT_STRERROR_R
   3664 // There are 2 versions of strerror_r:
   3665 //  * POSIX version returns 0 on success, negative error code on failure,
   3666 //    writes message to buf.
   3667 //  * GNU version returns message pointer, which points to either buf or some
   3668 //    static storage.
   3669 #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
   3670     SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD ||                 \
   3671     SANITIZER_FREEBSD || SANITIZER_OPENBSD
   3672 // POSIX version. Spec is not clear on whether buf is NULL-terminated.
   3673 // At least on OSX, buf contents are valid even when the call fails.
   3674 INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
   3675   void *ctx;
   3676   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
   3677   // FIXME: under ASan the call below may write to freed memory and corrupt
   3678   // its metadata. See
   3679   // https://github.com/google/sanitizers/issues/321.
   3680   int res = REAL(strerror_r)(errnum, buf, buflen);
   3681 
   3682   SIZE_T sz = internal_strnlen(buf, buflen);
   3683   if (sz < buflen) ++sz;
   3684   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
   3685   return res;
   3686 }
   3687 #else
   3688 // GNU version.
   3689 INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
   3690   void *ctx;
   3691   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
   3692   // FIXME: under ASan the call below may write to freed memory and corrupt
   3693   // its metadata. See
   3694   // https://github.com/google/sanitizers/issues/321.
   3695   char *res = REAL(strerror_r)(errnum, buf, buflen);
   3696   if (res == buf)
   3697     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3698   else
   3699     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   3700   return res;
   3701 }
   3702 #endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||
   3703        //SANITIZER_MAC
   3704 #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
   3705 #else
   3706 #define INIT_STRERROR_R
   3707 #endif
   3708 
   3709 #if SANITIZER_INTERCEPT_XPG_STRERROR_R
   3710 INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
   3711   void *ctx;
   3712   COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
   3713   // FIXME: under ASan the call below may write to freed memory and corrupt
   3714   // its metadata. See
   3715   // https://github.com/google/sanitizers/issues/321.
   3716   int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
   3717   // This version always returns a null-terminated string.
   3718   if (buf && buflen)
   3719     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   3720   return res;
   3721 }
   3722 #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
   3723 #else
   3724 #define INIT_XPG_STRERROR_R
   3725 #endif
   3726 
   3727 #if SANITIZER_INTERCEPT_SCANDIR
   3728 typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
   3729 typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
   3730                                 const struct __sanitizer_dirent **);
   3731 
   3732 static THREADLOCAL scandir_filter_f scandir_filter;
   3733 static THREADLOCAL scandir_compar_f scandir_compar;
   3734 
   3735 static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
   3736   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   3737   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
   3738   return scandir_filter(dir);
   3739 }
   3740 
   3741 static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
   3742                                   const struct __sanitizer_dirent **b) {
   3743   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   3744   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
   3745   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
   3746   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
   3747   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
   3748   return scandir_compar(a, b);
   3749 }
   3750 
   3751 INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
   3752             scandir_filter_f filter, scandir_compar_f compar) {
   3753   void *ctx;
   3754   COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
   3755   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
   3756   scandir_filter = filter;
   3757   scandir_compar = compar;
   3758   // FIXME: under ASan the call below may write to freed memory and corrupt
   3759   // its metadata. See
   3760   // https://github.com/google/sanitizers/issues/321.
   3761   int res = REAL(scandir)(dirp, namelist,
   3762                           filter ? wrapped_scandir_filter : nullptr,
   3763                           compar ? wrapped_scandir_compar : nullptr);
   3764   scandir_filter = nullptr;
   3765   scandir_compar = nullptr;
   3766   if (namelist && res > 0) {
   3767     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
   3768     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
   3769     for (int i = 0; i < res; ++i)
   3770       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
   3771                                      (*namelist)[i]->d_reclen);
   3772   }
   3773   return res;
   3774 }
   3775 #define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
   3776 #else
   3777 #define INIT_SCANDIR
   3778 #endif
   3779 
   3780 #if SANITIZER_INTERCEPT_SCANDIR64
   3781 typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
   3782 typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
   3783                                   const struct __sanitizer_dirent64 **);
   3784 
   3785 static THREADLOCAL scandir64_filter_f scandir64_filter;
   3786 static THREADLOCAL scandir64_compar_f scandir64_compar;
   3787 
   3788 static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
   3789   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   3790   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
   3791   return scandir64_filter(dir);
   3792 }
   3793 
   3794 static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
   3795                                     const struct __sanitizer_dirent64 **b) {
   3796   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   3797   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
   3798   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
   3799   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
   3800   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
   3801   return scandir64_compar(a, b);
   3802 }
   3803 
   3804 INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
   3805             scandir64_filter_f filter, scandir64_compar_f compar) {
   3806   void *ctx;
   3807   COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
   3808   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
   3809   scandir64_filter = filter;
   3810   scandir64_compar = compar;
   3811   // FIXME: under ASan the call below may write to freed memory and corrupt
   3812   // its metadata. See
   3813   // https://github.com/google/sanitizers/issues/321.
   3814   int res =
   3815       REAL(scandir64)(dirp, namelist,
   3816                       filter ? wrapped_scandir64_filter : nullptr,
   3817                       compar ? wrapped_scandir64_compar : nullptr);
   3818   scandir64_filter = nullptr;
   3819   scandir64_compar = nullptr;
   3820   if (namelist && res > 0) {
   3821     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
   3822     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
   3823     for (int i = 0; i < res; ++i)
   3824       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
   3825                                      (*namelist)[i]->d_reclen);
   3826   }
   3827   return res;
   3828 }
   3829 #define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
   3830 #else
   3831 #define INIT_SCANDIR64
   3832 #endif
   3833 
   3834 #if SANITIZER_INTERCEPT_GETGROUPS
   3835 INTERCEPTOR(int, getgroups, int size, u32 *lst) {
   3836   void *ctx;
   3837   COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
   3838   // FIXME: under ASan the call below may write to freed memory and corrupt
   3839   // its metadata. See
   3840   // https://github.com/google/sanitizers/issues/321.
   3841   int res = REAL(getgroups)(size, lst);
   3842   if (res >= 0 && lst && size > 0)
   3843     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
   3844   return res;
   3845 }
   3846 #define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
   3847 #else
   3848 #define INIT_GETGROUPS
   3849 #endif
   3850 
   3851 #if SANITIZER_INTERCEPT_POLL
   3852 static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
   3853                         __sanitizer_nfds_t nfds) {
   3854   for (unsigned i = 0; i < nfds; ++i) {
   3855     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
   3856     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
   3857   }
   3858 }
   3859 
   3860 static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
   3861                          __sanitizer_nfds_t nfds) {
   3862   for (unsigned i = 0; i < nfds; ++i)
   3863     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
   3864                                    sizeof(fds[i].revents));
   3865 }
   3866 
   3867 INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
   3868             int timeout) {
   3869   void *ctx;
   3870   COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
   3871   if (fds && nfds) read_pollfd(ctx, fds, nfds);
   3872   int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
   3873   if (fds && nfds) write_pollfd(ctx, fds, nfds);
   3874   return res;
   3875 }
   3876 #define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
   3877 #else
   3878 #define INIT_POLL
   3879 #endif
   3880 
   3881 #if SANITIZER_INTERCEPT_PPOLL
   3882 INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
   3883             void *timeout_ts, __sanitizer_sigset_t *sigmask) {
   3884   void *ctx;
   3885   COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
   3886   if (fds && nfds) read_pollfd(ctx, fds, nfds);
   3887   if (timeout_ts)
   3888     COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
   3889   if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));
   3890   int res =
   3891       COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
   3892   if (fds && nfds) write_pollfd(ctx, fds, nfds);
   3893   return res;
   3894 }
   3895 #define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
   3896 #else
   3897 #define INIT_PPOLL
   3898 #endif
   3899 
   3900 #if SANITIZER_INTERCEPT_WORDEXP
   3901 INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
   3902   void *ctx;
   3903   COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
   3904   if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
   3905   // FIXME: under ASan the call below may write to freed memory and corrupt
   3906   // its metadata. See
   3907   // https://github.com/google/sanitizers/issues/321.
   3908   int res = REAL(wordexp)(s, p, flags);
   3909   if (!res && p) {
   3910     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   3911     if (p->we_wordc)
   3912       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
   3913                                      sizeof(*p->we_wordv) * p->we_wordc);
   3914     for (uptr i = 0; i < p->we_wordc; ++i) {
   3915       char *w = p->we_wordv[i];
   3916       if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
   3917     }
   3918   }
   3919   return res;
   3920 }
   3921 #define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
   3922 #else
   3923 #define INIT_WORDEXP
   3924 #endif
   3925 
   3926 #if SANITIZER_INTERCEPT_SIGWAIT
   3927 INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
   3928   void *ctx;
   3929   COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
   3930   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
   3931   // FIXME: under ASan the call below may write to freed memory and corrupt
   3932   // its metadata. See
   3933   // https://github.com/google/sanitizers/issues/321.
   3934   int res = REAL(sigwait)(set, sig);
   3935   if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
   3936   return res;
   3937 }
   3938 #define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
   3939 #else
   3940 #define INIT_SIGWAIT
   3941 #endif
   3942 
   3943 #if SANITIZER_INTERCEPT_SIGWAITINFO
   3944 INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
   3945   void *ctx;
   3946   COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
   3947   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
   3948   // FIXME: under ASan the call below may write to freed memory and corrupt
   3949   // its metadata. See
   3950   // https://github.com/google/sanitizers/issues/321.
   3951   int res = REAL(sigwaitinfo)(set, info);
   3952   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
   3953   return res;
   3954 }
   3955 #define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
   3956 #else
   3957 #define INIT_SIGWAITINFO
   3958 #endif
   3959 
   3960 #if SANITIZER_INTERCEPT_SIGTIMEDWAIT
   3961 INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
   3962             void *timeout) {
   3963   void *ctx;
   3964   COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
   3965   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
   3966   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
   3967   // FIXME: under ASan the call below may write to freed memory and corrupt
   3968   // its metadata. See
   3969   // https://github.com/google/sanitizers/issues/321.
   3970   int res = REAL(sigtimedwait)(set, info, timeout);
   3971   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
   3972   return res;
   3973 }
   3974 #define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
   3975 #else
   3976 #define INIT_SIGTIMEDWAIT
   3977 #endif
   3978 
   3979 #if SANITIZER_INTERCEPT_SIGSETOPS
   3980 INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
   3981   void *ctx;
   3982   COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
   3983   // FIXME: under ASan the call below may write to freed memory and corrupt
   3984   // its metadata. See
   3985   // https://github.com/google/sanitizers/issues/321.
   3986   int res = REAL(sigemptyset)(set);
   3987   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
   3988   return res;
   3989 }
   3990 
   3991 INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
   3992   void *ctx;
   3993   COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
   3994   // FIXME: under ASan the call below may write to freed memory and corrupt
   3995   // its metadata. See
   3996   // https://github.com/google/sanitizers/issues/321.
   3997   int res = REAL(sigfillset)(set);
   3998   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
   3999   return res;
   4000 }
   4001 #define INIT_SIGSETOPS                    \
   4002   COMMON_INTERCEPT_FUNCTION(sigemptyset); \
   4003   COMMON_INTERCEPT_FUNCTION(sigfillset);
   4004 #else
   4005 #define INIT_SIGSETOPS
   4006 #endif
   4007 
   4008 #if SANITIZER_INTERCEPT_SIGPENDING
   4009 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
   4010   void *ctx;
   4011   COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
   4012   // FIXME: under ASan the call below may write to freed memory and corrupt
   4013   // its metadata. See
   4014   // https://github.com/google/sanitizers/issues/321.
   4015   int res = REAL(sigpending)(set);
   4016   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
   4017   return res;
   4018 }
   4019 #define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
   4020 #else
   4021 #define INIT_SIGPENDING
   4022 #endif
   4023 
   4024 #if SANITIZER_INTERCEPT_SIGPROCMASK
   4025 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
   4026             __sanitizer_sigset_t *oldset) {
   4027   void *ctx;
   4028   COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
   4029   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
   4030   // FIXME: under ASan the call below may write to freed memory and corrupt
   4031   // its metadata. See
   4032   // https://github.com/google/sanitizers/issues/321.
   4033   int res = REAL(sigprocmask)(how, set, oldset);
   4034   if (!res && oldset)
   4035     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
   4036   return res;
   4037 }
   4038 #define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
   4039 #else
   4040 #define INIT_SIGPROCMASK
   4041 #endif
   4042 
   4043 #if SANITIZER_INTERCEPT_BACKTRACE
   4044 INTERCEPTOR(int, backtrace, void **buffer, int size) {
   4045   void *ctx;
   4046   COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
   4047   // FIXME: under ASan the call below may write to freed memory and corrupt
   4048   // its metadata. See
   4049   // https://github.com/google/sanitizers/issues/321.
   4050   int res = REAL(backtrace)(buffer, size);
   4051   if (res && buffer)
   4052     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
   4053   return res;
   4054 }
   4055 
   4056 INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
   4057   void *ctx;
   4058   COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
   4059   if (buffer && size)
   4060     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
   4061   // FIXME: under ASan the call below may write to freed memory and corrupt
   4062   // its metadata. See
   4063   // https://github.com/google/sanitizers/issues/321.
   4064   char **res = REAL(backtrace_symbols)(buffer, size);
   4065   if (res && size) {
   4066     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
   4067     for (int i = 0; i < size; ++i)
   4068       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
   4069   }
   4070   return res;
   4071 }
   4072 #define INIT_BACKTRACE                  \
   4073   COMMON_INTERCEPT_FUNCTION(backtrace); \
   4074   COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
   4075 #else
   4076 #define INIT_BACKTRACE
   4077 #endif
   4078 
   4079 #if SANITIZER_INTERCEPT__EXIT
   4080 INTERCEPTOR(void, _exit, int status) {
   4081   void *ctx;
   4082   COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
   4083   COMMON_INTERCEPTOR_USER_CALLBACK_START();
   4084   int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
   4085   COMMON_INTERCEPTOR_USER_CALLBACK_END();
   4086   if (status == 0) status = status1;
   4087   REAL(_exit)(status);
   4088 }
   4089 #define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
   4090 #else
   4091 #define INIT__EXIT
   4092 #endif
   4093 
   4094 #if SANITIZER_INTERCEPT_PTHREAD_MUTEX
   4095 INTERCEPTOR(int, pthread_mutex_lock, void *m) {
   4096   void *ctx;
   4097   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
   4098   COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
   4099   int res = REAL(pthread_mutex_lock)(m);
   4100   if (res == errno_EOWNERDEAD)
   4101     COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
   4102   if (res == 0 || res == errno_EOWNERDEAD)
   4103     COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
   4104   if (res == errno_EINVAL)
   4105     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
   4106   return res;
   4107 }
   4108 
   4109 INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
   4110   void *ctx;
   4111   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
   4112   COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
   4113   int res = REAL(pthread_mutex_unlock)(m);
   4114   if (res == errno_EINVAL)
   4115     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
   4116   return res;
   4117 }
   4118 
   4119 #define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
   4120 #define INIT_PTHREAD_MUTEX_UNLOCK \
   4121   COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
   4122 #else
   4123 #define INIT_PTHREAD_MUTEX_LOCK
   4124 #define INIT_PTHREAD_MUTEX_UNLOCK
   4125 #endif
   4126 
   4127 #if SANITIZER_INTERCEPT___PTHREAD_MUTEX
   4128 INTERCEPTOR(int, __pthread_mutex_lock, void *m) {
   4129   return WRAP(pthread_mutex_lock)(m);
   4130 }
   4131 
   4132 INTERCEPTOR(int, __pthread_mutex_unlock, void *m) {
   4133   return WRAP(pthread_mutex_unlock)(m);
   4134 }
   4135 
   4136 #define INIT___PTHREAD_MUTEX_LOCK \
   4137   COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock)
   4138 #define INIT___PTHREAD_MUTEX_UNLOCK \
   4139   COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock)
   4140 #else
   4141 #define INIT___PTHREAD_MUTEX_LOCK
   4142 #define INIT___PTHREAD_MUTEX_UNLOCK
   4143 #endif
   4144 
   4145 #if SANITIZER_INTERCEPT___LIBC_MUTEX
   4146 INTERCEPTOR(int, __libc_mutex_lock, void *m)
   4147 ALIAS(WRAPPER_NAME(pthread_mutex_lock));
   4148 
   4149 INTERCEPTOR(int, __libc_mutex_unlock, void *m)
   4150 ALIAS(WRAPPER_NAME(pthread_mutex_unlock));
   4151 
   4152 INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)
   4153 ALIAS(WRAPPER_NAME(pthread_setcancelstate));
   4154 
   4155 #define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock)
   4156 #define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock)
   4157 #define INIT___LIBC_THR_SETCANCELSTATE \
   4158   COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)
   4159 #else
   4160 #define INIT___LIBC_MUTEX_LOCK
   4161 #define INIT___LIBC_MUTEX_UNLOCK
   4162 #define INIT___LIBC_THR_SETCANCELSTATE
   4163 #endif
   4164 
   4165 #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
   4166 static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
   4167   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
   4168   if (mnt->mnt_fsname)
   4169     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
   4170                                    REAL(strlen)(mnt->mnt_fsname) + 1);
   4171   if (mnt->mnt_dir)
   4172     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
   4173                                    REAL(strlen)(mnt->mnt_dir) + 1);
   4174   if (mnt->mnt_type)
   4175     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
   4176                                    REAL(strlen)(mnt->mnt_type) + 1);
   4177   if (mnt->mnt_opts)
   4178     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
   4179                                    REAL(strlen)(mnt->mnt_opts) + 1);
   4180 }
   4181 #endif
   4182 
   4183 #if SANITIZER_INTERCEPT_GETMNTENT
   4184 INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
   4185   void *ctx;
   4186   COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
   4187   __sanitizer_mntent *res = REAL(getmntent)(fp);
   4188   if (res) write_mntent(ctx, res);
   4189   return res;
   4190 }
   4191 #define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
   4192 #else
   4193 #define INIT_GETMNTENT
   4194 #endif
   4195 
   4196 #if SANITIZER_INTERCEPT_GETMNTENT_R
   4197 INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
   4198             __sanitizer_mntent *mntbuf, char *buf, int buflen) {
   4199   void *ctx;
   4200   COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
   4201   __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
   4202   if (res) write_mntent(ctx, res);
   4203   return res;
   4204 }
   4205 #define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
   4206 #else
   4207 #define INIT_GETMNTENT_R
   4208 #endif
   4209 
   4210 #if SANITIZER_INTERCEPT_STATFS
   4211 INTERCEPTOR(int, statfs, char *path, void *buf) {
   4212   void *ctx;
   4213   COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
   4214   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4215   // FIXME: under ASan the call below may write to freed memory and corrupt
   4216   // its metadata. See
   4217   // https://github.com/google/sanitizers/issues/321.
   4218   int res = REAL(statfs)(path, buf);
   4219   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
   4220   return res;
   4221 }
   4222 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
   4223   void *ctx;
   4224   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
   4225   // FIXME: under ASan the call below may write to freed memory and corrupt
   4226   // its metadata. See
   4227   // https://github.com/google/sanitizers/issues/321.
   4228   int res = REAL(fstatfs)(fd, buf);
   4229   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
   4230   return res;
   4231 }
   4232 #define INIT_STATFS                  \
   4233   COMMON_INTERCEPT_FUNCTION(statfs); \
   4234   COMMON_INTERCEPT_FUNCTION(fstatfs);
   4235 #else
   4236 #define INIT_STATFS
   4237 #endif
   4238 
   4239 #if SANITIZER_INTERCEPT_STATFS64
   4240 INTERCEPTOR(int, statfs64, char *path, void *buf) {
   4241   void *ctx;
   4242   COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
   4243   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4244   // FIXME: under ASan the call below may write to freed memory and corrupt
   4245   // its metadata. See
   4246   // https://github.com/google/sanitizers/issues/321.
   4247   int res = REAL(statfs64)(path, buf);
   4248   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
   4249   return res;
   4250 }
   4251 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
   4252   void *ctx;
   4253   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
   4254   // FIXME: under ASan the call below may write to freed memory and corrupt
   4255   // its metadata. See
   4256   // https://github.com/google/sanitizers/issues/321.
   4257   int res = REAL(fstatfs64)(fd, buf);
   4258   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
   4259   return res;
   4260 }
   4261 #define INIT_STATFS64                  \
   4262   COMMON_INTERCEPT_FUNCTION(statfs64); \
   4263   COMMON_INTERCEPT_FUNCTION(fstatfs64);
   4264 #else
   4265 #define INIT_STATFS64
   4266 #endif
   4267 
   4268 #if SANITIZER_INTERCEPT_STATVFS
   4269 INTERCEPTOR(int, statvfs, char *path, void *buf) {
   4270   void *ctx;
   4271   COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
   4272   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4273   // FIXME: under ASan the call below may write to freed memory and corrupt
   4274   // its metadata. See
   4275   // https://github.com/google/sanitizers/issues/321.
   4276   int res = REAL(statvfs)(path, buf);
   4277   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
   4278   return res;
   4279 }
   4280 INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
   4281   void *ctx;
   4282   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
   4283   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   4284   // FIXME: under ASan the call below may write to freed memory and corrupt
   4285   // its metadata. See
   4286   // https://github.com/google/sanitizers/issues/321.
   4287   int res = REAL(fstatvfs)(fd, buf);
   4288   if (!res) {
   4289     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
   4290     if (fd >= 0)
   4291       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   4292   }
   4293   return res;
   4294 }
   4295 #define INIT_STATVFS                  \
   4296   COMMON_INTERCEPT_FUNCTION(statvfs); \
   4297   COMMON_INTERCEPT_FUNCTION(fstatvfs);
   4298 #else
   4299 #define INIT_STATVFS
   4300 #endif
   4301 
   4302 #if SANITIZER_INTERCEPT_STATVFS64
   4303 INTERCEPTOR(int, statvfs64, char *path, void *buf) {
   4304   void *ctx;
   4305   COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
   4306   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4307   // FIXME: under ASan the call below may write to freed memory and corrupt
   4308   // its metadata. See
   4309   // https://github.com/google/sanitizers/issues/321.
   4310   int res = REAL(statvfs64)(path, buf);
   4311   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
   4312   return res;
   4313 }
   4314 INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
   4315   void *ctx;
   4316   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
   4317   // FIXME: under ASan the call below may write to freed memory and corrupt
   4318   // its metadata. See
   4319   // https://github.com/google/sanitizers/issues/321.
   4320   int res = REAL(fstatvfs64)(fd, buf);
   4321   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
   4322   return res;
   4323 }
   4324 #define INIT_STATVFS64                  \
   4325   COMMON_INTERCEPT_FUNCTION(statvfs64); \
   4326   COMMON_INTERCEPT_FUNCTION(fstatvfs64);
   4327 #else
   4328 #define INIT_STATVFS64
   4329 #endif
   4330 
   4331 #if SANITIZER_INTERCEPT_INITGROUPS
   4332 INTERCEPTOR(int, initgroups, char *user, u32 group) {
   4333   void *ctx;
   4334   COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
   4335   if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
   4336   int res = REAL(initgroups)(user, group);
   4337   return res;
   4338 }
   4339 #define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
   4340 #else
   4341 #define INIT_INITGROUPS
   4342 #endif
   4343 
   4344 #if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
   4345 INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
   4346   void *ctx;
   4347   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
   4348   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
   4349   char *res = REAL(ether_ntoa)(addr);
   4350   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   4351   return res;
   4352 }
   4353 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
   4354   void *ctx;
   4355   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
   4356   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   4357   __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
   4358   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
   4359   return res;
   4360 }
   4361 #define INIT_ETHER_NTOA_ATON             \
   4362   COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
   4363   COMMON_INTERCEPT_FUNCTION(ether_aton);
   4364 #else
   4365 #define INIT_ETHER_NTOA_ATON
   4366 #endif
   4367 
   4368 #if SANITIZER_INTERCEPT_ETHER_HOST
   4369 INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
   4370   void *ctx;
   4371   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
   4372   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
   4373   // FIXME: under ASan the call below may write to freed memory and corrupt
   4374   // its metadata. See
   4375   // https://github.com/google/sanitizers/issues/321.
   4376   int res = REAL(ether_ntohost)(hostname, addr);
   4377   if (!res && hostname)
   4378     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
   4379   return res;
   4380 }
   4381 INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
   4382   void *ctx;
   4383   COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
   4384   if (hostname)
   4385     COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
   4386   // FIXME: under ASan the call below may write to freed memory and corrupt
   4387   // its metadata. See
   4388   // https://github.com/google/sanitizers/issues/321.
   4389   int res = REAL(ether_hostton)(hostname, addr);
   4390   if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
   4391   return res;
   4392 }
   4393 INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
   4394             char *hostname) {
   4395   void *ctx;
   4396   COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
   4397   if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
   4398   // FIXME: under ASan the call below may write to freed memory and corrupt
   4399   // its metadata. See
   4400   // https://github.com/google/sanitizers/issues/321.
   4401   int res = REAL(ether_line)(line, addr, hostname);
   4402   if (!res) {
   4403     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
   4404     if (hostname)
   4405       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
   4406   }
   4407   return res;
   4408 }
   4409 #define INIT_ETHER_HOST                     \
   4410   COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
   4411   COMMON_INTERCEPT_FUNCTION(ether_hostton); \
   4412   COMMON_INTERCEPT_FUNCTION(ether_line);
   4413 #else
   4414 #define INIT_ETHER_HOST
   4415 #endif
   4416 
   4417 #if SANITIZER_INTERCEPT_ETHER_R
   4418 INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
   4419   void *ctx;
   4420   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
   4421   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
   4422   // FIXME: under ASan the call below may write to freed memory and corrupt
   4423   // its metadata. See
   4424   // https://github.com/google/sanitizers/issues/321.
   4425   char *res = REAL(ether_ntoa_r)(addr, buf);
   4426   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   4427   return res;
   4428 }
   4429 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
   4430             __sanitizer_ether_addr *addr) {
   4431   void *ctx;
   4432   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
   4433   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   4434   // FIXME: under ASan the call below may write to freed memory and corrupt
   4435   // its metadata. See
   4436   // https://github.com/google/sanitizers/issues/321.
   4437   __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
   4438   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
   4439   return res;
   4440 }
   4441 #define INIT_ETHER_R                       \
   4442   COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
   4443   COMMON_INTERCEPT_FUNCTION(ether_aton_r);
   4444 #else
   4445 #define INIT_ETHER_R
   4446 #endif
   4447 
   4448 #if SANITIZER_INTERCEPT_SHMCTL
   4449 INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
   4450   void *ctx;
   4451   COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
   4452   // FIXME: under ASan the call below may write to freed memory and corrupt
   4453   // its metadata. See
   4454   // https://github.com/google/sanitizers/issues/321.
   4455   int res = REAL(shmctl)(shmid, cmd, buf);
   4456   if (res >= 0) {
   4457     unsigned sz = 0;
   4458     if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
   4459       sz = sizeof(__sanitizer_shmid_ds);
   4460     else if (cmd == shmctl_ipc_info)
   4461       sz = struct_shminfo_sz;
   4462     else if (cmd == shmctl_shm_info)
   4463       sz = struct_shm_info_sz;
   4464     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
   4465   }
   4466   return res;
   4467 }
   4468 #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
   4469 #else
   4470 #define INIT_SHMCTL
   4471 #endif
   4472 
   4473 #if SANITIZER_INTERCEPT_RANDOM_R
   4474 INTERCEPTOR(int, random_r, void *buf, u32 *result) {
   4475   void *ctx;
   4476   COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
   4477   // FIXME: under ASan the call below may write to freed memory and corrupt
   4478   // its metadata. See
   4479   // https://github.com/google/sanitizers/issues/321.
   4480   int res = REAL(random_r)(buf, result);
   4481   if (!res && result)
   4482     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   4483   return res;
   4484 }
   4485 #define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
   4486 #else
   4487 #define INIT_RANDOM_R
   4488 #endif
   4489 
   4490 // FIXME: under ASan the REAL() call below may write to freed memory and corrupt
   4491 // its metadata. See
   4492 // https://github.com/google/sanitizers/issues/321.
   4493 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
   4494     SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED ||        \
   4495     SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
   4496     SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
   4497     SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
   4498     SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
   4499     SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
   4500 #define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
   4501   INTERCEPTOR(int, fn, void *attr, void *r) {                  \
   4502     void *ctx;                                                 \
   4503     COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
   4504     int res = REAL(fn)(attr, r);                               \
   4505     if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
   4506     return res;                                                \
   4507   }
   4508 #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
   4509   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
   4510 #define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
   4511   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
   4512 #define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
   4513   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
   4514 #define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
   4515   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
   4516 #define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
   4517   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
   4518 #endif
   4519 
   4520 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
   4521 INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
   4522 INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
   4523 INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
   4524 INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
   4525 INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
   4526   void *ctx;
   4527   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
   4528   // FIXME: under ASan the call below may write to freed memory and corrupt
   4529   // its metadata. See
   4530   // https://github.com/google/sanitizers/issues/321.
   4531   int res = REAL(pthread_attr_getstack)(attr, addr, size);
   4532   if (!res) {
   4533     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
   4534     if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
   4535   }
   4536   return res;
   4537 }
   4538 
   4539 // We may need to call the real pthread_attr_getstack from the run-time
   4540 // in sanitizer_common, but we don't want to include the interception headers
   4541 // there. So, just define this function here.
   4542 namespace __sanitizer {
   4543 extern "C" {
   4544 int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
   4545   return REAL(pthread_attr_getstack)(attr, addr, size);
   4546 }
   4547 }  // extern "C"
   4548 }  // namespace __sanitizer
   4549 
   4550 #define INIT_PTHREAD_ATTR_GET                             \
   4551   COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
   4552   COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
   4553   COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
   4554   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
   4555   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
   4556 #else
   4557 #define INIT_PTHREAD_ATTR_GET
   4558 #endif
   4559 
   4560 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED
   4561 INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
   4562 INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
   4563 
   4564 #define INIT_PTHREAD_ATTR_GET_SCHED                      \
   4565   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
   4566   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);
   4567 #else
   4568 #define INIT_PTHREAD_ATTR_GET_SCHED
   4569 #endif
   4570 
   4571 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
   4572 INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
   4573 
   4574 #define INIT_PTHREAD_ATTR_GETINHERITSCHED \
   4575   COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
   4576 #else
   4577 #define INIT_PTHREAD_ATTR_GETINHERITSCHED
   4578 #endif
   4579 
   4580 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
   4581 INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
   4582             void *cpuset) {
   4583   void *ctx;
   4584   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
   4585                            cpuset);
   4586   // FIXME: under ASan the call below may write to freed memory and corrupt
   4587   // its metadata. See
   4588   // https://github.com/google/sanitizers/issues/321.
   4589   int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
   4590   if (!res && cpusetsize && cpuset)
   4591     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
   4592   return res;
   4593 }
   4594 
   4595 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
   4596   COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
   4597 #else
   4598 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP
   4599 #endif
   4600 
   4601 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
   4602 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
   4603 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
   4604   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
   4605 #else
   4606 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED
   4607 #endif
   4608 
   4609 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
   4610 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
   4611 #define INIT_PTHREAD_MUTEXATTR_GETTYPE \
   4612   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
   4613 #else
   4614 #define INIT_PTHREAD_MUTEXATTR_GETTYPE
   4615 #endif
   4616 
   4617 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
   4618 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
   4619 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
   4620   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
   4621 #else
   4622 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
   4623 #endif
   4624 
   4625 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
   4626 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
   4627 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
   4628   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
   4629 #else
   4630 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
   4631 #endif
   4632 
   4633 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
   4634 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
   4635 #define INIT_PTHREAD_MUTEXATTR_GETROBUST \
   4636   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
   4637 #else
   4638 #define INIT_PTHREAD_MUTEXATTR_GETROBUST
   4639 #endif
   4640 
   4641 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
   4642 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
   4643 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
   4644   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
   4645 #else
   4646 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
   4647 #endif
   4648 
   4649 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
   4650 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
   4651 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
   4652   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
   4653 #else
   4654 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
   4655 #endif
   4656 
   4657 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
   4658 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
   4659 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
   4660   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
   4661 #else
   4662 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
   4663 #endif
   4664 
   4665 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
   4666 INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
   4667 #define INIT_PTHREAD_CONDATTR_GETPSHARED \
   4668   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
   4669 #else
   4670 #define INIT_PTHREAD_CONDATTR_GETPSHARED
   4671 #endif
   4672 
   4673 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
   4674 INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
   4675 #define INIT_PTHREAD_CONDATTR_GETCLOCK \
   4676   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
   4677 #else
   4678 #define INIT_PTHREAD_CONDATTR_GETCLOCK
   4679 #endif
   4680 
   4681 #if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
   4682 INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
   4683 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
   4684   COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
   4685 #else
   4686 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED
   4687 #endif
   4688 
   4689 #if SANITIZER_INTERCEPT_TMPNAM
   4690 INTERCEPTOR(char *, tmpnam, char *s) {
   4691   void *ctx;
   4692   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
   4693   char *res = REAL(tmpnam)(s);
   4694   if (res) {
   4695     if (s)
   4696       // FIXME: under ASan the call below may write to freed memory and corrupt
   4697       // its metadata. See
   4698       // https://github.com/google/sanitizers/issues/321.
   4699       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
   4700     else
   4701       COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   4702   }
   4703   return res;
   4704 }
   4705 #define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
   4706 #else
   4707 #define INIT_TMPNAM
   4708 #endif
   4709 
   4710 #if SANITIZER_INTERCEPT_TMPNAM_R
   4711 INTERCEPTOR(char *, tmpnam_r, char *s) {
   4712   void *ctx;
   4713   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
   4714   // FIXME: under ASan the call below may write to freed memory and corrupt
   4715   // its metadata. See
   4716   // https://github.com/google/sanitizers/issues/321.
   4717   char *res = REAL(tmpnam_r)(s);
   4718   if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
   4719   return res;
   4720 }
   4721 #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
   4722 #else
   4723 #define INIT_TMPNAM_R
   4724 #endif
   4725 
   4726 #if SANITIZER_INTERCEPT_TTYNAME_R
   4727 INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {
   4728   void *ctx;
   4729   COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);
   4730   int res = REAL(ttyname_r)(fd, name, namesize);
   4731   if (res == 0)
   4732     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
   4733   return res;
   4734 }
   4735 #define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);
   4736 #else
   4737 #define INIT_TTYNAME_R
   4738 #endif
   4739 
   4740 #if SANITIZER_INTERCEPT_TEMPNAM
   4741 INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
   4742   void *ctx;
   4743   COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
   4744   if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
   4745   if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
   4746   char *res = REAL(tempnam)(dir, pfx);
   4747   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   4748   return res;
   4749 }
   4750 #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
   4751 #else
   4752 #define INIT_TEMPNAM
   4753 #endif
   4754 
   4755 #if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD
   4756 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
   4757   void *ctx;
   4758   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
   4759   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
   4760   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
   4761   return REAL(pthread_setname_np)(thread, name);
   4762 }
   4763 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
   4764 #elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD
   4765 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {
   4766   void *ctx;
   4767   char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32
   4768   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);
   4769   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
   4770   internal_snprintf(newname, sizeof(newname), name, arg);
   4771   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);
   4772   return REAL(pthread_setname_np)(thread, name, arg);
   4773 }
   4774 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
   4775 #else
   4776 #define INIT_PTHREAD_SETNAME_NP
   4777 #endif
   4778 
   4779 #if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP
   4780 INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {
   4781   void *ctx;
   4782   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);
   4783   int res = REAL(pthread_getname_np)(thread, name, len);
   4784   if (!res)
   4785     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);
   4786   return res;
   4787 }
   4788 #define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);
   4789 #else
   4790 #define INIT_PTHREAD_GETNAME_NP
   4791 #endif
   4792 
   4793 #if SANITIZER_INTERCEPT_SINCOS
   4794 INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
   4795   void *ctx;
   4796   COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
   4797   // FIXME: under ASan the call below may write to freed memory and corrupt
   4798   // its metadata. See
   4799   // https://github.com/google/sanitizers/issues/321.
   4800   REAL(sincos)(x, sin, cos);
   4801   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
   4802   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
   4803 }
   4804 INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
   4805   void *ctx;
   4806   COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
   4807   // FIXME: under ASan the call below may write to freed memory and corrupt
   4808   // its metadata. See
   4809   // https://github.com/google/sanitizers/issues/321.
   4810   REAL(sincosf)(x, sin, cos);
   4811   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
   4812   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
   4813 }
   4814 INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
   4815   void *ctx;
   4816   COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
   4817   // FIXME: under ASan the call below may write to freed memory and corrupt
   4818   // its metadata. See
   4819   // https://github.com/google/sanitizers/issues/321.
   4820   REAL(sincosl)(x, sin, cos);
   4821   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
   4822   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
   4823 }
   4824 #define INIT_SINCOS                   \
   4825   COMMON_INTERCEPT_FUNCTION(sincos);  \
   4826   COMMON_INTERCEPT_FUNCTION(sincosf); \
   4827   COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
   4828 #else
   4829 #define INIT_SINCOS
   4830 #endif
   4831 
   4832 #if SANITIZER_INTERCEPT_REMQUO
   4833 INTERCEPTOR(double, remquo, double x, double y, int *quo) {
   4834   void *ctx;
   4835   COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
   4836   // FIXME: under ASan the call below may write to freed memory and corrupt
   4837   // its metadata. See
   4838   // https://github.com/google/sanitizers/issues/321.
   4839   double res = REAL(remquo)(x, y, quo);
   4840   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
   4841   return res;
   4842 }
   4843 INTERCEPTOR(float, remquof, float x, float y, int *quo) {
   4844   void *ctx;
   4845   COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
   4846   // FIXME: under ASan the call below may write to freed memory and corrupt
   4847   // its metadata. See
   4848   // https://github.com/google/sanitizers/issues/321.
   4849   float res = REAL(remquof)(x, y, quo);
   4850   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
   4851   return res;
   4852 }
   4853 #define INIT_REMQUO                   \
   4854   COMMON_INTERCEPT_FUNCTION(remquo);  \
   4855   COMMON_INTERCEPT_FUNCTION(remquof);
   4856 #else
   4857 #define INIT_REMQUO
   4858 #endif
   4859 
   4860 #if SANITIZER_INTERCEPT_REMQUOL
   4861 INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
   4862   void *ctx;
   4863   COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
   4864   // FIXME: under ASan the call below may write to freed memory and corrupt
   4865   // its metadata. See
   4866   // https://github.com/google/sanitizers/issues/321.
   4867   long double res = REAL(remquol)(x, y, quo);
   4868   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
   4869   return res;
   4870 }
   4871 #define INIT_REMQUOL                  \
   4872   COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
   4873 #else
   4874 #define INIT_REMQUOL
   4875 #endif
   4876 
   4877 #if SANITIZER_INTERCEPT_LGAMMA
   4878 extern int signgam;
   4879 INTERCEPTOR(double, lgamma, double x) {
   4880   void *ctx;
   4881   COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
   4882   double res = REAL(lgamma)(x);
   4883   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
   4884   return res;
   4885 }
   4886 INTERCEPTOR(float, lgammaf, float x) {
   4887   void *ctx;
   4888   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
   4889   float res = REAL(lgammaf)(x);
   4890   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
   4891   return res;
   4892 }
   4893 #define INIT_LGAMMA                   \
   4894   COMMON_INTERCEPT_FUNCTION(lgamma);  \
   4895   COMMON_INTERCEPT_FUNCTION(lgammaf);
   4896 #else
   4897 #define INIT_LGAMMA
   4898 #endif
   4899 
   4900 #if SANITIZER_INTERCEPT_LGAMMAL
   4901 INTERCEPTOR(long double, lgammal, long double x) {
   4902   void *ctx;
   4903   COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
   4904   long double res = REAL(lgammal)(x);
   4905   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
   4906   return res;
   4907 }
   4908 #define INIT_LGAMMAL                  \
   4909   COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
   4910 #else
   4911 #define INIT_LGAMMAL
   4912 #endif
   4913 
   4914 #if SANITIZER_INTERCEPT_LGAMMA_R
   4915 INTERCEPTOR(double, lgamma_r, double x, int *signp) {
   4916   void *ctx;
   4917   COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
   4918   // FIXME: under ASan the call below may write to freed memory and corrupt
   4919   // its metadata. See
   4920   // https://github.com/google/sanitizers/issues/321.
   4921   double res = REAL(lgamma_r)(x, signp);
   4922   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
   4923   return res;
   4924 }
   4925 INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
   4926   void *ctx;
   4927   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
   4928   // FIXME: under ASan the call below may write to freed memory and corrupt
   4929   // its metadata. See
   4930   // https://github.com/google/sanitizers/issues/321.
   4931   float res = REAL(lgammaf_r)(x, signp);
   4932   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
   4933   return res;
   4934 }
   4935 #define INIT_LGAMMA_R                   \
   4936   COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
   4937   COMMON_INTERCEPT_FUNCTION(lgammaf_r);
   4938 #else
   4939 #define INIT_LGAMMA_R
   4940 #endif
   4941 
   4942 #if SANITIZER_INTERCEPT_LGAMMAL_R
   4943 INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
   4944   void *ctx;
   4945   COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
   4946   // FIXME: under ASan the call below may write to freed memory and corrupt
   4947   // its metadata. See
   4948   // https://github.com/google/sanitizers/issues/321.
   4949   long double res = REAL(lgammal_r)(x, signp);
   4950   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
   4951   return res;
   4952 }
   4953 #define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
   4954 #else
   4955 #define INIT_LGAMMAL_R
   4956 #endif
   4957 
   4958 #if SANITIZER_INTERCEPT_DRAND48_R
   4959 INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
   4960   void *ctx;
   4961   COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
   4962   // FIXME: under ASan the call below may write to freed memory and corrupt
   4963   // its metadata. See
   4964   // https://github.com/google/sanitizers/issues/321.
   4965   int res = REAL(drand48_r)(buffer, result);
   4966   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   4967   return res;
   4968 }
   4969 INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
   4970   void *ctx;
   4971   COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
   4972   // FIXME: under ASan the call below may write to freed memory and corrupt
   4973   // its metadata. See
   4974   // https://github.com/google/sanitizers/issues/321.
   4975   int res = REAL(lrand48_r)(buffer, result);
   4976   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   4977   return res;
   4978 }
   4979 #define INIT_DRAND48_R                  \
   4980   COMMON_INTERCEPT_FUNCTION(drand48_r); \
   4981   COMMON_INTERCEPT_FUNCTION(lrand48_r);
   4982 #else
   4983 #define INIT_DRAND48_R
   4984 #endif
   4985 
   4986 #if SANITIZER_INTERCEPT_RAND_R
   4987 INTERCEPTOR(int, rand_r, unsigned *seedp) {
   4988   void *ctx;
   4989   COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
   4990   COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
   4991   return REAL(rand_r)(seedp);
   4992 }
   4993 #define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
   4994 #else
   4995 #define INIT_RAND_R
   4996 #endif
   4997 
   4998 #if SANITIZER_INTERCEPT_GETLINE
   4999 INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
   5000   void *ctx;
   5001   COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
   5002   // FIXME: under ASan the call below may write to freed memory and corrupt
   5003   // its metadata. See
   5004   // https://github.com/google/sanitizers/issues/321.
   5005   SSIZE_T res = REAL(getline)(lineptr, n, stream);
   5006   if (res > 0) {
   5007     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
   5008     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
   5009     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
   5010   }
   5011   return res;
   5012 }
   5013 
   5014 // FIXME: under ASan the call below may write to freed memory and corrupt its
   5015 // metadata. See
   5016 // https://github.com/google/sanitizers/issues/321.
   5017 #define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
   5018   {                                                                            \
   5019     void *ctx;                                                                 \
   5020     COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
   5021     SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
   5022     if (res > 0) {                                                             \
   5023       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
   5024       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
   5025       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
   5026     }                                                                          \
   5027     return res;                                                                \
   5028   }
   5029 
   5030 INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
   5031             void *stream)
   5032 GETDELIM_INTERCEPTOR_IMPL(__getdelim)
   5033 
   5034 // There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
   5035 // with its own body.
   5036 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
   5037             void *stream)
   5038 GETDELIM_INTERCEPTOR_IMPL(getdelim)
   5039 
   5040 #define INIT_GETLINE                     \
   5041   COMMON_INTERCEPT_FUNCTION(getline);    \
   5042   COMMON_INTERCEPT_FUNCTION(__getdelim); \
   5043   COMMON_INTERCEPT_FUNCTION(getdelim);
   5044 #else
   5045 #define INIT_GETLINE
   5046 #endif
   5047 
   5048 #if SANITIZER_INTERCEPT_ICONV
   5049 INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
   5050             char **outbuf, SIZE_T *outbytesleft) {
   5051   void *ctx;
   5052   COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
   5053                            outbytesleft);
   5054   if (inbytesleft)
   5055     COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
   5056   if (inbuf && inbytesleft)
   5057     COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
   5058   if (outbytesleft)
   5059     COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
   5060   void *outbuf_orig = outbuf ? *outbuf : nullptr;
   5061   // FIXME: under ASan the call below may write to freed memory and corrupt
   5062   // its metadata. See
   5063   // https://github.com/google/sanitizers/issues/321.
   5064   SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
   5065   if (outbuf && *outbuf > outbuf_orig) {
   5066     SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
   5067     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
   5068   }
   5069   return res;
   5070 }
   5071 #define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
   5072 #else
   5073 #define INIT_ICONV
   5074 #endif
   5075 
   5076 #if SANITIZER_INTERCEPT_TIMES
   5077 INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
   5078   void *ctx;
   5079   COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
   5080   // FIXME: under ASan the call below may write to freed memory and corrupt
   5081   // its metadata. See
   5082   // https://github.com/google/sanitizers/issues/321.
   5083   __sanitizer_clock_t res = REAL(times)(tms);
   5084   if (res != (__sanitizer_clock_t)-1 && tms)
   5085     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
   5086   return res;
   5087 }
   5088 #define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
   5089 #else
   5090 #define INIT_TIMES
   5091 #endif
   5092 
   5093 #if SANITIZER_INTERCEPT_TLS_GET_ADDR
   5094 #if !SANITIZER_S390
   5095 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
   5096 // If you see any crashes around this functions, there are 2 known issues with
   5097 // it: 1. __tls_get_addr can be called with mis-aligned stack due to:
   5098 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
   5099 // 2. It can be called recursively if sanitizer code uses __tls_get_addr
   5100 // to access thread local variables (it should not happen normally,
   5101 // because sanitizers use initial-exec tls model).
   5102 INTERCEPTOR(void *, __tls_get_addr, void *arg) {
   5103   void *ctx;
   5104   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
   5105   void *res = REAL(__tls_get_addr)(arg);
   5106   uptr tls_begin, tls_end;
   5107   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
   5108   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
   5109   if (dtv) {
   5110     // New DTLS block has been allocated.
   5111     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
   5112   }
   5113   return res;
   5114 }
   5115 #if SANITIZER_PPC
   5116 // On PowerPC, we also need to intercept __tls_get_addr_opt, which has
   5117 // mostly the same semantics as __tls_get_addr, but its presence enables
   5118 // some optimizations in linker (which are safe to ignore here).
   5119 extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
   5120                           visibility("default")))
   5121 void *__tls_get_addr_opt(void *arg);
   5122 #endif
   5123 #else // SANITIZER_S390
   5124 // On s390, we have to intercept two functions here:
   5125 // - __tls_get_addr_internal, which is a glibc-internal function that is like
   5126 //   the usual __tls_get_addr, but returns a TP-relative offset instead of
   5127 //   a proper pointer.  It is used by dlsym for TLS symbols.
   5128 // - __tls_get_offset, which is like the above, but also takes a GOT-relative
   5129 //   descriptor offset as an argument instead of a pointer.  GOT address
   5130 //   is passed in r12, so it's necessary to write it in assembly.  This is
   5131 //   the function used by the compiler.
   5132 extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
   5133 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
   5134 DEFINE_REAL(uptr, __tls_get_offset, void *arg)
   5135 extern "C" uptr __tls_get_offset(void *arg);
   5136 extern "C" uptr __interceptor___tls_get_offset(void *arg);
   5137 INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
   5138   void *ctx;
   5139   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
   5140   uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
   5141   uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
   5142   void *ptr = reinterpret_cast<void *>(res + tp);
   5143   uptr tls_begin, tls_end;
   5144   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
   5145   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
   5146   if (dtv) {
   5147     // New DTLS block has been allocated.
   5148     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
   5149   }
   5150   return res;
   5151 }
   5152 // We need a hidden symbol aliasing the above, so that we can jump
   5153 // directly to it from the assembly below.
   5154 extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
   5155                           visibility("hidden")))
   5156 uptr __tls_get_addr_hidden(void *arg);
   5157 // Now carefully intercept __tls_get_offset.
   5158 asm(
   5159   ".text\n"
   5160 // The __intercept_ version has to exist, so that gen_dynamic_list.py
   5161 // exports our symbol.
   5162   ".weak __tls_get_offset\n"
   5163   ".type __tls_get_offset, @function\n"
   5164   "__tls_get_offset:\n"
   5165   ".global __interceptor___tls_get_offset\n"
   5166   ".type __interceptor___tls_get_offset, @function\n"
   5167   "__interceptor___tls_get_offset:\n"
   5168 #ifdef __s390x__
   5169   "la %r2, 0(%r2,%r12)\n"
   5170   "jg __tls_get_addr_hidden\n"
   5171 #else
   5172   "basr %r3,0\n"
   5173   "0: la %r2,0(%r2,%r12)\n"
   5174   "l %r4,1f-0b(%r3)\n"
   5175   "b 0(%r4,%r3)\n"
   5176   "1: .long __tls_get_addr_hidden - 0b\n"
   5177 #endif
   5178   ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
   5179 // Assembly wrapper to call REAL(__tls_get_offset)(arg)
   5180   ".type __tls_get_offset_wrapper, @function\n"
   5181   "__tls_get_offset_wrapper:\n"
   5182 #ifdef __s390x__
   5183   "sgr %r2,%r12\n"
   5184 #else
   5185   "sr %r2,%r12\n"
   5186 #endif
   5187   "br %r3\n"
   5188   ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
   5189 );
   5190 #endif // SANITIZER_S390
   5191 #else
   5192 #define INIT_TLS_GET_ADDR
   5193 #endif
   5194 
   5195 #if SANITIZER_INTERCEPT_LISTXATTR
   5196 INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
   5197   void *ctx;
   5198   COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
   5199   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5200   // FIXME: under ASan the call below may write to freed memory and corrupt
   5201   // its metadata. See
   5202   // https://github.com/google/sanitizers/issues/321.
   5203   SSIZE_T res = REAL(listxattr)(path, list, size);
   5204   // Here and below, size == 0 is a special case where nothing is written to the
   5205   // buffer, and res contains the desired buffer size.
   5206   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
   5207   return res;
   5208 }
   5209 INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
   5210   void *ctx;
   5211   COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
   5212   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5213   // FIXME: under ASan the call below may write to freed memory and corrupt
   5214   // its metadata. See
   5215   // https://github.com/google/sanitizers/issues/321.
   5216   SSIZE_T res = REAL(llistxattr)(path, list, size);
   5217   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
   5218   return res;
   5219 }
   5220 INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
   5221   void *ctx;
   5222   COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
   5223   // FIXME: under ASan the call below may write to freed memory and corrupt
   5224   // its metadata. See
   5225   // https://github.com/google/sanitizers/issues/321.
   5226   SSIZE_T res = REAL(flistxattr)(fd, list, size);
   5227   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
   5228   return res;
   5229 }
   5230 #define INIT_LISTXATTR                   \
   5231   COMMON_INTERCEPT_FUNCTION(listxattr);  \
   5232   COMMON_INTERCEPT_FUNCTION(llistxattr); \
   5233   COMMON_INTERCEPT_FUNCTION(flistxattr);
   5234 #else
   5235 #define INIT_LISTXATTR
   5236 #endif
   5237 
   5238 #if SANITIZER_INTERCEPT_GETXATTR
   5239 INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
   5240             SIZE_T size) {
   5241   void *ctx;
   5242   COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
   5243   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5244   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   5245   // FIXME: under ASan the call below may write to freed memory and corrupt
   5246   // its metadata. See
   5247   // https://github.com/google/sanitizers/issues/321.
   5248   SSIZE_T res = REAL(getxattr)(path, name, value, size);
   5249   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
   5250   return res;
   5251 }
   5252 INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
   5253             SIZE_T size) {
   5254   void *ctx;
   5255   COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
   5256   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5257   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   5258   // FIXME: under ASan the call below may write to freed memory and corrupt
   5259   // its metadata. See
   5260   // https://github.com/google/sanitizers/issues/321.
   5261   SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
   5262   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
   5263   return res;
   5264 }
   5265 INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
   5266             SIZE_T size) {
   5267   void *ctx;
   5268   COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
   5269   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   5270   // FIXME: under ASan the call below may write to freed memory and corrupt
   5271   // its metadata. See
   5272   // https://github.com/google/sanitizers/issues/321.
   5273   SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
   5274   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
   5275   return res;
   5276 }
   5277 #define INIT_GETXATTR                   \
   5278   COMMON_INTERCEPT_FUNCTION(getxattr);  \
   5279   COMMON_INTERCEPT_FUNCTION(lgetxattr); \
   5280   COMMON_INTERCEPT_FUNCTION(fgetxattr);
   5281 #else
   5282 #define INIT_GETXATTR
   5283 #endif
   5284 
   5285 #if SANITIZER_INTERCEPT_GETRESID
   5286 INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
   5287   void *ctx;
   5288   COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
   5289   // FIXME: under ASan the call below may write to freed memory and corrupt
   5290   // its metadata. See
   5291   // https://github.com/google/sanitizers/issues/321.
   5292   int res = REAL(getresuid)(ruid, euid, suid);
   5293   if (res >= 0) {
   5294     if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
   5295     if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
   5296     if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
   5297   }
   5298   return res;
   5299 }
   5300 INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
   5301   void *ctx;
   5302   COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
   5303   // FIXME: under ASan the call below may write to freed memory and corrupt
   5304   // its metadata. See
   5305   // https://github.com/google/sanitizers/issues/321.
   5306   int res = REAL(getresgid)(rgid, egid, sgid);
   5307   if (res >= 0) {
   5308     if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
   5309     if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
   5310     if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
   5311   }
   5312   return res;
   5313 }
   5314 #define INIT_GETRESID                   \
   5315   COMMON_INTERCEPT_FUNCTION(getresuid); \
   5316   COMMON_INTERCEPT_FUNCTION(getresgid);
   5317 #else
   5318 #define INIT_GETRESID
   5319 #endif
   5320 
   5321 #if SANITIZER_INTERCEPT_GETIFADDRS
   5322 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
   5323 // intercept freeifaddrs(). If that ceases to be the case, we might need to
   5324 // intercept it to poison the memory again.
   5325 INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
   5326   void *ctx;
   5327   COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
   5328   // FIXME: under ASan the call below may write to freed memory and corrupt
   5329   // its metadata. See
   5330   // https://github.com/google/sanitizers/issues/321.
   5331   int res = REAL(getifaddrs)(ifap);
   5332   if (res == 0 && ifap) {
   5333     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
   5334     __sanitizer_ifaddrs *p = *ifap;
   5335     while (p) {
   5336       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
   5337       if (p->ifa_name)
   5338         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
   5339                                        REAL(strlen)(p->ifa_name) + 1);
   5340       if (p->ifa_addr)
   5341         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
   5342       if (p->ifa_netmask)
   5343         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
   5344       // On Linux this is a union, but the other member also points to a
   5345       // struct sockaddr, so the following is sufficient.
   5346       if (p->ifa_dstaddr)
   5347         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
   5348       // FIXME(smatveev): Unpoison p->ifa_data as well.
   5349       p = p->ifa_next;
   5350     }
   5351   }
   5352   return res;
   5353 }
   5354 #define INIT_GETIFADDRS                  \
   5355   COMMON_INTERCEPT_FUNCTION(getifaddrs);
   5356 #else
   5357 #define INIT_GETIFADDRS
   5358 #endif
   5359 
   5360 #if SANITIZER_INTERCEPT_IF_INDEXTONAME
   5361 INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
   5362   void *ctx;
   5363   COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
   5364   // FIXME: under ASan the call below may write to freed memory and corrupt
   5365   // its metadata. See
   5366   // https://github.com/google/sanitizers/issues/321.
   5367   char *res = REAL(if_indextoname)(ifindex, ifname);
   5368   if (res && ifname)
   5369     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
   5370   return res;
   5371 }
   5372 INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
   5373   void *ctx;
   5374   COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
   5375   if (ifname)
   5376     COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
   5377   return REAL(if_nametoindex)(ifname);
   5378 }
   5379 #define INIT_IF_INDEXTONAME                  \
   5380   COMMON_INTERCEPT_FUNCTION(if_indextoname); \
   5381   COMMON_INTERCEPT_FUNCTION(if_nametoindex);
   5382 #else
   5383 #define INIT_IF_INDEXTONAME
   5384 #endif
   5385 
   5386 #if SANITIZER_INTERCEPT_CAPGET
   5387 INTERCEPTOR(int, capget, void *hdrp, void *datap) {
   5388   void *ctx;
   5389   COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
   5390   if (hdrp)
   5391     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
   5392   // FIXME: under ASan the call below may write to freed memory and corrupt
   5393   // its metadata. See
   5394   // https://github.com/google/sanitizers/issues/321.
   5395   int res = REAL(capget)(hdrp, datap);
   5396   if (res == 0 && datap)
   5397     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
   5398   // We can also return -1 and write to hdrp->version if the version passed in
   5399   // hdrp->version is unsupported. But that's not a trivial condition to check,
   5400   // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
   5401   return res;
   5402 }
   5403 INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
   5404   void *ctx;
   5405   COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
   5406   if (hdrp)
   5407     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
   5408   if (datap)
   5409     COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
   5410   return REAL(capset)(hdrp, datap);
   5411 }
   5412 #define INIT_CAPGET                  \
   5413   COMMON_INTERCEPT_FUNCTION(capget); \
   5414   COMMON_INTERCEPT_FUNCTION(capset);
   5415 #else
   5416 #define INIT_CAPGET
   5417 #endif
   5418 
   5419 #if SANITIZER_INTERCEPT_AEABI_MEM
   5420 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
   5421   void *ctx;
   5422   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
   5423 }
   5424 
   5425 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
   5426   void *ctx;
   5427   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
   5428 }
   5429 
   5430 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
   5431   void *ctx;
   5432   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
   5433 }
   5434 
   5435 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
   5436   void *ctx;
   5437   COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
   5438 }
   5439 
   5440 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
   5441   void *ctx;
   5442   COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
   5443 }
   5444 
   5445 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
   5446   void *ctx;
   5447   COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
   5448 }
   5449 
   5450 // Note the argument order.
   5451 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
   5452   void *ctx;
   5453   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
   5454 }
   5455 
   5456 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
   5457   void *ctx;
   5458   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
   5459 }
   5460 
   5461 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
   5462   void *ctx;
   5463   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
   5464 }
   5465 
   5466 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
   5467   void *ctx;
   5468   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
   5469 }
   5470 
   5471 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
   5472   void *ctx;
   5473   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
   5474 }
   5475 
   5476 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
   5477   void *ctx;
   5478   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
   5479 }
   5480 
   5481 #define INIT_AEABI_MEM                         \
   5482   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
   5483   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
   5484   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
   5485   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
   5486   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
   5487   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
   5488   COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
   5489   COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
   5490   COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
   5491   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
   5492   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
   5493   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
   5494 #else
   5495 #define INIT_AEABI_MEM
   5496 #endif  // SANITIZER_INTERCEPT_AEABI_MEM
   5497 
   5498 #if SANITIZER_INTERCEPT___BZERO
   5499 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
   5500   void *ctx;
   5501   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
   5502 }
   5503 
   5504 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
   5505 #else
   5506 #define INIT___BZERO
   5507 #endif  // SANITIZER_INTERCEPT___BZERO
   5508 
   5509 #if SANITIZER_INTERCEPT_FTIME
   5510 INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
   5511   void *ctx;
   5512   COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
   5513   // FIXME: under ASan the call below may write to freed memory and corrupt
   5514   // its metadata. See
   5515   // https://github.com/google/sanitizers/issues/321.
   5516   int res = REAL(ftime)(tp);
   5517   if (tp)
   5518     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
   5519   return res;
   5520 }
   5521 #define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
   5522 #else
   5523 #define INIT_FTIME
   5524 #endif  // SANITIZER_INTERCEPT_FTIME
   5525 
   5526 #if SANITIZER_INTERCEPT_XDR
   5527 INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
   5528             unsigned size, int op) {
   5529   void *ctx;
   5530   COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
   5531   // FIXME: under ASan the call below may write to freed memory and corrupt
   5532   // its metadata. See
   5533   // https://github.com/google/sanitizers/issues/321.
   5534   REAL(xdrmem_create)(xdrs, addr, size, op);
   5535   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
   5536   if (op == __sanitizer_XDR_ENCODE) {
   5537     // It's not obvious how much data individual xdr_ routines write.
   5538     // Simply unpoison the entire target buffer in advance.
   5539     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
   5540   }
   5541 }
   5542 
   5543 INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
   5544   void *ctx;
   5545   COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
   5546   // FIXME: under ASan the call below may write to freed memory and corrupt
   5547   // its metadata. See
   5548   // https://github.com/google/sanitizers/issues/321.
   5549   REAL(xdrstdio_create)(xdrs, file, op);
   5550   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
   5551 }
   5552 
   5553 // FIXME: under ASan the call below may write to freed memory and corrupt
   5554 // its metadata. See
   5555 // https://github.com/google/sanitizers/issues/321.
   5556 #define XDR_INTERCEPTOR(F, T)                             \
   5557   INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
   5558     void *ctx;                                            \
   5559     COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
   5560     if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
   5561       COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
   5562     int res = REAL(F)(xdrs, p);                           \
   5563     if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
   5564       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
   5565     return res;                                           \
   5566   }
   5567 
   5568 XDR_INTERCEPTOR(xdr_short, short)
   5569 XDR_INTERCEPTOR(xdr_u_short, unsigned short)
   5570 XDR_INTERCEPTOR(xdr_int, int)
   5571 XDR_INTERCEPTOR(xdr_u_int, unsigned)
   5572 XDR_INTERCEPTOR(xdr_long, long)
   5573 XDR_INTERCEPTOR(xdr_u_long, unsigned long)
   5574 XDR_INTERCEPTOR(xdr_hyper, long long)
   5575 XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
   5576 XDR_INTERCEPTOR(xdr_longlong_t, long long)
   5577 XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
   5578 XDR_INTERCEPTOR(xdr_int8_t, u8)
   5579 XDR_INTERCEPTOR(xdr_uint8_t, u8)
   5580 XDR_INTERCEPTOR(xdr_int16_t, u16)
   5581 XDR_INTERCEPTOR(xdr_uint16_t, u16)
   5582 XDR_INTERCEPTOR(xdr_int32_t, u32)
   5583 XDR_INTERCEPTOR(xdr_uint32_t, u32)
   5584 XDR_INTERCEPTOR(xdr_int64_t, u64)
   5585 XDR_INTERCEPTOR(xdr_uint64_t, u64)
   5586 XDR_INTERCEPTOR(xdr_quad_t, long long)
   5587 XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
   5588 XDR_INTERCEPTOR(xdr_bool, bool)
   5589 XDR_INTERCEPTOR(xdr_enum, int)
   5590 XDR_INTERCEPTOR(xdr_char, char)
   5591 XDR_INTERCEPTOR(xdr_u_char, unsigned char)
   5592 XDR_INTERCEPTOR(xdr_float, float)
   5593 XDR_INTERCEPTOR(xdr_double, double)
   5594 
   5595 // FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
   5596 // wrapstring, sizeof
   5597 
   5598 INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
   5599             unsigned maxsize) {
   5600   void *ctx;
   5601   COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
   5602   if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
   5603     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
   5604     COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
   5605     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
   5606   }
   5607   // FIXME: under ASan the call below may write to freed memory and corrupt
   5608   // its metadata. See
   5609   // https://github.com/google/sanitizers/issues/321.
   5610   int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
   5611   if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
   5612     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   5613     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
   5614     if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
   5615   }
   5616   return res;
   5617 }
   5618 
   5619 INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
   5620             unsigned maxsize) {
   5621   void *ctx;
   5622   COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
   5623   if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
   5624     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
   5625     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
   5626   }
   5627   // FIXME: under ASan the call below may write to freed memory and corrupt
   5628   // its metadata. See
   5629   // https://github.com/google/sanitizers/issues/321.
   5630   int res = REAL(xdr_string)(xdrs, p, maxsize);
   5631   if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
   5632     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   5633     if (res && *p)
   5634       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
   5635   }
   5636   return res;
   5637 }
   5638 
   5639 #define INIT_XDR                               \
   5640   COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
   5641   COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
   5642   COMMON_INTERCEPT_FUNCTION(xdr_short);        \
   5643   COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
   5644   COMMON_INTERCEPT_FUNCTION(xdr_int);          \
   5645   COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
   5646   COMMON_INTERCEPT_FUNCTION(xdr_long);         \
   5647   COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
   5648   COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
   5649   COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
   5650   COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
   5651   COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
   5652   COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
   5653   COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
   5654   COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
   5655   COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
   5656   COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
   5657   COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
   5658   COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
   5659   COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
   5660   COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
   5661   COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
   5662   COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
   5663   COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
   5664   COMMON_INTERCEPT_FUNCTION(xdr_char);         \
   5665   COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
   5666   COMMON_INTERCEPT_FUNCTION(xdr_float);        \
   5667   COMMON_INTERCEPT_FUNCTION(xdr_double);       \
   5668   COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
   5669   COMMON_INTERCEPT_FUNCTION(xdr_string);
   5670 #else
   5671 #define INIT_XDR
   5672 #endif  // SANITIZER_INTERCEPT_XDR
   5673 
   5674 #if SANITIZER_INTERCEPT_TSEARCH
   5675 INTERCEPTOR(void *, tsearch, void *key, void **rootp,
   5676             int (*compar)(const void *, const void *)) {
   5677   void *ctx;
   5678   COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
   5679   // FIXME: under ASan the call below may write to freed memory and corrupt
   5680   // its metadata. See
   5681   // https://github.com/google/sanitizers/issues/321.
   5682   void *res = REAL(tsearch)(key, rootp, compar);
   5683   if (res && *(void **)res == key)
   5684     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
   5685   return res;
   5686 }
   5687 #define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
   5688 #else
   5689 #define INIT_TSEARCH
   5690 #endif
   5691 
   5692 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
   5693     SANITIZER_INTERCEPT_OPEN_MEMSTREAM
   5694 void unpoison_file(__sanitizer_FILE *fp) {
   5695 #if SANITIZER_HAS_STRUCT_FILE
   5696   COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
   5697   if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
   5698     COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
   5699                                         fp->_IO_read_end - fp->_IO_read_base);
   5700 #endif  // SANITIZER_HAS_STRUCT_FILE
   5701 }
   5702 #endif
   5703 
   5704 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS
   5705 // These guys are called when a .c source is built with -O2.
   5706 INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
   5707   void *ctx;
   5708   COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
   5709   int res = REAL(__uflow)(fp);
   5710   unpoison_file(fp);
   5711   return res;
   5712 }
   5713 INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
   5714   void *ctx;
   5715   COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
   5716   int res = REAL(__underflow)(fp);
   5717   unpoison_file(fp);
   5718   return res;
   5719 }
   5720 INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
   5721   void *ctx;
   5722   COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
   5723   int res = REAL(__overflow)(fp, ch);
   5724   unpoison_file(fp);
   5725   return res;
   5726 }
   5727 INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
   5728   void *ctx;
   5729   COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
   5730   int res = REAL(__wuflow)(fp);
   5731   unpoison_file(fp);
   5732   return res;
   5733 }
   5734 INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
   5735   void *ctx;
   5736   COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
   5737   int res = REAL(__wunderflow)(fp);
   5738   unpoison_file(fp);
   5739   return res;
   5740 }
   5741 INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
   5742   void *ctx;
   5743   COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
   5744   int res = REAL(__woverflow)(fp, ch);
   5745   unpoison_file(fp);
   5746   return res;
   5747 }
   5748 #define INIT_LIBIO_INTERNALS               \
   5749   COMMON_INTERCEPT_FUNCTION(__uflow);      \
   5750   COMMON_INTERCEPT_FUNCTION(__underflow);  \
   5751   COMMON_INTERCEPT_FUNCTION(__overflow);   \
   5752   COMMON_INTERCEPT_FUNCTION(__wuflow);     \
   5753   COMMON_INTERCEPT_FUNCTION(__wunderflow); \
   5754   COMMON_INTERCEPT_FUNCTION(__woverflow);
   5755 #else
   5756 #define INIT_LIBIO_INTERNALS
   5757 #endif
   5758 
   5759 #if SANITIZER_INTERCEPT_FOPEN
   5760 INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
   5761   void *ctx;
   5762   COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
   5763   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5764   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5765   __sanitizer_FILE *res = REAL(fopen)(path, mode);
   5766   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5767   if (res) unpoison_file(res);
   5768   return res;
   5769 }
   5770 INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
   5771   void *ctx;
   5772   COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
   5773   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5774   __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
   5775   if (res) unpoison_file(res);
   5776   return res;
   5777 }
   5778 INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
   5779             __sanitizer_FILE *fp) {
   5780   void *ctx;
   5781   COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
   5782   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5783   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5784   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   5785   __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
   5786   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5787   if (res) unpoison_file(res);
   5788   return res;
   5789 }
   5790 #define INIT_FOPEN                   \
   5791   COMMON_INTERCEPT_FUNCTION(fopen);  \
   5792   COMMON_INTERCEPT_FUNCTION(fdopen); \
   5793   COMMON_INTERCEPT_FUNCTION(freopen);
   5794 #else
   5795 #define INIT_FOPEN
   5796 #endif
   5797 
   5798 #if SANITIZER_INTERCEPT_FOPEN64
   5799 INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
   5800   void *ctx;
   5801   COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
   5802   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5803   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5804   __sanitizer_FILE *res = REAL(fopen64)(path, mode);
   5805   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5806   if (res) unpoison_file(res);
   5807   return res;
   5808 }
   5809 INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
   5810             __sanitizer_FILE *fp) {
   5811   void *ctx;
   5812   COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
   5813   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5814   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5815   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   5816   __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
   5817   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5818   if (res) unpoison_file(res);
   5819   return res;
   5820 }
   5821 #define INIT_FOPEN64                  \
   5822   COMMON_INTERCEPT_FUNCTION(fopen64); \
   5823   COMMON_INTERCEPT_FUNCTION(freopen64);
   5824 #else
   5825 #define INIT_FOPEN64
   5826 #endif
   5827 
   5828 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
   5829 INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
   5830   void *ctx;
   5831   COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
   5832   // FIXME: under ASan the call below may write to freed memory and corrupt
   5833   // its metadata. See
   5834   // https://github.com/google/sanitizers/issues/321.
   5835   __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
   5836   if (res) {
   5837     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
   5838     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
   5839     unpoison_file(res);
   5840     FileMetadata file = {ptr, sizeloc};
   5841     SetInterceptorMetadata(res, file);
   5842   }
   5843   return res;
   5844 }
   5845 INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
   5846             SIZE_T *sizeloc) {
   5847   void *ctx;
   5848   COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
   5849   __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
   5850   if (res) {
   5851     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
   5852     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
   5853     unpoison_file(res);
   5854     FileMetadata file = {(char **)ptr, sizeloc};
   5855     SetInterceptorMetadata(res, file);
   5856   }
   5857   return res;
   5858 }
   5859 INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
   5860             const char *mode) {
   5861   void *ctx;
   5862   COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
   5863   // FIXME: under ASan the call below may write to freed memory and corrupt
   5864   // its metadata. See
   5865   // https://github.com/google/sanitizers/issues/321.
   5866   __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
   5867   if (res) unpoison_file(res);
   5868   return res;
   5869 }
   5870 #define INIT_OPEN_MEMSTREAM                   \
   5871   COMMON_INTERCEPT_FUNCTION(open_memstream);  \
   5872   COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
   5873   COMMON_INTERCEPT_FUNCTION(fmemopen);
   5874 #else
   5875 #define INIT_OPEN_MEMSTREAM
   5876 #endif
   5877 
   5878 #if SANITIZER_INTERCEPT_OBSTACK
   5879 static void initialize_obstack(__sanitizer_obstack *obstack) {
   5880   COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
   5881   if (obstack->chunk)
   5882     COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
   5883                                         sizeof(*obstack->chunk));
   5884 }
   5885 
   5886 INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
   5887             int align, void *(*alloc_fn)(uptr arg, uptr sz),
   5888             void (*free_fn)(uptr arg, void *p)) {
   5889   void *ctx;
   5890   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
   5891                            free_fn);
   5892   int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
   5893   if (res) initialize_obstack(obstack);
   5894   return res;
   5895 }
   5896 INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
   5897             int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
   5898   void *ctx;
   5899   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
   5900                            free_fn);
   5901   int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
   5902   if (res) initialize_obstack(obstack);
   5903   return res;
   5904 }
   5905 INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
   5906   void *ctx;
   5907   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
   5908   REAL(_obstack_newchunk)(obstack, length);
   5909   if (obstack->chunk)
   5910     COMMON_INTERCEPTOR_INITIALIZE_RANGE(
   5911         obstack->chunk, obstack->next_free - (char *)obstack->chunk);
   5912 }
   5913 #define INIT_OBSTACK                           \
   5914   COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
   5915   COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
   5916   COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
   5917 #else
   5918 #define INIT_OBSTACK
   5919 #endif
   5920 
   5921 #if SANITIZER_INTERCEPT_FFLUSH
   5922 INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
   5923   void *ctx;
   5924   COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
   5925   int res = REAL(fflush)(fp);
   5926   // FIXME: handle fp == NULL
   5927   if (fp) {
   5928     const FileMetadata *m = GetInterceptorMetadata(fp);
   5929     if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
   5930   }
   5931   return res;
   5932 }
   5933 #define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
   5934 #else
   5935 #define INIT_FFLUSH
   5936 #endif
   5937 
   5938 #if SANITIZER_INTERCEPT_FCLOSE
   5939 INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
   5940   void *ctx;
   5941   COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
   5942   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   5943   const FileMetadata *m = GetInterceptorMetadata(fp);
   5944   int res = REAL(fclose)(fp);
   5945   if (m) {
   5946     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
   5947     DeleteInterceptorMetadata(fp);
   5948   }
   5949   return res;
   5950 }
   5951 #define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
   5952 #else
   5953 #define INIT_FCLOSE
   5954 #endif
   5955 
   5956 #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
   5957 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
   5958   void *ctx;
   5959   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
   5960   if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
   5961   COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
   5962   void *res = REAL(dlopen)(filename, flag);
   5963   Symbolizer::GetOrInit()->InvalidateModuleList();
   5964   COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
   5965   return res;
   5966 }
   5967 
   5968 INTERCEPTOR(int, dlclose, void *handle) {
   5969   void *ctx;
   5970   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
   5971   int res = REAL(dlclose)(handle);
   5972   Symbolizer::GetOrInit()->InvalidateModuleList();
   5973   COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
   5974   return res;
   5975 }
   5976 #define INIT_DLOPEN_DLCLOSE          \
   5977   COMMON_INTERCEPT_FUNCTION(dlopen); \
   5978   COMMON_INTERCEPT_FUNCTION(dlclose);
   5979 #else
   5980 #define INIT_DLOPEN_DLCLOSE
   5981 #endif
   5982 
   5983 #if SANITIZER_INTERCEPT_GETPASS
   5984 INTERCEPTOR(char *, getpass, const char *prompt) {
   5985   void *ctx;
   5986   COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
   5987   if (prompt)
   5988     COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
   5989   char *res = REAL(getpass)(prompt);
   5990   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
   5991   return res;
   5992 }
   5993 
   5994 #define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
   5995 #else
   5996 #define INIT_GETPASS
   5997 #endif
   5998 
   5999 #if SANITIZER_INTERCEPT_TIMERFD
   6000 INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
   6001             void *old_value) {
   6002   void *ctx;
   6003   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
   6004                            old_value);
   6005   COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
   6006   int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
   6007   if (res != -1 && old_value)
   6008     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
   6009   return res;
   6010 }
   6011 
   6012 INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
   6013   void *ctx;
   6014   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
   6015   int res = REAL(timerfd_gettime)(fd, curr_value);
   6016   if (res != -1 && curr_value)
   6017     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
   6018   return res;
   6019 }
   6020 #define INIT_TIMERFD                          \
   6021   COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
   6022   COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
   6023 #else
   6024 #define INIT_TIMERFD
   6025 #endif
   6026 
   6027 #if SANITIZER_INTERCEPT_MLOCKX
   6028 // Linux kernel has a bug that leads to kernel deadlock if a process
   6029 // maps TBs of memory and then calls mlock().
   6030 static void MlockIsUnsupported() {
   6031   static atomic_uint8_t printed;
   6032   if (atomic_exchange(&printed, 1, memory_order_relaxed))
   6033     return;
   6034   VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
   6035           SanitizerToolName);
   6036 }
   6037 
   6038 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
   6039   MlockIsUnsupported();
   6040   return 0;
   6041 }
   6042 
   6043 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
   6044   MlockIsUnsupported();
   6045   return 0;
   6046 }
   6047 
   6048 INTERCEPTOR(int, mlockall, int flags) {
   6049   MlockIsUnsupported();
   6050   return 0;
   6051 }
   6052 
   6053 INTERCEPTOR(int, munlockall, void) {
   6054   MlockIsUnsupported();
   6055   return 0;
   6056 }
   6057 
   6058 #define INIT_MLOCKX                                                            \
   6059   COMMON_INTERCEPT_FUNCTION(mlock);                                            \
   6060   COMMON_INTERCEPT_FUNCTION(munlock);                                          \
   6061   COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
   6062   COMMON_INTERCEPT_FUNCTION(munlockall);
   6063 
   6064 #else
   6065 #define INIT_MLOCKX
   6066 #endif  // SANITIZER_INTERCEPT_MLOCKX
   6067 
   6068 #if SANITIZER_INTERCEPT_FOPENCOOKIE
   6069 struct WrappedCookie {
   6070   void *real_cookie;
   6071   __sanitizer_cookie_io_functions_t real_io_funcs;
   6072 };
   6073 
   6074 static uptr wrapped_read(void *cookie, char *buf, uptr size) {
   6075   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   6076   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   6077   __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
   6078   return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
   6079 }
   6080 
   6081 static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
   6082   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   6083   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   6084   __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
   6085   return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
   6086 }
   6087 
   6088 static int wrapped_seek(void *cookie, u64 *offset, int whence) {
   6089   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   6090   COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
   6091   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   6092   __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
   6093   return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
   6094                    : -1;
   6095 }
   6096 
   6097 static int wrapped_close(void *cookie) {
   6098   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   6099   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   6100   __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
   6101   int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
   6102   InternalFree(wrapped_cookie);
   6103   return res;
   6104 }
   6105 
   6106 INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
   6107             __sanitizer_cookie_io_functions_t io_funcs) {
   6108   void *ctx;
   6109   COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
   6110   WrappedCookie *wrapped_cookie =
   6111       (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
   6112   wrapped_cookie->real_cookie = cookie;
   6113   wrapped_cookie->real_io_funcs = io_funcs;
   6114   __sanitizer_FILE *res =
   6115       REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
   6116                                                wrapped_seek, wrapped_close});
   6117   return res;
   6118 }
   6119 
   6120 #define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
   6121 #else
   6122 #define INIT_FOPENCOOKIE
   6123 #endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
   6124 
   6125 #if SANITIZER_INTERCEPT_SEM
   6126 INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
   6127   void *ctx;
   6128   COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
   6129   // Workaround a bug in glibc's "old" semaphore implementation by
   6130   // zero-initializing the sem_t contents. This has to be done here because
   6131   // interceptors bind to the lowest symbols version by default, hitting the
   6132   // buggy code path while the non-sanitized build of the same code works fine.
   6133   REAL(memset)(s, 0, sizeof(*s));
   6134   int res = REAL(sem_init)(s, pshared, value);
   6135   return res;
   6136 }
   6137 
   6138 INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
   6139   void *ctx;
   6140   COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
   6141   int res = REAL(sem_destroy)(s);
   6142   return res;
   6143 }
   6144 
   6145 INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
   6146   void *ctx;
   6147   COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
   6148   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
   6149   if (res == 0) {
   6150     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   6151   }
   6152   return res;
   6153 }
   6154 
   6155 INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
   6156   void *ctx;
   6157   COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
   6158   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
   6159   if (res == 0) {
   6160     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   6161   }
   6162   return res;
   6163 }
   6164 
   6165 INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
   6166   void *ctx;
   6167   COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
   6168   COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
   6169   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
   6170   if (res == 0) {
   6171     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   6172   }
   6173   return res;
   6174 }
   6175 
   6176 INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
   6177   void *ctx;
   6178   COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
   6179   COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
   6180   int res = REAL(sem_post)(s);
   6181   return res;
   6182 }
   6183 
   6184 INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
   6185   void *ctx;
   6186   COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
   6187   int res = REAL(sem_getvalue)(s, sval);
   6188   if (res == 0) {
   6189     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   6190     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
   6191   }
   6192   return res;
   6193 }
   6194 #define INIT_SEM                                                               \
   6195   COMMON_INTERCEPT_FUNCTION(sem_init);                                         \
   6196   COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \
   6197   COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \
   6198   COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \
   6199   COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \
   6200   COMMON_INTERCEPT_FUNCTION(sem_post);                                         \
   6201   COMMON_INTERCEPT_FUNCTION(sem_getvalue);
   6202 #else
   6203 #define INIT_SEM
   6204 #endif // SANITIZER_INTERCEPT_SEM
   6205 
   6206 #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
   6207 INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
   6208   void *ctx;
   6209   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
   6210   int res = REAL(pthread_setcancelstate)(state, oldstate);
   6211   if (res == 0 && oldstate != nullptr)
   6212     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
   6213   return res;
   6214 }
   6215 
   6216 INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
   6217   void *ctx;
   6218   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
   6219   int res = REAL(pthread_setcanceltype)(type, oldtype);
   6220   if (res == 0 && oldtype != nullptr)
   6221     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
   6222   return res;
   6223 }
   6224 #define INIT_PTHREAD_SETCANCEL                                                 \
   6225   COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
   6226   COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
   6227 #else
   6228 #define INIT_PTHREAD_SETCANCEL
   6229 #endif
   6230 
   6231 #if SANITIZER_INTERCEPT_MINCORE
   6232 INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
   6233   void *ctx;
   6234   COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
   6235   int res = REAL(mincore)(addr, length, vec);
   6236   if (res == 0) {
   6237     uptr page_size = GetPageSizeCached();
   6238     uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
   6239     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
   6240   }
   6241   return res;
   6242 }
   6243 #define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
   6244 #else
   6245 #define INIT_MINCORE
   6246 #endif
   6247 
   6248 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
   6249 INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
   6250             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
   6251             uptr flags) {
   6252   void *ctx;
   6253   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
   6254                            remote_iov, riovcnt, flags);
   6255   SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
   6256                                        riovcnt, flags);
   6257   if (res > 0)
   6258     write_iovec(ctx, local_iov, liovcnt, res);
   6259   return res;
   6260 }
   6261 
   6262 INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
   6263             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
   6264             uptr flags) {
   6265   void *ctx;
   6266   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
   6267                            remote_iov, riovcnt, flags);
   6268   SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
   6269                                         riovcnt, flags);
   6270   if (res > 0)
   6271     read_iovec(ctx, local_iov, liovcnt, res);
   6272   return res;
   6273 }
   6274 #define INIT_PROCESS_VM_READV                                                  \
   6275   COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
   6276   COMMON_INTERCEPT_FUNCTION(process_vm_writev);
   6277 #else
   6278 #define INIT_PROCESS_VM_READV
   6279 #endif
   6280 
   6281 #if SANITIZER_INTERCEPT_CTERMID
   6282 INTERCEPTOR(char *, ctermid, char *s) {
   6283   void *ctx;
   6284   COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
   6285   char *res = REAL(ctermid)(s);
   6286   if (res) {
   6287     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   6288   }
   6289   return res;
   6290 }
   6291 #define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
   6292 #else
   6293 #define INIT_CTERMID
   6294 #endif
   6295 
   6296 #if SANITIZER_INTERCEPT_CTERMID_R
   6297 INTERCEPTOR(char *, ctermid_r, char *s) {
   6298   void *ctx;
   6299   COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
   6300   char *res = REAL(ctermid_r)(s);
   6301   if (res) {
   6302     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   6303   }
   6304   return res;
   6305 }
   6306 #define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
   6307 #else
   6308 #define INIT_CTERMID_R
   6309 #endif
   6310 
   6311 #if SANITIZER_INTERCEPT_RECV_RECVFROM
   6312 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
   6313   void *ctx;
   6314   COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
   6315   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   6316   SSIZE_T res = REAL(recv)(fd, buf, len, flags);
   6317   if (res > 0) {
   6318     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
   6319   }
   6320   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   6321   return res;
   6322 }
   6323 
   6324 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
   6325             void *srcaddr, int *addrlen) {
   6326   void *ctx;
   6327   COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
   6328                            addrlen);
   6329   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   6330   SIZE_T srcaddr_sz;
   6331   if (srcaddr) srcaddr_sz = *addrlen;
   6332   (void)srcaddr_sz;  // prevent "set but not used" warning
   6333   SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
   6334   if (res > 0) {
   6335     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
   6336     if (srcaddr)
   6337       COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
   6338                                           Min((SIZE_T)*addrlen, srcaddr_sz));
   6339   }
   6340   return res;
   6341 }
   6342 #define INIT_RECV_RECVFROM          \
   6343   COMMON_INTERCEPT_FUNCTION(recv);  \
   6344   COMMON_INTERCEPT_FUNCTION(recvfrom);
   6345 #else
   6346 #define INIT_RECV_RECVFROM
   6347 #endif
   6348 
   6349 #if SANITIZER_INTERCEPT_SEND_SENDTO
   6350 INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
   6351   void *ctx;
   6352   COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
   6353   if (fd >= 0) {
   6354     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   6355     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   6356   }
   6357   SSIZE_T res = REAL(send)(fd, buf, len, flags);
   6358   if (common_flags()->intercept_send && res > 0)
   6359     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
   6360   return res;
   6361 }
   6362 
   6363 INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
   6364             void *dstaddr, int addrlen) {
   6365   void *ctx;
   6366   COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
   6367   if (fd >= 0) {
   6368     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   6369     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   6370   }
   6371   // Can't check dstaddr as it may have uninitialized padding at the end.
   6372   SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
   6373   if (common_flags()->intercept_send && res > 0)
   6374     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
   6375   return res;
   6376 }
   6377 #define INIT_SEND_SENDTO           \
   6378   COMMON_INTERCEPT_FUNCTION(send); \
   6379   COMMON_INTERCEPT_FUNCTION(sendto);
   6380 #else
   6381 #define INIT_SEND_SENDTO
   6382 #endif
   6383 
   6384 #if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
   6385 INTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
   6386   void *ctx;
   6387   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
   6388   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   6389   int res = REAL(eventfd_read)(fd, value);
   6390   if (res == 0) {
   6391     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
   6392     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   6393   }
   6394   return res;
   6395 }
   6396 INTERCEPTOR(int, eventfd_write, int fd, u64 value) {
   6397   void *ctx;
   6398   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
   6399   if (fd >= 0) {
   6400     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   6401     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   6402   }
   6403   int res = REAL(eventfd_write)(fd, value);
   6404   return res;
   6405 }
   6406 #define INIT_EVENTFD_READ_WRITE            \
   6407   COMMON_INTERCEPT_FUNCTION(eventfd_read); \
   6408   COMMON_INTERCEPT_FUNCTION(eventfd_write)
   6409 #else
   6410 #define INIT_EVENTFD_READ_WRITE
   6411 #endif
   6412 
   6413 #if SANITIZER_INTERCEPT_STAT
   6414 INTERCEPTOR(int, stat, const char *path, void *buf) {
   6415   void *ctx;
   6416   COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
   6417   if (common_flags()->intercept_stat)
   6418     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   6419   int res = REAL(stat)(path, buf);
   6420   if (!res)
   6421     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   6422   return res;
   6423 }
   6424 #define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
   6425 #else
   6426 #define INIT_STAT
   6427 #endif
   6428 
   6429 #if SANITIZER_INTERCEPT_LSTAT
   6430 INTERCEPTOR(int, lstat, const char *path, void *buf) {
   6431   void *ctx;
   6432   COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);
   6433   if (common_flags()->intercept_stat)
   6434     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   6435   int res = REAL(lstat)(path, buf);
   6436   if (!res)
   6437     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   6438   return res;
   6439 }
   6440 #define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)
   6441 #else
   6442 #define INIT_LSTAT
   6443 #endif
   6444 
   6445 #if SANITIZER_INTERCEPT___XSTAT
   6446 INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
   6447   void *ctx;
   6448   COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
   6449   if (common_flags()->intercept_stat)
   6450     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   6451   int res = REAL(__xstat)(version, path, buf);
   6452   if (!res)
   6453     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   6454   return res;
   6455 }
   6456 #define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
   6457 #else
   6458 #define INIT___XSTAT
   6459 #endif
   6460 
   6461 #if SANITIZER_INTERCEPT___XSTAT64
   6462 INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
   6463   void *ctx;
   6464   COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
   6465   if (common_flags()->intercept_stat)
   6466     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   6467   int res = REAL(__xstat64)(version, path, buf);
   6468   if (!res)
   6469     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
   6470   return res;
   6471 }
   6472 #define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
   6473 #else
   6474 #define INIT___XSTAT64
   6475 #endif
   6476 
   6477 #if SANITIZER_INTERCEPT___LXSTAT
   6478 INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
   6479   void *ctx;
   6480   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
   6481   if (common_flags()->intercept_stat)
   6482     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   6483   int res = REAL(__lxstat)(version, path, buf);
   6484   if (!res)
   6485     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   6486   return res;
   6487 }
   6488 #define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
   6489 #else
   6490 #define INIT___LXSTAT
   6491 #endif
   6492 
   6493 #if SANITIZER_INTERCEPT___LXSTAT64
   6494 INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
   6495   void *ctx;
   6496   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
   6497   if (common_flags()->intercept_stat)
   6498     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   6499   int res = REAL(__lxstat64)(version, path, buf);
   6500   if (!res)
   6501     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
   6502   return res;
   6503 }
   6504 #define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
   6505 #else
   6506 #define INIT___LXSTAT64
   6507 #endif
   6508 
   6509 // FIXME: add other *stat interceptor
   6510 
   6511 #if SANITIZER_INTERCEPT_UTMP
   6512 INTERCEPTOR(void *, getutent, int dummy) {
   6513   void *ctx;
   6514   COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);
   6515   void *res = REAL(getutent)(dummy);
   6516   if (res)
   6517     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
   6518   return res;
   6519 }
   6520 INTERCEPTOR(void *, getutid, void *ut) {
   6521   void *ctx;
   6522   COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);
   6523   void *res = REAL(getutid)(ut);
   6524   if (res)
   6525     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
   6526   return res;
   6527 }
   6528 INTERCEPTOR(void *, getutline, void *ut) {
   6529   void *ctx;
   6530   COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);
   6531   void *res = REAL(getutline)(ut);
   6532   if (res)
   6533     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
   6534   return res;
   6535 }
   6536 #define INIT_UTMP                      \
   6537   COMMON_INTERCEPT_FUNCTION(getutent); \
   6538   COMMON_INTERCEPT_FUNCTION(getutid);  \
   6539   COMMON_INTERCEPT_FUNCTION(getutline);
   6540 #else
   6541 #define INIT_UTMP
   6542 #endif
   6543 
   6544 #if SANITIZER_INTERCEPT_UTMPX
   6545 INTERCEPTOR(void *, getutxent, int dummy) {
   6546   void *ctx;
   6547   COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);
   6548   void *res = REAL(getutxent)(dummy);
   6549   if (res)
   6550     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
   6551   return res;
   6552 }
   6553 INTERCEPTOR(void *, getutxid, void *ut) {
   6554   void *ctx;
   6555   COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);
   6556   void *res = REAL(getutxid)(ut);
   6557   if (res)
   6558     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
   6559   return res;
   6560 }
   6561 INTERCEPTOR(void *, getutxline, void *ut) {
   6562   void *ctx;
   6563   COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);
   6564   void *res = REAL(getutxline)(ut);
   6565   if (res)
   6566     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
   6567   return res;
   6568 }
   6569 #define INIT_UTMPX                      \
   6570   COMMON_INTERCEPT_FUNCTION(getutxent); \
   6571   COMMON_INTERCEPT_FUNCTION(getutxid);  \
   6572   COMMON_INTERCEPT_FUNCTION(getutxline);
   6573 #else
   6574 #define INIT_UTMPX
   6575 #endif
   6576 
   6577 #if SANITIZER_INTERCEPT_GETLOADAVG
   6578 INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {
   6579   void *ctx;
   6580   COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);
   6581   int res = REAL(getloadavg)(loadavg, nelem);
   6582   if (res > 0)
   6583     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));
   6584   return res;
   6585 }
   6586 #define INIT_GETLOADAVG                      \
   6587   COMMON_INTERCEPT_FUNCTION(getloadavg);
   6588 #else
   6589 #define INIT_GETLOADAVG
   6590 #endif
   6591 
   6592 #if SANITIZER_INTERCEPT_MCHECK_MPROBE
   6593 INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
   6594   return 0;
   6595 }
   6596 
   6597 INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
   6598   return 0;
   6599 }
   6600 
   6601 INTERCEPTOR(int, mprobe, void *ptr) {
   6602   return 0;
   6603 }
   6604 #endif
   6605 
   6606 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
   6607   void *ctx;
   6608   COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);
   6609   SIZE_T res = REAL(wcslen)(s);
   6610   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));
   6611   return res;
   6612 }
   6613 
   6614 INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
   6615   void *ctx;
   6616   COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);
   6617   SIZE_T res = REAL(wcsnlen)(s, n);
   6618   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));
   6619   return res;
   6620 }
   6621 #define INIT_WCSLEN                  \
   6622   COMMON_INTERCEPT_FUNCTION(wcslen); \
   6623   COMMON_INTERCEPT_FUNCTION(wcsnlen);
   6624 
   6625 #if SANITIZER_INTERCEPT_WCSCAT
   6626 INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {
   6627   void *ctx;
   6628   COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);
   6629   SIZE_T src_size = REAL(wcslen)(src);
   6630   SIZE_T dst_size = REAL(wcslen)(dst);
   6631   COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));
   6632   COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
   6633   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
   6634                                  (src_size + 1) * sizeof(wchar_t));
   6635   return REAL(wcscat)(dst, src);  // NOLINT
   6636 }
   6637 
   6638 INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
   6639   void *ctx;
   6640   COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);
   6641   SIZE_T src_size = REAL(wcsnlen)(src, n);
   6642   SIZE_T dst_size = REAL(wcslen)(dst);
   6643   COMMON_INTERCEPTOR_READ_RANGE(ctx, src,
   6644                                 Min(src_size + 1, n) * sizeof(wchar_t));
   6645   COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
   6646   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
   6647                                  (src_size + 1) * sizeof(wchar_t));
   6648   return REAL(wcsncat)(dst, src, n);  // NOLINT
   6649 }
   6650 #define INIT_WCSCAT                  \
   6651   COMMON_INTERCEPT_FUNCTION(wcscat); \
   6652   COMMON_INTERCEPT_FUNCTION(wcsncat);
   6653 #else
   6654 #define INIT_WCSCAT
   6655 #endif
   6656 
   6657 #if SANITIZER_INTERCEPT_STRXFRM
   6658 static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); }
   6659 
   6660 static SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); }
   6661 
   6662 #define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...)             \
   6663   {                                                                        \
   6664     void *ctx;                                                             \
   6665     COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \
   6666     COMMON_INTERCEPTOR_READ_RANGE(ctx, src,                                \
   6667                                   sizeof(*src) * (RealStrLen(src) + 1));   \
   6668     SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__);             \
   6669     if (res < len)                                                         \
   6670       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \
   6671     return res;                                                            \
   6672   }
   6673 
   6674 INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {
   6675   STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);
   6676 }
   6677 
   6678 INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,
   6679             void *locale) {
   6680   STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);
   6681 }
   6682 
   6683 #define INIT_STRXFRM                  \
   6684   COMMON_INTERCEPT_FUNCTION(strxfrm); \
   6685   COMMON_INTERCEPT_FUNCTION(strxfrm_l);
   6686 #else
   6687 #define INIT_STRXFRM
   6688 #endif
   6689 
   6690 #if SANITIZER_INTERCEPT___STRXFRM_L
   6691 INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,
   6692             void *locale) {
   6693   STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);
   6694 }
   6695 
   6696 #define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);
   6697 #else
   6698 #define INIT___STRXFRM_L
   6699 #endif
   6700 
   6701 #if SANITIZER_INTERCEPT_WCSXFRM
   6702 INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {
   6703   STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);
   6704 }
   6705 
   6706 INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
   6707             void *locale) {
   6708   STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);
   6709 }
   6710 
   6711 #define INIT_WCSXFRM                  \
   6712   COMMON_INTERCEPT_FUNCTION(wcsxfrm); \
   6713   COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);
   6714 #else
   6715 #define INIT_WCSXFRM
   6716 #endif
   6717 
   6718 #if SANITIZER_INTERCEPT___WCSXFRM_L
   6719 INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
   6720             void *locale) {
   6721   STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);
   6722 }
   6723 
   6724 #define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);
   6725 #else
   6726 #define INIT___WCSXFRM_L
   6727 #endif
   6728 
   6729 #if SANITIZER_INTERCEPT_ACCT
   6730 INTERCEPTOR(int, acct, const char *file) {
   6731   void *ctx;
   6732   COMMON_INTERCEPTOR_ENTER(ctx, acct, file);
   6733   if (file)
   6734     COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1);
   6735   return REAL(acct)(file);
   6736 }
   6737 #define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)
   6738 #else
   6739 #define INIT_ACCT
   6740 #endif
   6741 
   6742 #if SANITIZER_INTERCEPT_USER_FROM_UID
   6743 INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {
   6744   void *ctx;
   6745   const char *user;
   6746   COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);
   6747   user = REAL(user_from_uid)(uid, nouser);
   6748   if (user)
   6749     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1);
   6750   return user;
   6751 }
   6752 #define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)
   6753 #else
   6754 #define INIT_USER_FROM_UID
   6755 #endif
   6756 
   6757 #if SANITIZER_INTERCEPT_UID_FROM_USER
   6758 INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {
   6759   void *ctx;
   6760   int res;
   6761   COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);
   6762   if (name)
   6763     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   6764   res = REAL(uid_from_user)(name, uid);
   6765   if (uid)
   6766     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));
   6767   return res;
   6768 }
   6769 #define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)
   6770 #else
   6771 #define INIT_UID_FROM_USER
   6772 #endif
   6773 
   6774 #if SANITIZER_INTERCEPT_GROUP_FROM_GID
   6775 INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {
   6776   void *ctx;
   6777   const char *group;
   6778   COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);
   6779   group = REAL(group_from_gid)(gid, nogroup);
   6780   if (group)
   6781     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1);
   6782   return group;
   6783 }
   6784 #define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)
   6785 #else
   6786 #define INIT_GROUP_FROM_GID
   6787 #endif
   6788 
   6789 #if SANITIZER_INTERCEPT_GID_FROM_GROUP
   6790 INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {
   6791   void *ctx;
   6792   int res;
   6793   COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);
   6794   if (group)
   6795     COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1);
   6796   res = REAL(gid_from_group)(group, gid);
   6797   if (gid)
   6798     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));
   6799   return res;
   6800 }
   6801 #define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)
   6802 #else
   6803 #define INIT_GID_FROM_GROUP
   6804 #endif
   6805 
   6806 #if SANITIZER_INTERCEPT_ACCESS
   6807 INTERCEPTOR(int, access, const char *path, int mode) {
   6808   void *ctx;
   6809   COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);
   6810   if (path)
   6811     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   6812   return REAL(access)(path, mode);
   6813 }
   6814 #define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)
   6815 #else
   6816 #define INIT_ACCESS
   6817 #endif
   6818 
   6819 #if SANITIZER_INTERCEPT_FACCESSAT
   6820 INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {
   6821   void *ctx;
   6822   COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);
   6823   if (path)
   6824     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   6825   return REAL(faccessat)(fd, path, mode, flags);
   6826 }
   6827 #define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)
   6828 #else
   6829 #define INIT_FACCESSAT
   6830 #endif
   6831 
   6832 #if SANITIZER_INTERCEPT_GETGROUPLIST
   6833 INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,
   6834             int *ngroups) {
   6835   void *ctx;
   6836   int res;
   6837   COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);
   6838   if (name)
   6839     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   6840   if (ngroups)
   6841     COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));
   6842   res = REAL(getgrouplist)(name, basegid, groups, ngroups);
   6843   if (!res && groups && ngroups) {
   6844     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
   6845     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
   6846   }
   6847   return res;
   6848 }
   6849 
   6850 #define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);
   6851 #else
   6852 #define INIT_GETGROUPLIST
   6853 #endif
   6854 
   6855 #if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP
   6856 INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,
   6857             int maxgrp, int *ngroups) {
   6858   void *ctx;
   6859   int res;
   6860   COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,
   6861                            maxgrp, ngroups);
   6862   if (name)
   6863     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   6864   res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);
   6865   if (!res && groups && ngroups) {
   6866     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
   6867     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
   6868   }
   6869   return res;
   6870 }
   6871 
   6872 #define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);
   6873 #else
   6874 #define INIT_GETGROUPMEMBERSHIP
   6875 #endif
   6876 
   6877 #if SANITIZER_INTERCEPT_READLINK
   6878 INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
   6879   void* ctx;
   6880   COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);
   6881   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   6882   SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
   6883   if (res > 0)
   6884     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
   6885   return res;
   6886 }
   6887 
   6888 #define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)
   6889 #else
   6890 #define INIT_READLINK
   6891 #endif
   6892 
   6893 #if SANITIZER_INTERCEPT_READLINKAT
   6894 INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,
   6895             SIZE_T bufsiz) {
   6896   void* ctx;
   6897   COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);
   6898   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   6899   SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);
   6900   if (res > 0)
   6901     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
   6902   return res;
   6903 }
   6904 
   6905 #define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)
   6906 #else
   6907 #define INIT_READLINKAT
   6908 #endif
   6909 
   6910 #if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT
   6911 INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,
   6912             struct file_handle *handle, int *mount_id, int flags) {
   6913   void* ctx;
   6914   COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,
   6915                            mount_id, flags);
   6916   COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1);
   6917 
   6918   __sanitizer_file_handle *sanitizer_handle =
   6919       reinterpret_cast<__sanitizer_file_handle*>(handle);
   6920   COMMON_INTERCEPTOR_READ_RANGE(
   6921       ctx, &sanitizer_handle->handle_bytes,
   6922       sizeof(sanitizer_handle->handle_bytes));
   6923 
   6924   int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);
   6925   if (!res) {
   6926     COMMON_INTERCEPTOR_WRITE_RANGE(
   6927         ctx, &sanitizer_handle->handle_bytes,
   6928         sizeof(sanitizer_handle->handle_bytes));
   6929     COMMON_INTERCEPTOR_WRITE_RANGE(
   6930         ctx, &sanitizer_handle->handle_type,
   6931         sizeof(sanitizer_handle->handle_type));
   6932     COMMON_INTERCEPTOR_WRITE_RANGE(
   6933         ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
   6934     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));
   6935   }
   6936   return res;
   6937 }
   6938 
   6939 #define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)
   6940 #else
   6941 #define INIT_NAME_TO_HANDLE_AT
   6942 #endif
   6943 
   6944 #if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT
   6945 INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,
   6946             int flags) {
   6947   void* ctx;
   6948   COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);
   6949 
   6950   __sanitizer_file_handle *sanitizer_handle =
   6951       reinterpret_cast<__sanitizer_file_handle*>(handle);
   6952   COMMON_INTERCEPTOR_READ_RANGE(
   6953       ctx, &sanitizer_handle->handle_bytes,
   6954       sizeof(sanitizer_handle->handle_bytes));
   6955   COMMON_INTERCEPTOR_READ_RANGE(
   6956       ctx, &sanitizer_handle->handle_type,
   6957       sizeof(sanitizer_handle->handle_type));
   6958   COMMON_INTERCEPTOR_READ_RANGE(
   6959       ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
   6960 
   6961   return REAL(open_by_handle_at)(mount_fd, handle, flags);
   6962 }
   6963 
   6964 #define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)
   6965 #else
   6966 #define INIT_OPEN_BY_HANDLE_AT
   6967 #endif
   6968 
   6969 #if SANITIZER_INTERCEPT_STRLCPY
   6970 INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {
   6971   void *ctx;
   6972   SIZE_T res;
   6973   COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);
   6974   if (src) {
   6975     // Keep strnlen as macro argument, as macro may ignore it.
   6976     COMMON_INTERCEPTOR_READ_STRING(
   6977         ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);
   6978   }
   6979   res = REAL(strlcpy)(dst, src, size);
   6980   COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1);
   6981   return res;
   6982 }
   6983 
   6984 INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {
   6985   void *ctx;
   6986   SIZE_T len = 0;
   6987   COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);
   6988   // src is checked in the strlcpy() interceptor
   6989   if (dst) {
   6990     len = internal_strnlen(dst, size);
   6991     COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);
   6992   }
   6993   // Reuse the rest of the code in the strlcpy() interceptor
   6994   return WRAP(strlcpy)(dst + len, src, size - len) + len;
   6995 }
   6996 #define INIT_STRLCPY \
   6997   COMMON_INTERCEPT_FUNCTION(strlcpy); \
   6998   COMMON_INTERCEPT_FUNCTION(strlcat);
   6999 #else
   7000 #define INIT_STRLCPY
   7001 #endif
   7002 
   7003 #if SANITIZER_INTERCEPT_MMAP
   7004 INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,
   7005             OFF_T off) {
   7006   void *ctx;
   7007   if (common_flags()->detect_write_exec)
   7008     ReportMmapWriteExec(prot);
   7009   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
   7010     return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
   7011   COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
   7012   COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);
   7013 }
   7014 
   7015 INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {
   7016   void *ctx;
   7017   if (common_flags()->detect_write_exec)
   7018     ReportMmapWriteExec(prot);
   7019   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
   7020     return (int)internal_mprotect(addr, sz, prot);
   7021   COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);
   7022   MprotectMallocZones(addr, prot);
   7023   return REAL(mprotect)(addr, sz, prot);
   7024 }
   7025 #define INIT_MMAP                                                              \
   7026   COMMON_INTERCEPT_FUNCTION(mmap);                                             \
   7027   COMMON_INTERCEPT_FUNCTION(mprotect);
   7028 #else
   7029 #define INIT_MMAP
   7030 #endif
   7031 
   7032 #if SANITIZER_INTERCEPT_MMAP64
   7033 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,
   7034             OFF64_T off) {
   7035   void *ctx;
   7036   if (common_flags()->detect_write_exec)
   7037     ReportMmapWriteExec(prot);
   7038   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
   7039     return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
   7040   COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
   7041   COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);
   7042 }
   7043 #define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);
   7044 #else
   7045 #define INIT_MMAP64
   7046 #endif
   7047 
   7048 #if SANITIZER_INTERCEPT_DEVNAME
   7049 INTERCEPTOR(char *, devname, u64 dev, u32 type) {
   7050   void *ctx;
   7051   char *name;
   7052   COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);
   7053   name = REAL(devname)(dev, type);
   7054   if (name)
   7055     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
   7056   return name;
   7057 }
   7058 #define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);
   7059 #else
   7060 #define INIT_DEVNAME
   7061 #endif
   7062 
   7063 #if SANITIZER_INTERCEPT_DEVNAME_R
   7064 #if SANITIZER_NETBSD
   7065 #define DEVNAME_R_RETTYPE int
   7066 #define DEVNAME_R_SUCCESS(x) (!(x))
   7067 #else
   7068 #define DEVNAME_R_RETTYPE char*
   7069 #define DEVNAME_R_SUCCESS(x) (x)
   7070 #endif
   7071 INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
   7072             uptr len) {
   7073   void *ctx;
   7074   COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
   7075   DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
   7076   if (DEVNAME_R_SUCCESS(res))
   7077     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1);
   7078   return res;
   7079 }
   7080 #define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);
   7081 #else
   7082 #define INIT_DEVNAME_R
   7083 #endif
   7084 
   7085 #if SANITIZER_INTERCEPT_FGETLN
   7086 INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {
   7087   void *ctx;
   7088   COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);
   7089   char *str = REAL(fgetln)(stream, len);
   7090   if (str && len) {
   7091     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
   7092     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);
   7093   }
   7094   return str;
   7095 }
   7096 #define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)
   7097 #else
   7098 #define INIT_FGETLN
   7099 #endif
   7100 
   7101 #if SANITIZER_INTERCEPT_STRMODE
   7102 INTERCEPTOR(void, strmode, u32 mode, char *bp) {
   7103   void *ctx;
   7104   COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);
   7105   REAL(strmode)(mode, bp);
   7106   if (bp)
   7107     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1);
   7108 }
   7109 #define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)
   7110 #else
   7111 #define INIT_STRMODE
   7112 #endif
   7113 
   7114 #if SANITIZER_INTERCEPT_TTYENT
   7115 INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {
   7116   void *ctx;
   7117   COMMON_INTERCEPTOR_ENTER(ctx, getttyent);
   7118   struct __sanitizer_ttyent *ttyent = REAL(getttyent)();
   7119   if (ttyent)
   7120     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
   7121   return ttyent;
   7122 }
   7123 INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {
   7124   void *ctx;
   7125   COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);
   7126   if (name)
   7127     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   7128   struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);
   7129   if (ttyent)
   7130     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
   7131   return ttyent;
   7132 }
   7133 INTERCEPTOR(int, setttyentpath, char *path) {
   7134   void *ctx;
   7135   COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);
   7136   if (path)
   7137     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   7138   return REAL(setttyentpath)(path);
   7139 }
   7140 #define INIT_TTYENT \
   7141   COMMON_INTERCEPT_FUNCTION(getttyent); \
   7142   COMMON_INTERCEPT_FUNCTION(getttynam); \
   7143   COMMON_INTERCEPT_FUNCTION(setttyentpath)
   7144 #else
   7145 #define INIT_TTYENT
   7146 #endif
   7147 
   7148 #if SANITIZER_INTERCEPT_PROTOENT
   7149 INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) {
   7150   void *ctx;
   7151   COMMON_INTERCEPTOR_ENTER(ctx, getprotoent);
   7152   struct __sanitizer_protoent *p = REAL(getprotoent)();
   7153   if (p) {
   7154     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   7155 
   7156     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
   7157 
   7158     SIZE_T pp_size = 1; // One handles the trailing \0
   7159 
   7160     for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
   7161        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
   7162 
   7163     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
   7164                                    pp_size * sizeof(char **));
   7165   }
   7166   return p;
   7167 }
   7168 
   7169 INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {
   7170   void *ctx;
   7171   COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);
   7172   if (name)
   7173     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   7174   struct __sanitizer_protoent *p = REAL(getprotobyname)(name);
   7175   if (p) {
   7176     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   7177 
   7178     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
   7179 
   7180     SIZE_T pp_size = 1; // One handles the trailing \0
   7181 
   7182     for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
   7183        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
   7184 
   7185     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
   7186                                    pp_size * sizeof(char **));
   7187   }
   7188   return p;
   7189 }
   7190 
   7191 INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
   7192   void *ctx;
   7193   COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);
   7194   struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);
   7195   if (p) {
   7196     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   7197 
   7198     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
   7199 
   7200     SIZE_T pp_size = 1; // One handles the trailing \0
   7201 
   7202     for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
   7203        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
   7204 
   7205     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
   7206                                    pp_size * sizeof(char **));
   7207   }
   7208   return p;
   7209 }
   7210 #define INIT_PROTOENT \
   7211   COMMON_INTERCEPT_FUNCTION(getprotoent); \
   7212   COMMON_INTERCEPT_FUNCTION(getprotobyname); \
   7213   COMMON_INTERCEPT_FUNCTION(getprotobynumber)
   7214 #else
   7215 #define INIT_PROTOENT
   7216 #endif
   7217 
   7218 #if SANITIZER_INTERCEPT_NETENT
   7219 INTERCEPTOR(struct __sanitizer_netent *, getnetent) {
   7220   void *ctx;
   7221   COMMON_INTERCEPTOR_ENTER(ctx, getnetent);
   7222   struct __sanitizer_netent *n = REAL(getnetent)();
   7223   if (n) {
   7224     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
   7225 
   7226     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1);
   7227 
   7228     SIZE_T nn_size = 1; // One handles the trailing \0
   7229 
   7230     for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
   7231       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1);
   7232 
   7233     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
   7234                                    nn_size * sizeof(char **));
   7235   }
   7236   return n;
   7237 }
   7238 
   7239 INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {
   7240   void *ctx;
   7241   COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);
   7242   if (name)
   7243     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   7244   struct __sanitizer_netent *n = REAL(getnetbyname)(name);
   7245   if (n) {
   7246     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
   7247 
   7248     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1);
   7249 
   7250     SIZE_T nn_size = 1; // One handles the trailing \0
   7251 
   7252     for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
   7253       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1);
   7254 
   7255     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
   7256                                    nn_size * sizeof(char **));
   7257   }
   7258   return n;
   7259 }
   7260 
   7261 INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {
   7262   void *ctx;
   7263   COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);
   7264   struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);
   7265   if (n) {
   7266     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
   7267 
   7268     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1);
   7269 
   7270     SIZE_T nn_size = 1; // One handles the trailing \0
   7271 
   7272     for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
   7273       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1);
   7274 
   7275     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
   7276                                    nn_size * sizeof(char **));
   7277   }
   7278   return n;
   7279 }
   7280 #define INIT_NETENT \
   7281   COMMON_INTERCEPT_FUNCTION(getnetent); \
   7282   COMMON_INTERCEPT_FUNCTION(getnetbyname); \
   7283   COMMON_INTERCEPT_FUNCTION(getnetbyaddr)
   7284 #else
   7285 #define INIT_NETENT
   7286 #endif
   7287 
   7288 #if SANITIZER_INTERCEPT_GETMNTINFO
   7289 INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {
   7290   void *ctx;
   7291   COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);
   7292   int cnt = REAL(getmntinfo)(mntbufp, flags);
   7293   if (cnt > 0 && mntbufp) {
   7294     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
   7295     if (*mntbufp)
   7296 #if SANITIZER_NETBSD
   7297       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);
   7298 #else
   7299       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);
   7300 #endif
   7301   }
   7302   return cnt;
   7303 }
   7304 #define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)
   7305 #else
   7306 #define INIT_GETMNTINFO
   7307 #endif
   7308 
   7309 #if SANITIZER_INTERCEPT_MI_VECTOR_HASH
   7310 INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,
   7311             u32 hashes[3]) {
   7312   void *ctx;
   7313   COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);
   7314   if (key)
   7315     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);
   7316   REAL(mi_vector_hash)(key, len, seed, hashes);
   7317   if (hashes)
   7318     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);
   7319 }
   7320 #define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)
   7321 #else
   7322 #define INIT_MI_VECTOR_HASH
   7323 #endif
   7324 
   7325 #if SANITIZER_INTERCEPT_SETVBUF
   7326 INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,
   7327   SIZE_T size) {
   7328   void *ctx;
   7329   COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);
   7330   int ret = REAL(setvbuf)(stream, buf, mode, size);
   7331   if (buf)
   7332     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
   7333   if (stream)
   7334       unpoison_file(stream);
   7335   return ret;
   7336 }
   7337 
   7338 INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {
   7339   void *ctx;
   7340   COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);
   7341   REAL(setbuf)(stream, buf);
   7342   if (buf) {
   7343     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
   7344   }
   7345   if (stream)
   7346       unpoison_file(stream);
   7347 }
   7348 
   7349 INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) {
   7350   void *ctx;
   7351   COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode);
   7352   REAL(setbuffer)(stream, buf, mode);
   7353   if (buf) {
   7354     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
   7355   }
   7356   if (stream)
   7357     unpoison_file(stream);
   7358 }
   7359 
   7360 INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {
   7361   void *ctx;
   7362   COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);
   7363   REAL(setlinebuf)(stream);
   7364   if (stream)
   7365     unpoison_file(stream);
   7366 }
   7367 #define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \
   7368     COMMON_INTERCEPT_FUNCTION(setbuf); \
   7369     COMMON_INTERCEPT_FUNCTION(setbuffer); \
   7370     COMMON_INTERCEPT_FUNCTION(setlinebuf)
   7371 #else
   7372 #define INIT_SETVBUF
   7373 #endif
   7374 
   7375 #if SANITIZER_INTERCEPT_GETVFSSTAT
   7376 INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
   7377   void *ctx;
   7378   COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
   7379   int ret = REAL(getvfsstat)(buf, bufsize, flags);
   7380   if (buf && ret > 0)
   7381     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);
   7382   return ret;
   7383 }
   7384 #define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)
   7385 #else
   7386 #define INIT_GETVFSSTAT
   7387 #endif
   7388 
   7389 #if SANITIZER_INTERCEPT_REGEX
   7390 INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {
   7391   void *ctx;
   7392   COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);
   7393   if (pattern)
   7394     COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1);
   7395   int res = REAL(regcomp)(preg, pattern, cflags);
   7396   if (!res)
   7397     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);
   7398   return res;
   7399 }
   7400 INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,
   7401             struct __sanitizer_regmatch *pmatch[], int eflags) {
   7402   void *ctx;
   7403   COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);
   7404   if (preg)
   7405     COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
   7406   if (string)
   7407     COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1);
   7408   int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);
   7409   if (!res && pmatch)
   7410     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);
   7411   return res;
   7412 }
   7413 INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,
   7414             SIZE_T errbuf_size) {
   7415   void *ctx;
   7416   COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);
   7417   if (preg)
   7418     COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
   7419   SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);
   7420   if (errbuf)
   7421     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1);
   7422   return res;
   7423 }
   7424 INTERCEPTOR(void, regfree, const void *preg) {
   7425   void *ctx;
   7426   COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);
   7427   if (preg)
   7428     COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
   7429   REAL(regfree)(preg);
   7430 }
   7431 #define INIT_REGEX                                                             \
   7432   COMMON_INTERCEPT_FUNCTION(regcomp);                                          \
   7433   COMMON_INTERCEPT_FUNCTION(regexec);                                          \
   7434   COMMON_INTERCEPT_FUNCTION(regerror);                                         \
   7435   COMMON_INTERCEPT_FUNCTION(regfree);
   7436 #else
   7437 #define INIT_REGEX
   7438 #endif
   7439 
   7440 #if SANITIZER_INTERCEPT_REGEXSUB
   7441 INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
   7442             const struct __sanitizer_regmatch *rm, const char *str) {
   7443   void *ctx;
   7444   COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);
   7445   if (sub)
   7446     COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1);
   7447   // The implementation demands and hardcodes 10 elements
   7448   if (rm)
   7449     COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
   7450   if (str)
   7451     COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
   7452   SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);
   7453   if (res > 0 && buf)
   7454     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   7455   return res;
   7456 }
   7457 INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
   7458             const struct __sanitizer_regmatch *rm, const char *sstr) {
   7459   void *ctx;
   7460   COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);
   7461   if (sub)
   7462     COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1);
   7463   // Hardcode 10 elements as this is hardcoded size
   7464   if (rm)
   7465     COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
   7466   if (sstr)
   7467     COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1);
   7468   SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);
   7469   if (res > 0 && buf) {
   7470     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));
   7471     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1);
   7472   }
   7473   return res;
   7474 }
   7475 
   7476 #define INIT_REGEXSUB                                                          \
   7477   COMMON_INTERCEPT_FUNCTION(regnsub);                                          \
   7478   COMMON_INTERCEPT_FUNCTION(regasub);
   7479 #else
   7480 #define INIT_REGEXSUB
   7481 #endif
   7482 
   7483 #if SANITIZER_INTERCEPT_FTS
   7484 INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,
   7485             int (*compar)(void **, void **)) {
   7486   void *ctx;
   7487   COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);
   7488   if (path_argv) {
   7489     for (char *const *pa = path_argv; ; ++pa) {
   7490       COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
   7491       if (!*pa)
   7492         break;
   7493       COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
   7494     }
   7495   }
   7496   // TODO(kamil): handle compar callback
   7497   void *fts = REAL(fts_open)(path_argv, options, compar);
   7498   if (fts)
   7499     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);
   7500   return fts;
   7501 }
   7502 
   7503 INTERCEPTOR(void *, fts_read, void *ftsp) {
   7504   void *ctx;
   7505   COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);
   7506   if (ftsp)
   7507     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
   7508   void *ftsent = REAL(fts_read)(ftsp);
   7509   if (ftsent)
   7510     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
   7511   return ftsent;
   7512 }
   7513 
   7514 INTERCEPTOR(void *, fts_children, void *ftsp, int options) {
   7515   void *ctx;
   7516   COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);
   7517   if (ftsp)
   7518     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
   7519   void *ftsent = REAL(fts_children)(ftsp, options);
   7520   if (ftsent)
   7521     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
   7522   return ftsent;
   7523 }
   7524 
   7525 INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {
   7526   void *ctx;
   7527   COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);
   7528   if (ftsp)
   7529     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
   7530   if (f)
   7531     COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);
   7532   return REAL(fts_set)(ftsp, f, options);
   7533 }
   7534 
   7535 INTERCEPTOR(int, fts_close, void *ftsp) {
   7536   void *ctx;
   7537   COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);
   7538   if (ftsp)
   7539     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
   7540   return REAL(fts_close)(ftsp);
   7541 }
   7542 #define INIT_FTS                                                               \
   7543   COMMON_INTERCEPT_FUNCTION(fts_open);                                         \
   7544   COMMON_INTERCEPT_FUNCTION(fts_read);                                         \
   7545   COMMON_INTERCEPT_FUNCTION(fts_children);                                     \
   7546   COMMON_INTERCEPT_FUNCTION(fts_set);                                          \
   7547   COMMON_INTERCEPT_FUNCTION(fts_close);
   7548 #else
   7549 #define INIT_FTS
   7550 #endif
   7551 
   7552 #if SANITIZER_INTERCEPT_SYSCTL
   7553 INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
   7554             SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
   7555   void *ctx;
   7556   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
   7557     return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
   7558   COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
   7559                            newlen);
   7560   if (name)
   7561     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));
   7562   if (oldlenp)
   7563     COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
   7564   if (newp && newlen)
   7565     COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
   7566   int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);
   7567   if (!res) {
   7568     if (oldlenp) {
   7569       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
   7570       if (oldp)
   7571         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
   7572     }
   7573   }
   7574   return res;
   7575 }
   7576 
   7577 INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
   7578             void *newp, SIZE_T newlen) {
   7579   void *ctx;
   7580   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
   7581     return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
   7582   COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
   7583                            newlen);
   7584   if (sname)
   7585     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
   7586   if (oldlenp)
   7587     COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
   7588   if (newp && newlen)
   7589     COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
   7590   int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);
   7591   if (!res) {
   7592     if (oldlenp) {
   7593       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
   7594       if (oldp)
   7595         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
   7596     }
   7597   }
   7598   return res;
   7599 }
   7600 
   7601 INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
   7602             SIZE_T *namelenp) {
   7603   void *ctx;
   7604   COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
   7605   if (sname)
   7606     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
   7607   if (namelenp)
   7608     COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
   7609   int res = REAL(sysctlnametomib)(sname, name, namelenp);
   7610   if (!res) {
   7611     if (namelenp) {
   7612       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
   7613       if (name)
   7614         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
   7615     }
   7616   }
   7617   return res;
   7618 }
   7619 
   7620 #define INIT_SYSCTL                        \
   7621   COMMON_INTERCEPT_FUNCTION(sysctl);       \
   7622   COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
   7623   COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
   7624 #else
   7625 #define INIT_SYSCTL
   7626 #endif
   7627 
   7628 #if SANITIZER_INTERCEPT_ASYSCTL
   7629 INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
   7630   void *ctx;
   7631   COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
   7632   if (name)
   7633     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
   7634   void *res = REAL(asysctl)(name, namelen, len);
   7635   if (res && len) {
   7636     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
   7637     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
   7638   }
   7639   return res;
   7640 }
   7641 
   7642 INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
   7643   void *ctx;
   7644   COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
   7645   if (sname)
   7646     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
   7647   void *res = REAL(asysctlbyname)(sname, len);
   7648   if (res && len) {
   7649     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
   7650     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
   7651   }
   7652   return res;
   7653 }
   7654 #define INIT_ASYSCTL                           \
   7655   COMMON_INTERCEPT_FUNCTION(asysctl);          \
   7656   COMMON_INTERCEPT_FUNCTION(asysctlbyname);
   7657 #else
   7658 #define INIT_ASYSCTL
   7659 #endif
   7660 
   7661 #if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
   7662 INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
   7663             unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
   7664             int v) {
   7665   void *ctx;
   7666   COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,
   7667                            csz, rnode, v);
   7668   if (sname)
   7669     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
   7670   if (namelenp)
   7671     COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
   7672   if (csz)
   7673     COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));
   7674   // Skip rnode, it's rarely used and not trivial to sanitize
   7675   // It's also used mostly internally
   7676   int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);
   7677   if (!res) {
   7678     if (namelenp) {
   7679       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
   7680       if (name)
   7681         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
   7682     }
   7683     if (csz) {
   7684       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));
   7685       if (cname)
   7686         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);
   7687     }
   7688   }
   7689   return res;
   7690 }
   7691 #define INIT_SYSCTLGETMIBINFO                  \
   7692   COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
   7693 #else
   7694 #define INIT_SYSCTLGETMIBINFO
   7695 #endif
   7696 
   7697 #if SANITIZER_INTERCEPT_NL_LANGINFO
   7698 INTERCEPTOR(char *, nl_langinfo, long item) {
   7699   void *ctx;
   7700   COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);
   7701   char *ret = REAL(nl_langinfo)(item);
   7702   if (ret)
   7703     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1);
   7704   return ret;
   7705 }
   7706 #define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)
   7707 #else
   7708 #define INIT_NL_LANGINFO
   7709 #endif
   7710 
   7711 #if SANITIZER_INTERCEPT_MODCTL
   7712 INTERCEPTOR(int, modctl, int operation, void *argp) {
   7713   void *ctx;
   7714   int ret;
   7715   COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);
   7716 
   7717   if (operation == modctl_load) {
   7718     if (argp) {
   7719       __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;
   7720       COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));
   7721       if (ml->ml_filename)
   7722         COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,
   7723                                       REAL(strlen)(ml->ml_filename) + 1);
   7724       if (ml->ml_props)
   7725         COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);
   7726     }
   7727     ret = REAL(modctl)(operation, argp);
   7728   } else if (operation == modctl_unload) {
   7729     if (argp) {
   7730       const char *name = (const char *)argp;
   7731       COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   7732     }
   7733     ret = REAL(modctl)(operation, argp);
   7734   } else if (operation == modctl_stat) {
   7735     uptr iov_len;
   7736     struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;
   7737     if (iov) {
   7738       COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));
   7739       iov_len = iov->iov_len;
   7740     }
   7741     ret = REAL(modctl)(operation, argp);
   7742     if (iov)
   7743       COMMON_INTERCEPTOR_WRITE_RANGE(
   7744           ctx, iov->iov_base, Min(iov_len,  iov->iov_len));
   7745   } else if (operation == modctl_exists)
   7746     ret = REAL(modctl)(operation, argp);
   7747   else
   7748     ret = REAL(modctl)(operation, argp);
   7749 
   7750   return ret;
   7751 }
   7752 #define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)
   7753 #else
   7754 #define INIT_MODCTL
   7755 #endif
   7756 
   7757 #if SANITIZER_INTERCEPT_STRTONUM
   7758 INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
   7759             long long maxval, const char **errstr) {
   7760   void *ctx;
   7761   COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
   7762 
   7763   // TODO(kamil): Implement strtoll as a common inteceptor
   7764   char *real_endptr;
   7765   long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
   7766   StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
   7767 
   7768   ret = REAL(strtonum)(nptr, minval, maxval, errstr);
   7769   if (errstr) {
   7770     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
   7771      if (*errstr)
   7772       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1);
   7773   }
   7774   return ret;
   7775 }
   7776 #define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
   7777 #else
   7778 #define INIT_STRTONUM
   7779 #endif
   7780 
   7781 #if SANITIZER_INTERCEPT_FPARSELN
   7782 INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,
   7783             SIZE_T *lineno, const char delim[3], int flags) {
   7784   void *ctx;
   7785   COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);
   7786   if (lineno)
   7787     COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));
   7788   if (delim)
   7789     COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);
   7790   char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);
   7791   if (ret) {
   7792     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1);
   7793     if (len)
   7794       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
   7795     if (lineno)
   7796       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));
   7797   }
   7798   return ret;
   7799 }
   7800 #define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)
   7801 #else
   7802 #define INIT_FPARSELN
   7803 #endif
   7804 
   7805 #if SANITIZER_INTERCEPT_STATVFS1
   7806 INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
   7807   void *ctx;
   7808   COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
   7809   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   7810   int res = REAL(statvfs1)(path, buf, flags);
   7811   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
   7812   return res;
   7813 }
   7814 INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
   7815   void *ctx;
   7816   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
   7817   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   7818   int res = REAL(fstatvfs1)(fd, buf, flags);
   7819   if (!res) {
   7820     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
   7821     if (fd >= 0)
   7822       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   7823   }
   7824   return res;
   7825 }
   7826 #define INIT_STATVFS1                  \
   7827   COMMON_INTERCEPT_FUNCTION(statvfs1);  \
   7828   COMMON_INTERCEPT_FUNCTION(fstatvfs1);
   7829 #else
   7830 #define INIT_STATVFS1
   7831 #endif
   7832 
   7833 #if SANITIZER_INTERCEPT_STRTOI
   7834 INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
   7835             INTMAX_T low, INTMAX_T high, int *rstatus) {
   7836   void *ctx;
   7837   COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
   7838   char *real_endptr;
   7839   INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
   7840   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
   7841   if (rstatus)
   7842     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
   7843   return ret;
   7844 }
   7845 
   7846 INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
   7847             UINTMAX_T low, UINTMAX_T high, int *rstatus) {
   7848   void *ctx;
   7849   COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
   7850   char *real_endptr;
   7851   UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
   7852   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
   7853   if (rstatus)
   7854     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
   7855   return ret;
   7856 }
   7857 #define INIT_STRTOI                                                            \
   7858   COMMON_INTERCEPT_FUNCTION(strtoi);                                           \
   7859   COMMON_INTERCEPT_FUNCTION(strtou)
   7860 #else
   7861 #define INIT_STRTOI
   7862 #endif
   7863 
   7864 #if SANITIZER_INTERCEPT_CAPSICUM
   7865 #define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...)          \
   7866   {                                                                        \
   7867     void *ctx;                                                             \
   7868     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
   7869     if (rights)                                                            \
   7870       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));         \
   7871     __sanitizer_cap_rights_t *ret =                                        \
   7872         REAL(cap_rights_init)(rights, ##__VA_ARGS__);                      \
   7873     if (ret)                                                               \
   7874       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));              \
   7875     return ret;                                                            \
   7876   }
   7877 
   7878 #define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...)           \
   7879   {                                                                       \
   7880     void *ctx;                                                            \
   7881     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
   7882     if (rights)                                                           \
   7883       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));        \
   7884     __sanitizer_cap_rights_t *ret =                                       \
   7885         REAL(cap_rights_set)(rights, ##__VA_ARGS__);                      \
   7886     if (ret)                                                              \
   7887       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));             \
   7888     return ret;                                                           \
   7889   }
   7890 
   7891 #define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...)         \
   7892   {                                                                         \
   7893     void *ctx;                                                              \
   7894     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
   7895     if (rights)                                                             \
   7896       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));          \
   7897     __sanitizer_cap_rights_t *ret =                                         \
   7898         REAL(cap_rights_clear)(rights, ##__VA_ARGS__);                      \
   7899     if (ret)                                                                \
   7900       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));               \
   7901     return ret;                                                             \
   7902   }
   7903 
   7904 #define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...)        \
   7905   {                                                                          \
   7906     void *ctx;                                                               \
   7907     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
   7908     if (rights)                                                              \
   7909       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));           \
   7910     return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__);                   \
   7911   }
   7912 
   7913 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
   7914             __sanitizer_cap_rights_t *rights) {
   7915   CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
   7916 }
   7917 
   7918 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
   7919             __sanitizer_cap_rights_t *rights) {
   7920   CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
   7921 }
   7922 
   7923 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
   7924             __sanitizer_cap_rights_t *rights) {
   7925   CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
   7926 }
   7927 
   7928 INTERCEPTOR(bool, cap_rights_is_set,
   7929             __sanitizer_cap_rights_t *rights) {
   7930   CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
   7931 }
   7932 
   7933 INTERCEPTOR(int, cap_rights_limit, int fd,
   7934             const __sanitizer_cap_rights_t *rights) {
   7935   void *ctx;
   7936   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);
   7937   if (rights)
   7938     COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
   7939 
   7940   return REAL(cap_rights_limit)(fd, rights);
   7941 }
   7942 
   7943 INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {
   7944   void *ctx;
   7945   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);
   7946   int ret = REAL(cap_rights_get)(fd, rights);
   7947   if (!ret && rights)
   7948     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));
   7949 
   7950   return ret;
   7951 }
   7952 
   7953 INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {
   7954   void *ctx;
   7955   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);
   7956   if (rights)
   7957     COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
   7958 
   7959   return REAL(cap_rights_is_valid(rights));
   7960 }
   7961 
   7962 INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,
   7963   __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
   7964   void *ctx;
   7965   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);
   7966   if (src)
   7967     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   7968 
   7969   __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);
   7970   if (dst)
   7971     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
   7972 
   7973   return ret;
   7974 }
   7975 
   7976 INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,
   7977   __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
   7978   void *ctx;
   7979   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);
   7980   if (src)
   7981     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   7982 
   7983   __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);
   7984   if (dst)
   7985     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
   7986 
   7987   return ret;
   7988 }
   7989 
   7990 INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,
   7991   const __sanitizer_cap_rights *little) {
   7992   void *ctx;
   7993   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);
   7994   if (little)
   7995     COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));
   7996   if (big)
   7997     COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));
   7998 
   7999   return REAL(cap_rights_contains)(big, little);
   8000 }
   8001 
   8002 INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {
   8003   void *ctx;
   8004   COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);
   8005   if (cmds)
   8006     COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);
   8007 
   8008   return REAL(cap_ioctls_limit)(fd, cmds, ncmds);
   8009 }
   8010 
   8011 INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
   8012   void *ctx;
   8013   COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);
   8014   int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);
   8015   if (!ret && cmds)
   8016     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);
   8017 
   8018   return ret;
   8019 }
   8020 #define INIT_CAPSICUM                          \
   8021   COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
   8022   COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
   8023   COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
   8024   COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
   8025   COMMON_INTERCEPT_FUNCTION(cap_rights_get);   \
   8026   COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
   8027   COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
   8028   COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \
   8029   COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \
   8030   COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \
   8031   COMMON_INTERCEPT_FUNCTION(cap_ioctls_get);   \
   8032   COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)
   8033 #else
   8034 #define INIT_CAPSICUM
   8035 #endif
   8036 
   8037 #if SANITIZER_INTERCEPT_SHA1
   8038 INTERCEPTOR(void, SHA1Init, void *context) {
   8039   void *ctx;
   8040   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);
   8041   REAL(SHA1Init)(context);
   8042   if (context)
   8043     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
   8044 }
   8045 INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {
   8046   void *ctx;
   8047   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);
   8048   if (data && len > 0)
   8049     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8050   if (context)
   8051     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
   8052   REAL(SHA1Update)(context, data, len);
   8053   if (context)
   8054     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
   8055 }
   8056 INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {
   8057   void *ctx;
   8058   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);
   8059   if (context)
   8060     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
   8061   REAL(SHA1Final)(digest, context);
   8062   if (digest)
   8063     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
   8064 }
   8065 INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {
   8066   void *ctx;
   8067   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);
   8068   if (state)
   8069     COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
   8070   if (buffer)
   8071     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);
   8072   REAL(SHA1Transform)(state, buffer);
   8073   if (state)
   8074     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
   8075 }
   8076 INTERCEPTOR(char *, SHA1End, void *context, char *buf) {
   8077   void *ctx;
   8078   COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);
   8079   if (context)
   8080     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
   8081   char *ret = REAL(SHA1End)(context, buf);
   8082   if (ret)
   8083     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
   8084   return ret;
   8085 }
   8086 INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {
   8087   void *ctx;
   8088   COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);
   8089   if (filename)
   8090     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8091   char *ret = REAL(SHA1File)(filename, buf);
   8092   if (ret)
   8093     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
   8094   return ret;
   8095 }
   8096 INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,
   8097   OFF_T length) {
   8098   void *ctx;
   8099   COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);
   8100   if (filename)
   8101     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8102   char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);
   8103   if (ret)
   8104     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
   8105   return ret;
   8106 }
   8107 INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {
   8108   void *ctx;
   8109   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);
   8110   if (data)
   8111     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8112   char *ret = REAL(SHA1Data)(data, len, buf);
   8113   if (ret)
   8114     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
   8115   return ret;
   8116 }
   8117 #define INIT_SHA1                                                              \
   8118   COMMON_INTERCEPT_FUNCTION(SHA1Init);                                         \
   8119   COMMON_INTERCEPT_FUNCTION(SHA1Update);                                       \
   8120   COMMON_INTERCEPT_FUNCTION(SHA1Final);                                        \
   8121   COMMON_INTERCEPT_FUNCTION(SHA1Transform);                                    \
   8122   COMMON_INTERCEPT_FUNCTION(SHA1End);                                          \
   8123   COMMON_INTERCEPT_FUNCTION(SHA1File);                                         \
   8124   COMMON_INTERCEPT_FUNCTION(SHA1FileChunk);                                    \
   8125   COMMON_INTERCEPT_FUNCTION(SHA1Data)
   8126 #else
   8127 #define INIT_SHA1
   8128 #endif
   8129 
   8130 #if SANITIZER_INTERCEPT_MD4
   8131 INTERCEPTOR(void, MD4Init, void *context) {
   8132   void *ctx;
   8133   COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);
   8134   REAL(MD4Init)(context);
   8135   if (context)
   8136     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
   8137 }
   8138 
   8139 INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,
   8140             unsigned int len) {
   8141   void *ctx;
   8142   COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);
   8143   if (data && len > 0)
   8144     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8145   if (context)
   8146     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
   8147   REAL(MD4Update)(context, data, len);
   8148   if (context)
   8149     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
   8150 }
   8151 
   8152 INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {
   8153   void *ctx;
   8154   COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);
   8155   if (context)
   8156     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
   8157   REAL(MD4Final)(digest, context);
   8158   if (digest)
   8159     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
   8160 }
   8161 
   8162 INTERCEPTOR(char *, MD4End, void *context, char *buf) {
   8163   void *ctx;
   8164   COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);
   8165   if (context)
   8166     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
   8167   char *ret = REAL(MD4End)(context, buf);
   8168   if (ret)
   8169     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
   8170   return ret;
   8171 }
   8172 
   8173 INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {
   8174   void *ctx;
   8175   COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);
   8176   if (filename)
   8177     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8178   char *ret = REAL(MD4File)(filename, buf);
   8179   if (ret)
   8180     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
   8181   return ret;
   8182 }
   8183 
   8184 INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,
   8185             char *buf) {
   8186   void *ctx;
   8187   COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);
   8188   if (data && len > 0)
   8189     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8190   char *ret = REAL(MD4Data)(data, len, buf);
   8191   if (ret)
   8192     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
   8193   return ret;
   8194 }
   8195 
   8196 #define INIT_MD4                                                               \
   8197   COMMON_INTERCEPT_FUNCTION(MD4Init);                                          \
   8198   COMMON_INTERCEPT_FUNCTION(MD4Update);                                        \
   8199   COMMON_INTERCEPT_FUNCTION(MD4Final);                                         \
   8200   COMMON_INTERCEPT_FUNCTION(MD4End);                                           \
   8201   COMMON_INTERCEPT_FUNCTION(MD4File);                                          \
   8202   COMMON_INTERCEPT_FUNCTION(MD4Data)
   8203 #else
   8204 #define INIT_MD4
   8205 #endif
   8206 
   8207 #if SANITIZER_INTERCEPT_RMD160
   8208 INTERCEPTOR(void, RMD160Init, void *context) {
   8209   void *ctx;
   8210   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);
   8211   REAL(RMD160Init)(context);
   8212   if (context)
   8213     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
   8214 }
   8215 INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {
   8216   void *ctx;
   8217   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);
   8218   if (data && len > 0)
   8219     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8220   if (context)
   8221     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
   8222   REAL(RMD160Update)(context, data, len);
   8223   if (context)
   8224     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
   8225 }
   8226 INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {
   8227   void *ctx;
   8228   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);
   8229   if (context)
   8230     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
   8231   REAL(RMD160Final)(digest, context);
   8232   if (digest)
   8233     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
   8234 }
   8235 INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {
   8236   void *ctx;
   8237   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);
   8238   if (state)
   8239     COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
   8240   if (buffer)
   8241     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);
   8242   REAL(RMD160Transform)(state, buffer);
   8243   if (state)
   8244     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
   8245 }
   8246 INTERCEPTOR(char *, RMD160End, void *context, char *buf) {
   8247   void *ctx;
   8248   COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);
   8249   if (context)
   8250     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
   8251   char *ret = REAL(RMD160End)(context, buf);
   8252   if (ret)
   8253     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
   8254   return ret;
   8255 }
   8256 INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {
   8257   void *ctx;
   8258   COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);
   8259   if (filename)
   8260     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8261   char *ret = REAL(RMD160File)(filename, buf);
   8262   if (ret)
   8263     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
   8264   return ret;
   8265 }
   8266 INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,
   8267   OFF_T length) {
   8268   void *ctx;
   8269   COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);
   8270   if (filename)
   8271     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8272   char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);
   8273   if (ret)
   8274     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
   8275   return ret;
   8276 }
   8277 INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {
   8278   void *ctx;
   8279   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);
   8280   if (data && len > 0)
   8281     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8282   char *ret = REAL(RMD160Data)(data, len, buf);
   8283   if (ret)
   8284     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
   8285   return ret;
   8286 }
   8287 #define INIT_RMD160                                                            \
   8288   COMMON_INTERCEPT_FUNCTION(RMD160Init);                                       \
   8289   COMMON_INTERCEPT_FUNCTION(RMD160Update);                                     \
   8290   COMMON_INTERCEPT_FUNCTION(RMD160Final);                                      \
   8291   COMMON_INTERCEPT_FUNCTION(RMD160Transform);                                  \
   8292   COMMON_INTERCEPT_FUNCTION(RMD160End);                                        \
   8293   COMMON_INTERCEPT_FUNCTION(RMD160File);                                       \
   8294   COMMON_INTERCEPT_FUNCTION(RMD160FileChunk);                                  \
   8295   COMMON_INTERCEPT_FUNCTION(RMD160Data)
   8296 #else
   8297 #define INIT_RMD160
   8298 #endif
   8299 
   8300 #if SANITIZER_INTERCEPT_MD5
   8301 INTERCEPTOR(void, MD5Init, void *context) {
   8302   void *ctx;
   8303   COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context);
   8304   REAL(MD5Init)(context);
   8305   if (context)
   8306     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
   8307 }
   8308 
   8309 INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data,
   8310             unsigned int len) {
   8311   void *ctx;
   8312   COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len);
   8313   if (data && len > 0)
   8314     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8315   if (context)
   8316     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
   8317   REAL(MD5Update)(context, data, len);
   8318   if (context)
   8319     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
   8320 }
   8321 
   8322 INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) {
   8323   void *ctx;
   8324   COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context);
   8325   if (context)
   8326     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
   8327   REAL(MD5Final)(digest, context);
   8328   if (digest)
   8329     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
   8330 }
   8331 
   8332 INTERCEPTOR(char *, MD5End, void *context, char *buf) {
   8333   void *ctx;
   8334   COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf);
   8335   if (context)
   8336     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
   8337   char *ret = REAL(MD5End)(context, buf);
   8338   if (ret)
   8339     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
   8340   return ret;
   8341 }
   8342 
   8343 INTERCEPTOR(char *, MD5File, const char *filename, char *buf) {
   8344   void *ctx;
   8345   COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf);
   8346   if (filename)
   8347     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8348   char *ret = REAL(MD5File)(filename, buf);
   8349   if (ret)
   8350     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
   8351   return ret;
   8352 }
   8353 
   8354 INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len,
   8355             char *buf) {
   8356   void *ctx;
   8357   COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf);
   8358   if (data && len > 0)
   8359     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8360   char *ret = REAL(MD5Data)(data, len, buf);
   8361   if (ret)
   8362     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
   8363   return ret;
   8364 }
   8365 
   8366 #define INIT_MD5                                                               \
   8367   COMMON_INTERCEPT_FUNCTION(MD5Init);                                          \
   8368   COMMON_INTERCEPT_FUNCTION(MD5Update);                                        \
   8369   COMMON_INTERCEPT_FUNCTION(MD5Final);                                         \
   8370   COMMON_INTERCEPT_FUNCTION(MD5End);                                           \
   8371   COMMON_INTERCEPT_FUNCTION(MD5File);                                          \
   8372   COMMON_INTERCEPT_FUNCTION(MD5Data)
   8373 #else
   8374 #define INIT_MD5
   8375 #endif
   8376 
   8377 #if SANITIZER_INTERCEPT_FSEEK
   8378 INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {
   8379   void *ctx;
   8380   COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);
   8381   return REAL(fseek)(stream, offset, whence);
   8382 }
   8383 INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {
   8384   void *ctx;
   8385   COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);
   8386   return REAL(fseeko)(stream, offset, whence);
   8387 }
   8388 INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {
   8389   void *ctx;
   8390   COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);
   8391   return REAL(ftell)(stream);
   8392 }
   8393 INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {
   8394   void *ctx;
   8395   COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);
   8396   return REAL(ftello)(stream);
   8397 }
   8398 INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {
   8399   void *ctx;
   8400   COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);
   8401   return REAL(rewind)(stream);
   8402 }
   8403 INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {
   8404   void *ctx;
   8405   COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);
   8406   int ret = REAL(fgetpos)(stream, pos);
   8407   if (pos && !ret)
   8408     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);
   8409   return ret;
   8410 }
   8411 INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {
   8412   void *ctx;
   8413   COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);
   8414   if (pos)
   8415     COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);
   8416   return REAL(fsetpos)(stream, pos);
   8417 }
   8418 #define INIT_FSEEK \
   8419   COMMON_INTERCEPT_FUNCTION(fseek); \
   8420   COMMON_INTERCEPT_FUNCTION(fseeko); \
   8421   COMMON_INTERCEPT_FUNCTION(ftell); \
   8422   COMMON_INTERCEPT_FUNCTION(ftello); \
   8423   COMMON_INTERCEPT_FUNCTION(rewind); \
   8424   COMMON_INTERCEPT_FUNCTION(fgetpos); \
   8425   COMMON_INTERCEPT_FUNCTION(fsetpos)
   8426 #else
   8427 #define INIT_FSEEK
   8428 #endif
   8429 
   8430 #if SANITIZER_INTERCEPT_MD2
   8431 INTERCEPTOR(void, MD2Init, void *context) {
   8432   void *ctx;
   8433   COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);
   8434   REAL(MD2Init)(context);
   8435   if (context)
   8436     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
   8437 }
   8438 
   8439 INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,
   8440             unsigned int len) {
   8441   void *ctx;
   8442   COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);
   8443   if (data && len > 0)
   8444     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8445   if (context)
   8446     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
   8447   REAL(MD2Update)(context, data, len);
   8448   if (context)
   8449     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
   8450 }
   8451 
   8452 INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {
   8453   void *ctx;
   8454   COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);
   8455   if (context)
   8456     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
   8457   REAL(MD2Final)(digest, context);
   8458   if (digest)
   8459     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
   8460 }
   8461 
   8462 INTERCEPTOR(char *, MD2End, void *context, char *buf) {
   8463   void *ctx;
   8464   COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);
   8465   if (context)
   8466     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
   8467   char *ret = REAL(MD2End)(context, buf);
   8468   if (ret)
   8469     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
   8470   return ret;
   8471 }
   8472 
   8473 INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {
   8474   void *ctx;
   8475   COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);
   8476   if (filename)
   8477     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
   8478   char *ret = REAL(MD2File)(filename, buf);
   8479   if (ret)
   8480     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
   8481   return ret;
   8482 }
   8483 
   8484 INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
   8485             char *buf) {
   8486   void *ctx;
   8487   COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);
   8488   if (data && len > 0)
   8489     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
   8490   char *ret = REAL(MD2Data)(data, len, buf);
   8491   if (ret)
   8492     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
   8493   return ret;
   8494 }
   8495 
   8496 #define INIT_MD2                                                               \
   8497   COMMON_INTERCEPT_FUNCTION(MD2Init);                                          \
   8498   COMMON_INTERCEPT_FUNCTION(MD2Update);                                        \
   8499   COMMON_INTERCEPT_FUNCTION(MD2Final);                                         \
   8500   COMMON_INTERCEPT_FUNCTION(MD2End);                                           \
   8501   COMMON_INTERCEPT_FUNCTION(MD2File);                                          \
   8502   COMMON_INTERCEPT_FUNCTION(MD2Data)
   8503 #else
   8504 #define INIT_MD2
   8505 #endif
   8506 
   8507 #if SANITIZER_INTERCEPT_SHA2
   8508 #define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \
   8509   INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \
   8510     void *ctx; \
   8511     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \
   8512     REAL(SHA##LEN##_Init)(context); \
   8513     if (context) \
   8514       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
   8515   } \
   8516   INTERCEPTOR(void, SHA##LEN##_Update, void *context, \
   8517               const u8 *data, SIZE_T len) { \
   8518     void *ctx; \
   8519     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \
   8520     if (data && len > 0) \
   8521       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
   8522     if (context) \
   8523       COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
   8524     REAL(SHA##LEN##_Update)(context, data, len); \
   8525     if (context) \
   8526       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
   8527   } \
   8528   INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \
   8529   void *context) { \
   8530     void *ctx; \
   8531     CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \
   8532     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \
   8533     if (context) \
   8534       COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
   8535     REAL(SHA##LEN##_Final)(digest, context); \
   8536     if (digest) \
   8537       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \
   8538                                      sizeof(digest[0]) * \
   8539   SHA##LEN##_digest_length); \
   8540   } \
   8541   INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \
   8542     void *ctx; \
   8543     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \
   8544     if (context) \
   8545       COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
   8546     char *ret = REAL(SHA##LEN##_End)(context, buf); \
   8547     if (ret) \
   8548       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
   8549     return ret; \
   8550   } \
   8551   INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \
   8552     void *ctx; \
   8553     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \
   8554     if (filename) \
   8555       COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\
   8556     char *ret = REAL(SHA##LEN##_File)(filename, buf); \
   8557     if (ret) \
   8558       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
   8559     return ret; \
   8560   } \
   8561   INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \
   8562               OFF_T offset, OFF_T length) { \
   8563     void *ctx; \
   8564     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \
   8565   length); \
   8566     if (filename) \
   8567       COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\
   8568     char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \
   8569     if (ret) \
   8570       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
   8571     return ret; \
   8572   } \
   8573   INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \
   8574     void *ctx; \
   8575     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \
   8576     if (data && len > 0) \
   8577       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
   8578     char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \
   8579     if (ret) \
   8580       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
   8581     return ret; \
   8582   }
   8583 
   8584 SHA2_INTERCEPTORS(224, u32);
   8585 SHA2_INTERCEPTORS(256, u32);
   8586 SHA2_INTERCEPTORS(384, u64);
   8587 SHA2_INTERCEPTORS(512, u64);
   8588 
   8589 #define INIT_SHA2_INTECEPTORS(LEN) \
   8590   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \
   8591   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \
   8592   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \
   8593   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \
   8594   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \
   8595   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \
   8596   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data)
   8597 
   8598 #define INIT_SHA2 \
   8599   INIT_SHA2_INTECEPTORS(224); \
   8600   INIT_SHA2_INTECEPTORS(256); \
   8601   INIT_SHA2_INTECEPTORS(384); \
   8602   INIT_SHA2_INTECEPTORS(512)
   8603 #undef SHA2_INTERCEPTORS
   8604 #else
   8605 #define INIT_SHA2
   8606 #endif
   8607 
   8608 #if SANITIZER_INTERCEPT_VIS
   8609 INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
   8610   void *ctx;
   8611   COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
   8612   char *end = REAL(vis)(dst, c, flag, nextc);
   8613   // dst is NULL terminated and end points to the NULL char
   8614   if (dst && end)
   8615     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
   8616   return end;
   8617 }
   8618 INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
   8619   void *ctx;
   8620   COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
   8621   char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
   8622   // nvis cannot make sure the dst is NULL terminated
   8623   if (dst && end)
   8624     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
   8625   return end;
   8626 }
   8627 INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
   8628   void *ctx;
   8629   COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
   8630   if (src)
   8631     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8632   int len = REAL(strvis)(dst, src, flag);
   8633   if (dst)
   8634     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
   8635   return len;
   8636 }
   8637 INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
   8638   void *ctx;
   8639   COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
   8640   if (src)
   8641     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8642   int len = REAL(stravis)(dst, src, flag);
   8643   if (dst) {
   8644     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
   8645     if (*dst)
   8646       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
   8647   }
   8648   return len;
   8649 }
   8650 INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
   8651   void *ctx;
   8652   COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
   8653   if (src)
   8654     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8655   int len = REAL(strnvis)(dst, dlen, src, flag);
   8656   // The interface will be valid even if there is no space for NULL char
   8657   if (dst && len > 0)
   8658     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
   8659   return len;
   8660 }
   8661 INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
   8662   void *ctx;
   8663   COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
   8664   if (src)
   8665     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
   8666   int ret = REAL(strvisx)(dst, src, len, flag);
   8667   if (dst)
   8668     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8669   return ret;
   8670 }
   8671 INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
   8672             int flag) {
   8673   void *ctx;
   8674   COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
   8675   if (src)
   8676     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
   8677   int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
   8678   if (dst && ret >= 0)
   8679     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8680   return ret;
   8681 }
   8682 INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
   8683             int flag, int *cerr_ptr) {
   8684   void *ctx;
   8685   COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
   8686   if (src)
   8687     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
   8688   // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
   8689   // according to the implementation
   8690   if (cerr_ptr)
   8691     COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
   8692   int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
   8693   if (dst && ret >= 0)
   8694     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8695   if (cerr_ptr)
   8696     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
   8697   return ret;
   8698 }
   8699 INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
   8700             const char *extra) {
   8701   void *ctx;
   8702   COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
   8703   if (extra)
   8704     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8705   char *end = REAL(svis)(dst, c, flag, nextc, extra);
   8706   if (dst && end)
   8707     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
   8708   return end;
   8709 }
   8710 INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
   8711             const char *extra) {
   8712   void *ctx;
   8713   COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
   8714   if (extra)
   8715     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8716   char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
   8717   if (dst && end)
   8718     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
   8719                                    Min((SIZE_T)(end - dst + 1), dlen));
   8720   return end;
   8721 }
   8722 INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
   8723             const char *extra) {
   8724   void *ctx;
   8725   COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
   8726   if (src)
   8727     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8728   if (extra)
   8729     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8730   int len = REAL(strsvis)(dst, src, flag, extra);
   8731   if (dst)
   8732     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
   8733   return len;
   8734 }
   8735 INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
   8736             const char *extra) {
   8737   void *ctx;
   8738   COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
   8739   if (src)
   8740     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8741   if (extra)
   8742     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8743   int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
   8744   // The interface will be valid even if there is no space for NULL char
   8745   if (dst && len >= 0)
   8746     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
   8747   return len;
   8748 }
   8749 INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
   8750             const char *extra) {
   8751   void *ctx;
   8752   COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
   8753   if (src)
   8754     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
   8755   if (extra)
   8756     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8757   int ret = REAL(strsvisx)(dst, src, len, flag, extra);
   8758   if (dst)
   8759     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8760   return ret;
   8761 }
   8762 INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
   8763             int flag, const char *extra) {
   8764   void *ctx;
   8765   COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
   8766   if (src)
   8767     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
   8768   if (extra)
   8769     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8770   int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
   8771   if (dst && ret >= 0)
   8772     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8773   return ret;
   8774 }
   8775 INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
   8776             SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
   8777   void *ctx;
   8778   COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
   8779                            cerr_ptr);
   8780   if (src)
   8781     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
   8782   if (extra)
   8783     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
   8784   // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
   8785   // according to the implementation
   8786   if (cerr_ptr)
   8787     COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
   8788   int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
   8789   if (dst && ret >= 0)
   8790     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8791   if (cerr_ptr)
   8792     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
   8793   return ret;
   8794 }
   8795 INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
   8796   void *ctx;
   8797   COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
   8798   if (astate)
   8799     COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
   8800   int ret = REAL(unvis)(cp, c, astate, flag);
   8801   if (ret == unvis_valid || ret == unvis_validpush) {
   8802     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
   8803   }
   8804   return ret;
   8805 }
   8806 INTERCEPTOR(int, strunvis, char *dst, const char *src) {
   8807   void *ctx;
   8808   COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
   8809   if (src)
   8810     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8811   int ret = REAL(strunvis)(dst, src);
   8812   if (ret != -1)
   8813     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8814   return ret;
   8815 }
   8816 INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
   8817   void *ctx;
   8818   COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
   8819   if (src)
   8820     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8821   int ret = REAL(strnunvis)(dst, dlen, src);
   8822   if (ret != -1)
   8823     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8824   return ret;
   8825 }
   8826 INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
   8827   void *ctx;
   8828   COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
   8829   if (src)
   8830     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8831   int ret = REAL(strunvisx)(dst, src, flag);
   8832   if (ret != -1)
   8833     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8834   return ret;
   8835 }
   8836 INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
   8837             int flag) {
   8838   void *ctx;
   8839   COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
   8840   if (src)
   8841     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
   8842   int ret = REAL(strnunvisx)(dst, dlen, src, flag);
   8843   if (ret != -1)
   8844     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
   8845   return ret;
   8846 }
   8847 #define INIT_VIS                                                               \
   8848   COMMON_INTERCEPT_FUNCTION(vis);                                              \
   8849   COMMON_INTERCEPT_FUNCTION(nvis);                                             \
   8850   COMMON_INTERCEPT_FUNCTION(strvis);                                           \
   8851   COMMON_INTERCEPT_FUNCTION(stravis);                                          \
   8852   COMMON_INTERCEPT_FUNCTION(strnvis);                                          \
   8853   COMMON_INTERCEPT_FUNCTION(strvisx);                                          \
   8854   COMMON_INTERCEPT_FUNCTION(strnvisx);                                         \
   8855   COMMON_INTERCEPT_FUNCTION(strenvisx);                                        \
   8856   COMMON_INTERCEPT_FUNCTION(svis);                                             \
   8857   COMMON_INTERCEPT_FUNCTION(snvis);                                            \
   8858   COMMON_INTERCEPT_FUNCTION(strsvis);                                          \
   8859   COMMON_INTERCEPT_FUNCTION(strsnvis);                                         \
   8860   COMMON_INTERCEPT_FUNCTION(strsvisx);                                         \
   8861   COMMON_INTERCEPT_FUNCTION(strsnvisx);                                        \
   8862   COMMON_INTERCEPT_FUNCTION(strsenvisx);                                       \
   8863   COMMON_INTERCEPT_FUNCTION(unvis);                                            \
   8864   COMMON_INTERCEPT_FUNCTION(strunvis);                                         \
   8865   COMMON_INTERCEPT_FUNCTION(strnunvis);                                        \
   8866   COMMON_INTERCEPT_FUNCTION(strunvisx);                                        \
   8867   COMMON_INTERCEPT_FUNCTION(strnunvisx)
   8868 #else
   8869 #define INIT_VIS
   8870 #endif
   8871 
   8872 #if SANITIZER_INTERCEPT_CDB
   8873 INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {
   8874   void *ctx;
   8875   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);
   8876   if (path)
   8877     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   8878   struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);
   8879   if (cdbr)
   8880     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
   8881   return cdbr;
   8882 }
   8883 
   8884 INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,
   8885   int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {
   8886   void *ctx;
   8887   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,
   8888     cookie);
   8889   if (base && size)
   8890     COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);
   8891   struct __sanitizer_cdbr *cdbr =
   8892     REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);
   8893   if (cdbr)
   8894     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
   8895   return cdbr;
   8896 }
   8897 
   8898 INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {
   8899   void *ctx;
   8900   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);
   8901   if (cdbr)
   8902     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
   8903   return REAL(cdbr_entries)(cdbr);
   8904 }
   8905 
   8906 INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,
   8907             const void **data, SIZE_T *datalen) {
   8908   void *ctx;
   8909   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);
   8910   if (cdbr)
   8911     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
   8912   int ret = REAL(cdbr_get)(cdbr, index, data, datalen);
   8913   if (!ret) {
   8914     if (data)
   8915       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
   8916     if (datalen)
   8917       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
   8918     if (data && datalen)
   8919       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
   8920   }
   8921   return ret;
   8922 }
   8923 
   8924 INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,
   8925             SIZE_T keylen, const void **data, SIZE_T *datalen) {
   8926   void *ctx;
   8927   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);
   8928   if (cdbr)
   8929     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
   8930   if (key)
   8931     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
   8932   int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);
   8933   if (!ret) {
   8934     if (data)
   8935       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
   8936     if (datalen)
   8937       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
   8938     if (data && datalen)
   8939       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
   8940   }
   8941   return ret;
   8942 }
   8943 
   8944 INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {
   8945   void *ctx;
   8946   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);
   8947   if (cdbr)
   8948     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
   8949   REAL(cdbr_close)(cdbr);
   8950 }
   8951 
   8952 INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {
   8953   void *ctx;
   8954   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);
   8955   struct __sanitizer_cdbw *ret = REAL(cdbw_open)();
   8956   if (ret)
   8957     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));
   8958   return ret;
   8959 }
   8960 
   8961 INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,
   8962   SIZE_T keylen, const void *data, SIZE_T datalen) {
   8963   void *ctx;
   8964   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);
   8965   if (cdbw)
   8966     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
   8967   if (data && datalen)
   8968     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
   8969   if (key && keylen)
   8970     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
   8971   int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);
   8972   if (!ret && cdbw)
   8973     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
   8974   return ret;
   8975 }
   8976 
   8977 INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,
   8978   SIZE_T datalen, u32 *index) {
   8979   void *ctx;
   8980   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);
   8981   if (cdbw)
   8982     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
   8983   if (data && datalen)
   8984     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
   8985   int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);
   8986   if (!ret) {
   8987     if (index)
   8988       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));
   8989     if (cdbw)
   8990       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
   8991   }
   8992   return ret;
   8993 }
   8994 
   8995 INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,
   8996   SIZE_T keylen, u32 index) {
   8997   void *ctx;
   8998   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);
   8999   if (cdbw)
   9000     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
   9001   if (key && keylen)
   9002     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
   9003   int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);
   9004   if (!ret && cdbw)
   9005     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
   9006   return ret;
   9007 }
   9008 
   9009 INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,
   9010   const char descr[16], u32 (*seedgen)(void)) {
   9011   void *ctx;
   9012   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);
   9013   COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);
   9014   if (cdbw)
   9015     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
   9016   if (descr)
   9017     COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));
   9018   if (seedgen)
   9019     COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));
   9020   int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);
   9021   if (!ret) {
   9022     if (cdbw)
   9023       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
   9024     if (output >= 0)
   9025       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);
   9026   }
   9027   return ret;
   9028 }
   9029 
   9030 INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
   9031   void *ctx;
   9032   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);
   9033   if (cdbw)
   9034     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
   9035   REAL(cdbw_close)(cdbw);
   9036 }
   9037 
   9038 #define INIT_CDB \
   9039   COMMON_INTERCEPT_FUNCTION(cdbr_open); \
   9040   COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \
   9041   COMMON_INTERCEPT_FUNCTION(cdbr_entries); \
   9042   COMMON_INTERCEPT_FUNCTION(cdbr_get); \
   9043   COMMON_INTERCEPT_FUNCTION(cdbr_find); \
   9044   COMMON_INTERCEPT_FUNCTION(cdbr_close); \
   9045   COMMON_INTERCEPT_FUNCTION(cdbw_open); \
   9046   COMMON_INTERCEPT_FUNCTION(cdbw_put); \
   9047   COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \
   9048   COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \
   9049   COMMON_INTERCEPT_FUNCTION(cdbw_output); \
   9050   COMMON_INTERCEPT_FUNCTION(cdbw_close)
   9051 #else
   9052 #define INIT_CDB
   9053 #endif
   9054 
   9055 #if SANITIZER_INTERCEPT_GETFSENT
   9056 INTERCEPTOR(void *, getfsent) {
   9057   void *ctx;
   9058   COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
   9059   void *ret = REAL(getfsent)();
   9060   if (ret)
   9061     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
   9062   return ret;
   9063 }
   9064 
   9065 INTERCEPTOR(void *, getfsspec, const char *spec) {
   9066   void *ctx;
   9067   COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
   9068   if (spec)
   9069     COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1);
   9070   void *ret = REAL(getfsspec)(spec);
   9071   if (ret)
   9072     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
   9073   return ret;
   9074 }
   9075 
   9076 INTERCEPTOR(void *, getfsfile, const char *file) {
   9077   void *ctx;
   9078   COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
   9079   if (file)
   9080     COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1);
   9081   void *ret = REAL(getfsfile)(file);
   9082   if (ret)
   9083     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
   9084   return ret;
   9085 }
   9086 
   9087 #define INIT_GETFSENT \
   9088   COMMON_INTERCEPT_FUNCTION(getfsent); \
   9089   COMMON_INTERCEPT_FUNCTION(getfsspec); \
   9090   COMMON_INTERCEPT_FUNCTION(getfsfile);
   9091 #else
   9092 #define INIT_GETFSENT
   9093 #endif
   9094 
   9095 #if SANITIZER_INTERCEPT_ARC4RANDOM
   9096 INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
   9097   void *ctx;
   9098   COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
   9099   REAL(arc4random_buf)(buf, len);
   9100   if (buf && len)
   9101     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
   9102 }
   9103 
   9104 INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
   9105   void *ctx;
   9106   COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
   9107   if (dat && datlen)
   9108     COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
   9109   REAL(arc4random_addrandom)(dat, datlen);
   9110 }
   9111 
   9112 #define INIT_ARC4RANDOM \
   9113   COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
   9114   COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
   9115 #else
   9116 #define INIT_ARC4RANDOM
   9117 #endif
   9118 
   9119 #if SANITIZER_INTERCEPT_POPEN
   9120 INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
   9121   void *ctx;
   9122   COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
   9123   if (command)
   9124     COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1);
   9125   if (type)
   9126     COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
   9127   __sanitizer_FILE *res = REAL(popen)(command, type);
   9128   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
   9129   if (res) unpoison_file(res);
   9130   return res;
   9131 }
   9132 #define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
   9133 #else
   9134 #define INIT_POPEN
   9135 #endif
   9136 
   9137 #if SANITIZER_INTERCEPT_POPENVE
   9138 INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
   9139             char *const *argv, char *const *envp, const char *type) {
   9140   void *ctx;
   9141   COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
   9142   if (path)
   9143     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   9144   if (argv) {
   9145     for (char *const *pa = argv; ; ++pa) {
   9146       COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
   9147       if (!*pa)
   9148         break;
   9149       COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
   9150     }
   9151   }
   9152   if (envp) {
   9153     for (char *const *pa = envp; ; ++pa) {
   9154       COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
   9155       if (!*pa)
   9156         break;
   9157       COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
   9158     }
   9159   }
   9160   if (type)
   9161     COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
   9162   __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
   9163   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
   9164   if (res) unpoison_file(res);
   9165   return res;
   9166 }
   9167 #define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
   9168 #else
   9169 #define INIT_POPENVE
   9170 #endif
   9171 
   9172 #if SANITIZER_INTERCEPT_PCLOSE
   9173 INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
   9174   void *ctx;
   9175   COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
   9176   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   9177   const FileMetadata *m = GetInterceptorMetadata(fp);
   9178   int res = REAL(pclose)(fp);
   9179   if (m) {
   9180     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
   9181     DeleteInterceptorMetadata(fp);
   9182   }
   9183   return res;
   9184 }
   9185 #define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
   9186 #else
   9187 #define INIT_PCLOSE
   9188 #endif
   9189 
   9190 #if SANITIZER_INTERCEPT_FUNOPEN
   9191 typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
   9192 typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
   9193 typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
   9194 typedef int (*funopen_closefn)(void *cookie);
   9195 
   9196 struct WrappedFunopenCookie {
   9197   void *real_cookie;
   9198   funopen_readfn real_read;
   9199   funopen_writefn real_write;
   9200   funopen_seekfn real_seek;
   9201   funopen_closefn real_close;
   9202 };
   9203 
   9204 static int wrapped_funopen_read(void *cookie, char *buf, int len) {
   9205   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   9206   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
   9207   funopen_readfn real_read = wrapped_cookie->real_read;
   9208   return real_read(wrapped_cookie->real_cookie, buf, len);
   9209 }
   9210 
   9211 static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
   9212   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   9213   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
   9214   funopen_writefn real_write = wrapped_cookie->real_write;
   9215   return real_write(wrapped_cookie->real_cookie, buf, len);
   9216 }
   9217 
   9218 static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
   9219   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   9220   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
   9221   funopen_seekfn real_seek = wrapped_cookie->real_seek;
   9222   return real_seek(wrapped_cookie->real_cookie, offset, whence);
   9223 }
   9224 
   9225 static int wrapped_funopen_close(void *cookie) {
   9226   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   9227   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
   9228   funopen_closefn real_close = wrapped_cookie->real_close;
   9229   int res = real_close(wrapped_cookie->real_cookie);
   9230   InternalFree(wrapped_cookie);
   9231   return res;
   9232 }
   9233 
   9234 INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
   9235             funopen_writefn writefn, funopen_seekfn seekfn,
   9236             funopen_closefn closefn) {
   9237   void *ctx;
   9238   COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
   9239                            closefn);
   9240 
   9241   WrappedFunopenCookie *wrapped_cookie =
   9242       (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
   9243   wrapped_cookie->real_cookie = cookie;
   9244   wrapped_cookie->real_read = readfn;
   9245   wrapped_cookie->real_write = writefn;
   9246   wrapped_cookie->real_seek = seekfn;
   9247   wrapped_cookie->real_close = closefn;
   9248 
   9249   __sanitizer_FILE *res =
   9250       REAL(funopen)(wrapped_cookie,
   9251                     readfn  ? wrapped_funopen_read  : nullptr,
   9252                     writefn ? wrapped_funopen_write : nullptr,
   9253                     seekfn  ? wrapped_funopen_seek  : nullptr,
   9254                     closefn ? wrapped_funopen_close : nullptr);
   9255   if (res)
   9256     unpoison_file(res);
   9257   return res;
   9258 }
   9259 #define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
   9260 #else
   9261 #define INIT_FUNOPEN
   9262 #endif
   9263 
   9264 #if SANITIZER_INTERCEPT_FUNOPEN2
   9265 typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
   9266 typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
   9267 typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
   9268 typedef int (*funopen2_flushfn)(void *cookie);
   9269 typedef int (*funopen2_closefn)(void *cookie);
   9270 
   9271 struct WrappedFunopen2Cookie {
   9272   void *real_cookie;
   9273   funopen2_readfn real_read;
   9274   funopen2_writefn real_write;
   9275   funopen2_seekfn real_seek;
   9276   funopen2_flushfn real_flush;
   9277   funopen2_closefn real_close;
   9278 };
   9279 
   9280 static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
   9281   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   9282   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
   9283   funopen2_readfn real_read = wrapped_cookie->real_read;
   9284   return real_read(wrapped_cookie->real_cookie, buf, len);
   9285 }
   9286 
   9287 static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
   9288                                       SIZE_T len) {
   9289   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   9290   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
   9291   funopen2_writefn real_write = wrapped_cookie->real_write;
   9292   return real_write(wrapped_cookie->real_cookie, buf, len);
   9293 }
   9294 
   9295 static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
   9296   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   9297   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
   9298   funopen2_seekfn real_seek = wrapped_cookie->real_seek;
   9299   return real_seek(wrapped_cookie->real_cookie, offset, whence);
   9300 }
   9301 
   9302 static int wrapped_funopen2_flush(void *cookie) {
   9303   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   9304   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
   9305   funopen2_flushfn real_flush = wrapped_cookie->real_flush;
   9306   return real_flush(wrapped_cookie->real_cookie);
   9307 }
   9308 
   9309 static int wrapped_funopen2_close(void *cookie) {
   9310   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   9311   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
   9312   funopen2_closefn real_close = wrapped_cookie->real_close;
   9313   int res = real_close(wrapped_cookie->real_cookie);
   9314   InternalFree(wrapped_cookie);
   9315   return res;
   9316 }
   9317 
   9318 INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
   9319             funopen2_writefn writefn, funopen2_seekfn seekfn,
   9320             funopen2_flushfn flushfn, funopen2_closefn closefn) {
   9321   void *ctx;
   9322   COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
   9323                            flushfn, closefn);
   9324 
   9325   WrappedFunopen2Cookie *wrapped_cookie =
   9326       (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
   9327   wrapped_cookie->real_cookie = cookie;
   9328   wrapped_cookie->real_read = readfn;
   9329   wrapped_cookie->real_write = writefn;
   9330   wrapped_cookie->real_seek = seekfn;
   9331   wrapped_cookie->real_flush = flushfn;
   9332   wrapped_cookie->real_close = closefn;
   9333 
   9334   __sanitizer_FILE *res =
   9335       REAL(funopen2)(wrapped_cookie,
   9336                      readfn  ? wrapped_funopen2_read  : nullptr,
   9337                      writefn ? wrapped_funopen2_write : nullptr,
   9338                      seekfn  ? wrapped_funopen2_seek  : nullptr,
   9339                      flushfn ? wrapped_funopen2_flush : nullptr,
   9340                      closefn ? wrapped_funopen2_close : nullptr);
   9341   if (res)
   9342     unpoison_file(res);
   9343   return res;
   9344 }
   9345 #define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
   9346 #else
   9347 #define INIT_FUNOPEN2
   9348 #endif
   9349 
   9350 static void InitializeCommonInterceptors() {
   9351   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
   9352   interceptor_metadata_map =
   9353       new ((void *)&metadata_mem) MetadataHashMap();  // NOLINT
   9354 
   9355   INIT_MMAP;
   9356   INIT_MMAP64;
   9357   INIT_TEXTDOMAIN;
   9358   INIT_STRLEN;
   9359   INIT_STRNLEN;
   9360   INIT_STRNDUP;
   9361   INIT___STRNDUP;
   9362   INIT_STRCMP;
   9363   INIT_STRNCMP;
   9364   INIT_STRCASECMP;
   9365   INIT_STRNCASECMP;
   9366   INIT_STRSTR;
   9367   INIT_STRCASESTR;
   9368   INIT_STRCHR;
   9369   INIT_STRCHRNUL;
   9370   INIT_STRRCHR;
   9371   INIT_STRSPN;
   9372   INIT_STRTOK;
   9373   INIT_STRPBRK;
   9374   INIT_STRXFRM;
   9375   INIT___STRXFRM_L;
   9376   INIT_MEMSET;
   9377   INIT_MEMMOVE;
   9378   INIT_MEMCPY;
   9379   INIT_MEMCHR;
   9380   INIT_MEMCMP;
   9381   INIT_MEMRCHR;
   9382   INIT_MEMMEM;
   9383   INIT_READ;
   9384   INIT_FREAD;
   9385   INIT_PREAD;
   9386   INIT_PREAD64;
   9387   INIT_READV;
   9388   INIT_PREADV;
   9389   INIT_PREADV64;
   9390   INIT_WRITE;
   9391   INIT_FWRITE;
   9392   INIT_PWRITE;
   9393   INIT_PWRITE64;
   9394   INIT_WRITEV;
   9395   INIT_PWRITEV;
   9396   INIT_PWRITEV64;
   9397   INIT_FGETS;
   9398   INIT_FPUTS;
   9399   INIT_PUTS;
   9400   INIT_PRCTL;
   9401   INIT_LOCALTIME_AND_FRIENDS;
   9402   INIT_STRPTIME;
   9403   INIT_SCANF;
   9404   INIT_ISOC99_SCANF;
   9405   INIT_PRINTF;
   9406   INIT_PRINTF_L;
   9407   INIT_ISOC99_PRINTF;
   9408   INIT_FREXP;
   9409   INIT_FREXPF_FREXPL;
   9410   INIT_GETPWNAM_AND_FRIENDS;
   9411   INIT_GETPWNAM_R_AND_FRIENDS;
   9412   INIT_GETPWENT;
   9413   INIT_FGETPWENT;
   9414   INIT_GETPWENT_R;
   9415   INIT_FGETPWENT_R;
   9416   INIT_FGETGRENT_R;
   9417   INIT_SETPWENT;
   9418   INIT_CLOCK_GETTIME;
   9419   INIT_GETITIMER;
   9420   INIT_TIME;
   9421   INIT_GLOB;
   9422   INIT_GLOB64;
   9423   INIT_WAIT;
   9424   INIT_WAIT4;
   9425   INIT_INET;
   9426   INIT_PTHREAD_GETSCHEDPARAM;
   9427   INIT_GETADDRINFO;
   9428   INIT_GETNAMEINFO;
   9429   INIT_GETSOCKNAME;
   9430   INIT_GETHOSTBYNAME;
   9431   INIT_GETHOSTBYNAME2;
   9432   INIT_GETHOSTBYNAME_R;
   9433   INIT_GETHOSTBYNAME2_R;
   9434   INIT_GETHOSTBYADDR_R;
   9435   INIT_GETHOSTENT_R;
   9436   INIT_GETSOCKOPT;
   9437   INIT_ACCEPT;
   9438   INIT_ACCEPT4;
   9439   INIT_PACCEPT;
   9440   INIT_MODF;
   9441   INIT_RECVMSG;
   9442   INIT_SENDMSG;
   9443   INIT_RECVMMSG;
   9444   INIT_SENDMMSG;
   9445   INIT_GETPEERNAME;
   9446   INIT_IOCTL;
   9447   INIT_INET_ATON;
   9448   INIT_SYSINFO;
   9449   INIT_READDIR;
   9450   INIT_READDIR64;
   9451   INIT_PTRACE;
   9452   INIT_SETLOCALE;
   9453   INIT_GETCWD;
   9454   INIT_GET_CURRENT_DIR_NAME;
   9455   INIT_STRTOIMAX;
   9456   INIT_MBSTOWCS;
   9457   INIT_MBSNRTOWCS;
   9458   INIT_WCSTOMBS;
   9459   INIT_WCSNRTOMBS;
   9460   INIT_WCRTOMB;
   9461   INIT_TCGETATTR;
   9462   INIT_REALPATH;
   9463   INIT_CANONICALIZE_FILE_NAME;
   9464   INIT_CONFSTR;
   9465   INIT_SCHED_GETAFFINITY;
   9466   INIT_SCHED_GETPARAM;
   9467   INIT_STRERROR;
   9468   INIT_STRERROR_R;
   9469   INIT_XPG_STRERROR_R;
   9470   INIT_SCANDIR;
   9471   INIT_SCANDIR64;
   9472   INIT_GETGROUPS;
   9473   INIT_POLL;
   9474   INIT_PPOLL;
   9475   INIT_WORDEXP;
   9476   INIT_SIGWAIT;
   9477   INIT_SIGWAITINFO;
   9478   INIT_SIGTIMEDWAIT;
   9479   INIT_SIGSETOPS;
   9480   INIT_SIGPENDING;
   9481   INIT_SIGPROCMASK;
   9482   INIT_BACKTRACE;
   9483   INIT__EXIT;
   9484   INIT_PTHREAD_MUTEX_LOCK;
   9485   INIT_PTHREAD_MUTEX_UNLOCK;
   9486   INIT___PTHREAD_MUTEX_LOCK;
   9487   INIT___PTHREAD_MUTEX_UNLOCK;
   9488   INIT___LIBC_MUTEX_LOCK;
   9489   INIT___LIBC_MUTEX_UNLOCK;
   9490   INIT___LIBC_THR_SETCANCELSTATE;
   9491   INIT_GETMNTENT;
   9492   INIT_GETMNTENT_R;
   9493   INIT_STATFS;
   9494   INIT_STATFS64;
   9495   INIT_STATVFS;
   9496   INIT_STATVFS64;
   9497   INIT_INITGROUPS;
   9498   INIT_ETHER_NTOA_ATON;
   9499   INIT_ETHER_HOST;
   9500   INIT_ETHER_R;
   9501   INIT_SHMCTL;
   9502   INIT_RANDOM_R;
   9503   INIT_PTHREAD_ATTR_GET;
   9504   INIT_PTHREAD_ATTR_GET_SCHED;
   9505   INIT_PTHREAD_ATTR_GETINHERITSCHED;
   9506   INIT_PTHREAD_ATTR_GETAFFINITY_NP;
   9507   INIT_PTHREAD_MUTEXATTR_GETPSHARED;
   9508   INIT_PTHREAD_MUTEXATTR_GETTYPE;
   9509   INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
   9510   INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
   9511   INIT_PTHREAD_MUTEXATTR_GETROBUST;
   9512   INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
   9513   INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
   9514   INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
   9515   INIT_PTHREAD_CONDATTR_GETPSHARED;
   9516   INIT_PTHREAD_CONDATTR_GETCLOCK;
   9517   INIT_PTHREAD_BARRIERATTR_GETPSHARED;
   9518   INIT_TMPNAM;
   9519   INIT_TMPNAM_R;
   9520   INIT_TTYNAME_R;
   9521   INIT_TEMPNAM;
   9522   INIT_PTHREAD_SETNAME_NP;
   9523   INIT_PTHREAD_GETNAME_NP;
   9524   INIT_SINCOS;
   9525   INIT_REMQUO;
   9526   INIT_REMQUOL;
   9527   INIT_LGAMMA;
   9528   INIT_LGAMMAL;
   9529   INIT_LGAMMA_R;
   9530   INIT_LGAMMAL_R;
   9531   INIT_DRAND48_R;
   9532   INIT_RAND_R;
   9533   INIT_GETLINE;
   9534   INIT_ICONV;
   9535   INIT_TIMES;
   9536   INIT_TLS_GET_ADDR;
   9537   INIT_LISTXATTR;
   9538   INIT_GETXATTR;
   9539   INIT_GETRESID;
   9540   INIT_GETIFADDRS;
   9541   INIT_IF_INDEXTONAME;
   9542   INIT_CAPGET;
   9543   INIT_AEABI_MEM;
   9544   INIT___BZERO;
   9545   INIT_FTIME;
   9546   INIT_XDR;
   9547   INIT_TSEARCH;
   9548   INIT_LIBIO_INTERNALS;
   9549   INIT_FOPEN;
   9550   INIT_FOPEN64;
   9551   INIT_OPEN_MEMSTREAM;
   9552   INIT_OBSTACK;
   9553   INIT_FFLUSH;
   9554   INIT_FCLOSE;
   9555   INIT_DLOPEN_DLCLOSE;
   9556   INIT_GETPASS;
   9557   INIT_TIMERFD;
   9558   INIT_MLOCKX;
   9559   INIT_FOPENCOOKIE;
   9560   INIT_SEM;
   9561   INIT_PTHREAD_SETCANCEL;
   9562   INIT_MINCORE;
   9563   INIT_PROCESS_VM_READV;
   9564   INIT_CTERMID;
   9565   INIT_CTERMID_R;
   9566   INIT_RECV_RECVFROM;
   9567   INIT_SEND_SENDTO;
   9568   INIT_STAT;
   9569   INIT_EVENTFD_READ_WRITE;
   9570   INIT_LSTAT;
   9571   INIT___XSTAT;
   9572   INIT___XSTAT64;
   9573   INIT___LXSTAT;
   9574   INIT___LXSTAT64;
   9575   // FIXME: add other *stat interceptors.
   9576   INIT_UTMP;
   9577   INIT_UTMPX;
   9578   INIT_GETLOADAVG;
   9579   INIT_WCSLEN;
   9580   INIT_WCSCAT;
   9581   INIT_WCSXFRM;
   9582   INIT___WCSXFRM_L;
   9583   INIT_ACCT;
   9584   INIT_USER_FROM_UID;
   9585   INIT_UID_FROM_USER;
   9586   INIT_GROUP_FROM_GID;
   9587   INIT_GID_FROM_GROUP;
   9588   INIT_ACCESS;
   9589   INIT_FACCESSAT;
   9590   INIT_GETGROUPLIST;
   9591   INIT_GETGROUPMEMBERSHIP;
   9592   INIT_READLINK;
   9593   INIT_READLINKAT;
   9594   INIT_NAME_TO_HANDLE_AT;
   9595   INIT_OPEN_BY_HANDLE_AT;
   9596   INIT_STRLCPY;
   9597   INIT_DEVNAME;
   9598   INIT_DEVNAME_R;
   9599   INIT_FGETLN;
   9600   INIT_STRMODE;
   9601   INIT_TTYENT;
   9602   INIT_PROTOENT;
   9603   INIT_NETENT;
   9604   INIT_GETMNTINFO;
   9605   INIT_MI_VECTOR_HASH;
   9606   INIT_SETVBUF;
   9607   INIT_GETVFSSTAT;
   9608   INIT_REGEX;
   9609   INIT_REGEXSUB;
   9610   INIT_FTS;
   9611   INIT_SYSCTL;
   9612   INIT_ASYSCTL;
   9613   INIT_SYSCTLGETMIBINFO;
   9614   INIT_NL_LANGINFO;
   9615   INIT_MODCTL;
   9616   INIT_STRTONUM;
   9617   INIT_FPARSELN;
   9618   INIT_STATVFS1;
   9619   INIT_STRTOI;
   9620   INIT_CAPSICUM;
   9621   INIT_SHA1;
   9622   INIT_MD4;
   9623   INIT_RMD160;
   9624   INIT_MD5;
   9625   INIT_FSEEK;
   9626   INIT_MD2;
   9627   INIT_SHA2;
   9628   INIT_VIS;
   9629   INIT_CDB;
   9630   INIT_GETFSENT;
   9631   INIT_ARC4RANDOM;
   9632   INIT_POPEN;
   9633   INIT_POPENVE;
   9634   INIT_PCLOSE;
   9635   INIT_FUNOPEN;
   9636   INIT_FUNOPEN2;
   9637 
   9638   INIT___PRINTF_CHK;
   9639 }
   9640