]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
MFV r309587:
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / sanitizer_common / sanitizer_common_interceptors.inc
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_LOCK
28 //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
29 //   COMMON_INTERCEPTOR_MUTEX_REPAIR
30 //   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
31 //   COMMON_INTERCEPTOR_HANDLE_RECVMSG
32 //   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
33 //===----------------------------------------------------------------------===//
34
35 #include "interception/interception.h"
36 #include "sanitizer_addrhashmap.h"
37 #include "sanitizer_placement_new.h"
38 #include "sanitizer_platform_interceptors.h"
39 #include "sanitizer_tls_get_addr.h"
40
41 #include <stdarg.h>
42
43 #if SANITIZER_INTERCEPTOR_HOOKS
44 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)                                     \
45   do {                                                                         \
46     if (f)                                                                     \
47       f(__VA_ARGS__);                                                          \
48   } while (false);
49 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)                                  \
50   extern "C" {                                                                 \
51   SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);  \
52   } // extern "C"
53 #else
54 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
55 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
56
57 #endif  // SANITIZER_INTERCEPTOR_HOOKS
58
59 #if SANITIZER_WINDOWS && !defined(va_copy)
60 #define va_copy(dst, src) ((dst) = (src))
61 #endif // _WIN32
62
63 #if SANITIZER_FREEBSD
64 #define pthread_setname_np pthread_set_name_np
65 #define inet_aton __inet_aton
66 #define inet_pton __inet_pton
67 #define iconv __bsd_iconv
68 #endif
69
70 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
71 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
72 #endif
73
74 #ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
75 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
76 #endif
77
78 #ifndef COMMON_INTERCEPTOR_FD_ACCESS
79 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
80 #endif
81
82 #ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
83 #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
84 #endif
85
86 #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
87 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
88 #endif
89
90 #ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
91 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
92 #endif
93
94 #ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
95 #define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
96 #endif
97
98 #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
99 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
100 #endif
101
102 #ifndef COMMON_INTERCEPTOR_FILE_OPEN
103 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
104 #endif
105
106 #ifndef COMMON_INTERCEPTOR_FILE_CLOSE
107 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
108 #endif
109
110 #ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
111 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
112 #endif
113
114 #ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
115 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
116 #endif
117
118 #ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
119 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
120   COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
121 #endif
122
123 #ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
124 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
125 #endif
126
127 #define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n)       \
128     COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
129       common_flags()->strict_string_checks ? (len) + 1 : (n) )
130
131 #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
132     COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
133
134 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
135 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
136 #endif
137
138 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
139 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
140 #endif
141
142 #ifndef COMMON_INTERCEPTOR_ACQUIRE
143 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
144 #endif
145
146 #ifndef COMMON_INTERCEPTOR_RELEASE
147 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
148 #endif
149
150 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
151 #define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
152 #endif
153
154 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
155 #define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
156 #endif
157
158 #ifdef SANITIZER_NLDBL_VERSION
159 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
160     COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
161 #else
162 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
163     COMMON_INTERCEPT_FUNCTION(fn)
164 #endif
165
166 struct FileMetadata {
167   // For open_memstream().
168   char **addr;
169   SIZE_T *size;
170 };
171
172 struct CommonInterceptorMetadata {
173   enum {
174     CIMT_INVALID = 0,
175     CIMT_FILE
176   } type;
177   union {
178     FileMetadata file;
179   };
180 };
181
182 typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
183
184 static MetadataHashMap *interceptor_metadata_map;
185
186 #if SI_NOT_WINDOWS
187 UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
188                                           const FileMetadata &file) {
189   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
190   CHECK(h.created());
191   h->type = CommonInterceptorMetadata::CIMT_FILE;
192   h->file = file;
193 }
194
195 UNUSED static const FileMetadata *GetInterceptorMetadata(
196     __sanitizer_FILE *addr) {
197   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
198                             /* remove */ false,
199                             /* create */ false);
200   if (h.exists()) {
201     CHECK(!h.created());
202     CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
203     return &h->file;
204   } else {
205     return 0;
206   }
207 }
208
209 UNUSED static void DeleteInterceptorMetadata(void *addr) {
210   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
211   CHECK(h.exists());
212 }
213 #endif  // SI_NOT_WINDOWS
214
215 #if SANITIZER_INTERCEPT_STRLEN
216 INTERCEPTOR(SIZE_T, strlen, const char *s) {
217   // Sometimes strlen is called prior to InitializeCommonInterceptors,
218   // in which case the REAL(strlen) typically used in
219   // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
220   // to handle that.
221   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
222     return internal_strlen(s);
223   void *ctx;
224   COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
225   SIZE_T result = REAL(strlen)(s);
226   if (common_flags()->intercept_strlen)
227     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
228   return result;
229 }
230 #define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
231 #else
232 #define INIT_STRLEN
233 #endif
234
235 #if SANITIZER_INTERCEPT_STRNLEN
236 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
237   void *ctx;
238   COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
239   SIZE_T length = REAL(strnlen)(s, maxlen);
240   if (common_flags()->intercept_strlen)
241     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
242   return length;
243 }
244 #define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
245 #else
246 #define INIT_STRNLEN
247 #endif
248
249 #if SANITIZER_INTERCEPT_TEXTDOMAIN
250 INTERCEPTOR(char*, textdomain, const char *domainname) {
251   void *ctx;
252   COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
253   COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
254   char *domain = REAL(textdomain)(domainname);
255   if (domain) {
256     COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
257   }
258   return domain;
259 }
260 #define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
261 #else
262 #define INIT_TEXTDOMAIN
263 #endif
264
265 #if SANITIZER_INTERCEPT_STRCMP
266 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
267   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
268 }
269
270 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
271                               const char *s1, const char *s2, int result)
272
273 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
274   void *ctx;
275   COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
276   unsigned char c1, c2;
277   uptr i;
278   for (i = 0;; i++) {
279     c1 = (unsigned char)s1[i];
280     c2 = (unsigned char)s2[i];
281     if (c1 != c2 || c1 == '\0') break;
282   }
283   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
284   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
285   int result = CharCmpX(c1, c2);
286   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
287                              s2, result);
288   return result;
289 }
290
291 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
292                               const char *s1, const char *s2, uptr n,
293                               int result)
294
295 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
296   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
297     return internal_strncmp(s1, s2, size);
298   void *ctx;
299   COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
300   unsigned char c1 = 0, c2 = 0;
301   uptr i;
302   for (i = 0; i < size; i++) {
303     c1 = (unsigned char)s1[i];
304     c2 = (unsigned char)s2[i];
305     if (c1 != c2 || c1 == '\0') break;
306   }
307   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
308   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
309   int result = CharCmpX(c1, c2);
310   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
311                              s2, size, result);
312   return result;
313 }
314
315 #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
316 #define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
317 #else
318 #define INIT_STRCMP
319 #define INIT_STRNCMP
320 #endif
321
322 #if SANITIZER_INTERCEPT_STRCASECMP
323 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
324   int c1_low = ToLower(c1);
325   int c2_low = ToLower(c2);
326   return c1_low - c2_low;
327 }
328
329 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
330                               const char *s1, const char *s2, int result)
331
332 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
333   void *ctx;
334   COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
335   unsigned char c1 = 0, c2 = 0;
336   uptr i;
337   for (i = 0;; i++) {
338     c1 = (unsigned char)s1[i];
339     c2 = (unsigned char)s2[i];
340     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
341   }
342   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
343   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
344   int result = CharCaseCmp(c1, c2);
345   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
346                              s1, s2, result);
347   return result;
348 }
349
350 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
351                               const char *s1, const char *s2, uptr n,
352                               int result)
353
354 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
355   void *ctx;
356   COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
357   unsigned char c1 = 0, c2 = 0;
358   uptr i;
359   for (i = 0; i < n; i++) {
360     c1 = (unsigned char)s1[i];
361     c2 = (unsigned char)s2[i];
362     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
363   }
364   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
365   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
366   int result = CharCaseCmp(c1, c2);
367   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
368                              s1, s2, n, result);
369   return result;
370 }
371
372 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
373 #define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
374 #else
375 #define INIT_STRCASECMP
376 #define INIT_STRNCASECMP
377 #endif
378
379 #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
380 static inline void StrstrCheck(void *ctx, char *r, const char *s1,
381                                const char *s2) {
382     uptr len1 = REAL(strlen)(s1);
383     uptr len2 = REAL(strlen)(s2);
384     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
385                                           r ? r - s1 + len2 : len1 + 1);
386     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
387 }
388 #endif
389
390 #if SANITIZER_INTERCEPT_STRSTR
391
392 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
393                               const char *s1, const char *s2, char *result);
394
395 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
396   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
397     return internal_strstr(s1, s2);
398   void *ctx;
399   COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
400   char *r = REAL(strstr)(s1, s2);
401   if (common_flags()->intercept_strstr)
402     StrstrCheck(ctx, r, s1, s2);
403   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
404                              s2, r);
405   return r;
406 }
407
408 #define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
409 #else
410 #define INIT_STRSTR
411 #endif
412
413 #if SANITIZER_INTERCEPT_STRCASESTR
414
415 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
416                               const char *s1, const char *s2, char *result);
417
418 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
419   void *ctx;
420   COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
421   char *r = REAL(strcasestr)(s1, s2);
422   if (common_flags()->intercept_strstr)
423     StrstrCheck(ctx, r, s1, s2);
424   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
425                              s1, s2, r);
426   return r;
427 }
428
429 #define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
430 #else
431 #define INIT_STRCASESTR
432 #endif
433
434 #if SANITIZER_INTERCEPT_MEMMEM
435 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
436                               const void *s1, SIZE_T len1, const void *s2,
437                               SIZE_T len2, void *result);
438
439 INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
440             SIZE_T len2) {
441   void *ctx;
442   COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
443   void *r = REAL(memmem)(s1, len1, s2, len2);
444   if (common_flags()->intercept_memmem) {
445     COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
446     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
447   }
448   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
449                              s1, len1, s2, len2, r);
450   return r;
451 }
452
453 #define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
454 #else
455 #define INIT_MEMMEM
456 #endif  // SANITIZER_INTERCEPT_MEMMEM
457
458 #if SANITIZER_INTERCEPT_STRCHR
459 INTERCEPTOR(char*, strchr, const char *s, int c) {
460   void *ctx;
461   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
462     return internal_strchr(s, c);
463   COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
464   char *result = REAL(strchr)(s, c);
465   uptr len = internal_strlen(s);
466   uptr n = result ? result - s + 1 : len + 1;
467   if (common_flags()->intercept_strchr)
468     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n);
469   return result;
470 }
471 #define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
472 #else
473 #define INIT_STRCHR
474 #endif
475
476 #if SANITIZER_INTERCEPT_STRCHRNUL
477 INTERCEPTOR(char*, strchrnul, const char *s, int c) {
478   void *ctx;
479   COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
480   char *result = REAL(strchrnul)(s, c);
481   uptr len = result - s + 1;
482   if (common_flags()->intercept_strchr)
483     COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
484   return result;
485 }
486 #define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
487 #else
488 #define INIT_STRCHRNUL
489 #endif
490
491 #if SANITIZER_INTERCEPT_STRRCHR
492 INTERCEPTOR(char*, strrchr, const char *s, int c) {
493   void *ctx;
494   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
495     return internal_strrchr(s, c);
496   COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
497   uptr len = internal_strlen(s);
498   if (common_flags()->intercept_strchr)
499     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, len + 1);
500   return REAL(strrchr)(s, c);
501 }
502 #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
503 #else
504 #define INIT_STRRCHR
505 #endif
506
507 #if SANITIZER_INTERCEPT_STRSPN
508 INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
509   void *ctx;
510   COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
511   SIZE_T r = REAL(strspn)(s1, s2);
512   if (common_flags()->intercept_strspn) {
513     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
514     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
515   }
516   return r;
517 }
518
519 INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
520   void *ctx;
521   COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
522   SIZE_T r = REAL(strcspn)(s1, s2);
523   if (common_flags()->intercept_strspn) {
524     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
525     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
526   }
527   return r;
528 }
529
530 #define INIT_STRSPN \
531   COMMON_INTERCEPT_FUNCTION(strspn); \
532   COMMON_INTERCEPT_FUNCTION(strcspn);
533 #else
534 #define INIT_STRSPN
535 #endif
536
537 #if SANITIZER_INTERCEPT_STRPBRK
538 INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
539   void *ctx;
540   COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
541   char *r = REAL(strpbrk)(s1, s2);
542   if (common_flags()->intercept_strpbrk) {
543     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
544     COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
545         r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
546   }
547   return r;
548 }
549
550 #define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
551 #else
552 #define INIT_STRPBRK
553 #endif
554
555 #if SANITIZER_INTERCEPT_MEMSET
556 INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
557   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
558     return internal_memset(dst, v, size);
559   void *ctx;
560   COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);
561   if (common_flags()->intercept_intrin)
562     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
563   return REAL(memset)(dst, v, size);
564 }
565
566 #define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
567 #else
568 #define INIT_MEMSET
569 #endif
570
571 #if SANITIZER_INTERCEPT_MEMMOVE
572 INTERCEPTOR(void*, memmove, void *dst, const void *src, uptr size) {
573   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
574     return internal_memmove(dst, src, size);
575   void *ctx;
576   COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);
577   if (common_flags()->intercept_intrin) {
578     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
579     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
580   }
581   return REAL(memmove)(dst, src, size);
582 }
583
584 #define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
585 #else
586 #define INIT_MEMMOVE
587 #endif
588
589 #if SANITIZER_INTERCEPT_MEMCPY
590 INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {
591   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
592     // On OS X, calling internal_memcpy here will cause memory corruptions,
593     // because memcpy and memmove are actually aliases of the same
594     // implementation.  We need to use internal_memmove here.
595     return internal_memmove(dst, src, size);
596   }
597   void *ctx;
598   COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);
599   if (common_flags()->intercept_intrin) {
600     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
601     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
602   }
603   // N.B.: If we switch this to internal_ we'll have to use internal_memmove
604   // due to memcpy being an alias of memmove on OS X.
605   return REAL(memcpy)(dst, src, size);
606 }
607
608 #define INIT_MEMCPY COMMON_INTERCEPT_FUNCTION(memcpy)
609 #else
610 #define INIT_MEMCPY
611 #endif
612
613 #if SANITIZER_INTERCEPT_MEMCMP
614
615 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
616                               const void *s1, const void *s2, uptr n,
617                               int result)
618
619 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
620   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
621     return internal_memcmp(a1, a2, size);
622   void *ctx;
623   COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
624   if (common_flags()->intercept_memcmp) {
625     if (common_flags()->strict_memcmp) {
626       // Check the entire regions even if the first bytes of the buffers are
627       // different.
628       COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
629       COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
630       // Fallthrough to REAL(memcmp) below.
631     } else {
632       unsigned char c1 = 0, c2 = 0;
633       const unsigned char *s1 = (const unsigned char*)a1;
634       const unsigned char *s2 = (const unsigned char*)a2;
635       uptr i;
636       for (i = 0; i < size; i++) {
637         c1 = s1[i];
638         c2 = s2[i];
639         if (c1 != c2) break;
640       }
641       COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
642       COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
643       int r = CharCmpX(c1, c2);
644       CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
645                                  a1, a2, size, r);
646       return r;
647     }
648   }
649   int result = REAL(memcmp(a1, a2, size));
650   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
651                              a2, size, result);
652   return result;
653 }
654
655 #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
656 #else
657 #define INIT_MEMCMP
658 #endif
659
660 #if SANITIZER_INTERCEPT_MEMCHR
661 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
662   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
663     return internal_memchr(s, c, n);
664   void *ctx;
665   COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
666   void *res = REAL(memchr)(s, c, n);
667   uptr len = res ? (char *)res - (const char *)s + 1 : n;
668   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
669   return res;
670 }
671
672 #define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
673 #else
674 #define INIT_MEMCHR
675 #endif
676
677 #if SANITIZER_INTERCEPT_MEMRCHR
678 INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
679   void *ctx;
680   COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
681   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
682   return REAL(memrchr)(s, c, n);
683 }
684
685 #define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
686 #else
687 #define INIT_MEMRCHR
688 #endif
689
690 #if SANITIZER_INTERCEPT_FREXP
691 INTERCEPTOR(double, frexp, double x, int *exp) {
692   void *ctx;
693   COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
694   // Assuming frexp() always writes to |exp|.
695   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
696   double res = REAL(frexp)(x, exp);
697   return res;
698 }
699
700 #define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
701 #else
702 #define INIT_FREXP
703 #endif  // SANITIZER_INTERCEPT_FREXP
704
705 #if SANITIZER_INTERCEPT_FREXPF_FREXPL
706 INTERCEPTOR(float, frexpf, float x, int *exp) {
707   void *ctx;
708   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
709   // FIXME: under ASan the call below may write to freed memory and corrupt
710   // its metadata. See
711   // https://github.com/google/sanitizers/issues/321.
712   float res = REAL(frexpf)(x, exp);
713   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
714   return res;
715 }
716
717 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
718   void *ctx;
719   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
720   // FIXME: under ASan the call below may write to freed memory and corrupt
721   // its metadata. See
722   // https://github.com/google/sanitizers/issues/321.
723   long double res = REAL(frexpl)(x, exp);
724   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
725   return res;
726 }
727
728 #define INIT_FREXPF_FREXPL           \
729   COMMON_INTERCEPT_FUNCTION(frexpf); \
730   COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
731 #else
732 #define INIT_FREXPF_FREXPL
733 #endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
734
735 #if SI_NOT_WINDOWS
736 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
737                         SIZE_T iovlen, SIZE_T maxlen) {
738   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
739     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
740     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
741     maxlen -= sz;
742   }
743 }
744
745 static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
746                        SIZE_T iovlen, SIZE_T maxlen) {
747   COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
748   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
749     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
750     COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
751     maxlen -= sz;
752   }
753 }
754 #endif
755
756 #if SANITIZER_INTERCEPT_READ
757 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
758   void *ctx;
759   COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
760   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
761   // FIXME: under ASan the call below may write to freed memory and corrupt
762   // its metadata. See
763   // https://github.com/google/sanitizers/issues/321.
764   SSIZE_T res = REAL(read)(fd, ptr, count);
765   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
766   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
767   return res;
768 }
769 #define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
770 #else
771 #define INIT_READ
772 #endif
773
774 #if SANITIZER_INTERCEPT_PREAD
775 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
776   void *ctx;
777   COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
778   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
779   // FIXME: under ASan the call below may write to freed memory and corrupt
780   // its metadata. See
781   // https://github.com/google/sanitizers/issues/321.
782   SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
783   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
784   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
785   return res;
786 }
787 #define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
788 #else
789 #define INIT_PREAD
790 #endif
791
792 #if SANITIZER_INTERCEPT_PREAD64
793 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
794   void *ctx;
795   COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
796   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
797   // FIXME: under ASan the call below may write to freed memory and corrupt
798   // its metadata. See
799   // https://github.com/google/sanitizers/issues/321.
800   SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
801   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
802   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
803   return res;
804 }
805 #define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
806 #else
807 #define INIT_PREAD64
808 #endif
809
810 #if SANITIZER_INTERCEPT_READV
811 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
812                         int iovcnt) {
813   void *ctx;
814   COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
815   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
816   SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
817   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
818   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
819   return res;
820 }
821 #define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
822 #else
823 #define INIT_READV
824 #endif
825
826 #if SANITIZER_INTERCEPT_PREADV
827 INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
828             OFF_T offset) {
829   void *ctx;
830   COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
831   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
832   SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
833   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
834   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
835   return res;
836 }
837 #define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
838 #else
839 #define INIT_PREADV
840 #endif
841
842 #if SANITIZER_INTERCEPT_PREADV64
843 INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
844             OFF64_T offset) {
845   void *ctx;
846   COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
847   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
848   SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
849   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
850   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
851   return res;
852 }
853 #define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
854 #else
855 #define INIT_PREADV64
856 #endif
857
858 #if SANITIZER_INTERCEPT_WRITE
859 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
860   void *ctx;
861   COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
862   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
863   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
864   SSIZE_T res = REAL(write)(fd, ptr, count);
865   // FIXME: this check should be _before_ the call to REAL(write), not after
866   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
867   return res;
868 }
869 #define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
870 #else
871 #define INIT_WRITE
872 #endif
873
874 #if SANITIZER_INTERCEPT_PWRITE
875 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
876   void *ctx;
877   COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
878   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
879   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
880   SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
881   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
882   return res;
883 }
884 #define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
885 #else
886 #define INIT_PWRITE
887 #endif
888
889 #if SANITIZER_INTERCEPT_PWRITE64
890 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
891             OFF64_T offset) {
892   void *ctx;
893   COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
894   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
895   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
896   SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
897   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
898   return res;
899 }
900 #define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
901 #else
902 #define INIT_PWRITE64
903 #endif
904
905 #if SANITIZER_INTERCEPT_WRITEV
906 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
907                         int iovcnt) {
908   void *ctx;
909   COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
910   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
911   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
912   SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
913   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
914   return res;
915 }
916 #define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
917 #else
918 #define INIT_WRITEV
919 #endif
920
921 #if SANITIZER_INTERCEPT_PWRITEV
922 INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
923             OFF_T offset) {
924   void *ctx;
925   COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
926   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
927   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
928   SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
929   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
930   return res;
931 }
932 #define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
933 #else
934 #define INIT_PWRITEV
935 #endif
936
937 #if SANITIZER_INTERCEPT_PWRITEV64
938 INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
939             OFF64_T offset) {
940   void *ctx;
941   COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
942   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
943   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
944   SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
945   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
946   return res;
947 }
948 #define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
949 #else
950 #define INIT_PWRITEV64
951 #endif
952
953 #if SANITIZER_INTERCEPT_PRCTL
954 INTERCEPTOR(int, prctl, int option, unsigned long arg2,
955             unsigned long arg3,                        // NOLINT
956             unsigned long arg4, unsigned long arg5) {  // NOLINT
957   void *ctx;
958   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
959   static const int PR_SET_NAME = 15;
960   int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
961   if (option == PR_SET_NAME) {
962     char buff[16];
963     internal_strncpy(buff, (char *)arg2, 15);
964     buff[15] = 0;
965     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
966   }
967   return res;
968 }
969 #define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
970 #else
971 #define INIT_PRCTL
972 #endif  // SANITIZER_INTERCEPT_PRCTL
973
974 #if SANITIZER_INTERCEPT_TIME
975 INTERCEPTOR(unsigned long, time, unsigned long *t) {
976   void *ctx;
977   COMMON_INTERCEPTOR_ENTER(ctx, time, t);
978   unsigned long local_t;
979   unsigned long res = REAL(time)(&local_t);
980   if (t && res != (unsigned long)-1) {
981     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
982     *t = local_t;
983   }
984   return res;
985 }
986 #define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
987 #else
988 #define INIT_TIME
989 #endif  // SANITIZER_INTERCEPT_TIME
990
991 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
992 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
993   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
994   if (tm->tm_zone) {
995     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
996     // can point to shared memory and tsan would report a data race.
997     COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
998                                         REAL(strlen(tm->tm_zone)) + 1);
999   }
1000 }
1001 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
1002   void *ctx;
1003   COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
1004   __sanitizer_tm *res = REAL(localtime)(timep);
1005   if (res) {
1006     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1007     unpoison_tm(ctx, res);
1008   }
1009   return res;
1010 }
1011 INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
1012   void *ctx;
1013   COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
1014   __sanitizer_tm *res = REAL(localtime_r)(timep, result);
1015   if (res) {
1016     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1017     unpoison_tm(ctx, res);
1018   }
1019   return res;
1020 }
1021 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
1022   void *ctx;
1023   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
1024   __sanitizer_tm *res = REAL(gmtime)(timep);
1025   if (res) {
1026     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1027     unpoison_tm(ctx, res);
1028   }
1029   return res;
1030 }
1031 INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
1032   void *ctx;
1033   COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
1034   __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
1035   if (res) {
1036     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1037     unpoison_tm(ctx, res);
1038   }
1039   return res;
1040 }
1041 INTERCEPTOR(char *, ctime, unsigned long *timep) {
1042   void *ctx;
1043   COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
1044   // FIXME: under ASan the call below may write to freed memory and corrupt
1045   // its metadata. See
1046   // https://github.com/google/sanitizers/issues/321.
1047   char *res = REAL(ctime)(timep);
1048   if (res) {
1049     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1050     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1051   }
1052   return res;
1053 }
1054 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
1055   void *ctx;
1056   COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
1057   // FIXME: under ASan the call below may write to freed memory and corrupt
1058   // its metadata. See
1059   // https://github.com/google/sanitizers/issues/321.
1060   char *res = REAL(ctime_r)(timep, result);
1061   if (res) {
1062     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1063     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1064   }
1065   return res;
1066 }
1067 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
1068   void *ctx;
1069   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
1070   // FIXME: under ASan the call below may write to freed memory and corrupt
1071   // its metadata. See
1072   // https://github.com/google/sanitizers/issues/321.
1073   char *res = REAL(asctime)(tm);
1074   if (res) {
1075     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1076     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1077   }
1078   return res;
1079 }
1080 INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
1081   void *ctx;
1082   COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
1083   // FIXME: under ASan the call below may write to freed memory and corrupt
1084   // its metadata. See
1085   // https://github.com/google/sanitizers/issues/321.
1086   char *res = REAL(asctime_r)(tm, result);
1087   if (res) {
1088     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1089     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1090   }
1091   return res;
1092 }
1093 INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
1094   void *ctx;
1095   COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
1096   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
1097   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
1098   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
1099   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
1100   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
1101   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
1102   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
1103   long res = REAL(mktime)(tm);
1104   if (res != -1) unpoison_tm(ctx, tm);
1105   return res;
1106 }
1107 #define INIT_LOCALTIME_AND_FRIENDS        \
1108   COMMON_INTERCEPT_FUNCTION(localtime);   \
1109   COMMON_INTERCEPT_FUNCTION(localtime_r); \
1110   COMMON_INTERCEPT_FUNCTION(gmtime);      \
1111   COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
1112   COMMON_INTERCEPT_FUNCTION(ctime);       \
1113   COMMON_INTERCEPT_FUNCTION(ctime_r);     \
1114   COMMON_INTERCEPT_FUNCTION(asctime);     \
1115   COMMON_INTERCEPT_FUNCTION(asctime_r);   \
1116   COMMON_INTERCEPT_FUNCTION(mktime);
1117 #else
1118 #define INIT_LOCALTIME_AND_FRIENDS
1119 #endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1120
1121 #if SANITIZER_INTERCEPT_STRPTIME
1122 INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
1123   void *ctx;
1124   COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
1125   if (format)
1126     COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
1127   // FIXME: under ASan the call below may write to freed memory and corrupt
1128   // its metadata. See
1129   // https://github.com/google/sanitizers/issues/321.
1130   char *res = REAL(strptime)(s, format, tm);
1131   COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
1132   if (res && tm) {
1133     // Do not call unpoison_tm here, because strptime does not, in fact,
1134     // initialize the entire struct tm. For example, tm_zone pointer is left
1135     // uninitialized.
1136     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1137   }
1138   return res;
1139 }
1140 #define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
1141 #else
1142 #define INIT_STRPTIME
1143 #endif
1144
1145 #if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
1146 #include "sanitizer_common_interceptors_format.inc"
1147
1148 #define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
1149   {                                                                            \
1150     void *ctx;                                                                 \
1151     va_list ap;                                                                \
1152     va_start(ap, format);                                                      \
1153     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
1154     int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
1155     va_end(ap);                                                                \
1156     return res;                                                                \
1157   }
1158
1159 #endif
1160
1161 #if SANITIZER_INTERCEPT_SCANF
1162
1163 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
1164   {                                                                            \
1165     void *ctx;                                                                 \
1166     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
1167     va_list aq;                                                                \
1168     va_copy(aq, ap);                                                           \
1169     int res = REAL(vname)(__VA_ARGS__);                                        \
1170     if (res > 0)                                                               \
1171       scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
1172     va_end(aq);                                                                \
1173     return res;                                                                \
1174   }
1175
1176 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
1177 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
1178
1179 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
1180 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
1181
1182 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
1183 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
1184
1185 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1186 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
1187 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
1188
1189 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
1190             va_list ap)
1191 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
1192
1193 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
1194 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
1195 #endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
1196
1197 INTERCEPTOR(int, scanf, const char *format, ...)
1198 FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
1199
1200 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
1201 FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
1202
1203 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
1204 FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
1205
1206 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1207 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
1208 FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
1209
1210 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
1211 FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
1212
1213 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
1214 FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
1215 #endif
1216
1217 #endif
1218
1219 #if SANITIZER_INTERCEPT_SCANF
1220 #define INIT_SCANF                    \
1221   COMMON_INTERCEPT_FUNCTION(scanf);   \
1222   COMMON_INTERCEPT_FUNCTION(sscanf);  \
1223   COMMON_INTERCEPT_FUNCTION(fscanf);  \
1224   COMMON_INTERCEPT_FUNCTION(vscanf);  \
1225   COMMON_INTERCEPT_FUNCTION(vsscanf); \
1226   COMMON_INTERCEPT_FUNCTION(vfscanf);
1227 #else
1228 #define INIT_SCANF
1229 #endif
1230
1231 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1232 #define INIT_ISOC99_SCANF                      \
1233   COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
1234   COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
1235   COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
1236   COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
1237   COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1238   COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1239 #else
1240 #define INIT_ISOC99_SCANF
1241 #endif
1242
1243 #if SANITIZER_INTERCEPT_PRINTF
1244
1245 #define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
1246   void *ctx;                                                                   \
1247   COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
1248   va_list aq;                                                                  \
1249   va_copy(aq, ap);
1250
1251 #define VPRINTF_INTERCEPTOR_RETURN()                                           \
1252   va_end(aq);
1253
1254 #define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
1255   {                                                                            \
1256     VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
1257     if (common_flags()->check_printf)                                          \
1258       printf_common(ctx, format, aq);                                          \
1259     int res = REAL(vname)(__VA_ARGS__);                                        \
1260     VPRINTF_INTERCEPTOR_RETURN();                                              \
1261     return res;                                                                \
1262   }
1263
1264 // FIXME: under ASan the REAL() call below may write to freed memory and
1265 // corrupt its metadata. See
1266 // https://github.com/google/sanitizers/issues/321.
1267 #define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
1268   {                                                                            \
1269     VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
1270     if (common_flags()->check_printf) {                                        \
1271       printf_common(ctx, format, aq);                                          \
1272     }                                                                          \
1273     int res = REAL(vname)(str, __VA_ARGS__);                                   \
1274     if (res >= 0) {                                                            \
1275       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
1276     }                                                                          \
1277     VPRINTF_INTERCEPTOR_RETURN();                                              \
1278     return res;                                                                \
1279   }
1280
1281 // FIXME: under ASan the REAL() call below may write to freed memory and
1282 // corrupt its metadata. See
1283 // https://github.com/google/sanitizers/issues/321.
1284 #define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
1285   {                                                                            \
1286     VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
1287     if (common_flags()->check_printf) {                                        \
1288       printf_common(ctx, format, aq);                                          \
1289     }                                                                          \
1290     int res = REAL(vname)(str, size, __VA_ARGS__);                             \
1291     if (res >= 0) {                                                            \
1292       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
1293     }                                                                          \
1294     VPRINTF_INTERCEPTOR_RETURN();                                              \
1295     return res;                                                                \
1296   }
1297
1298 // FIXME: under ASan the REAL() call below may write to freed memory and
1299 // corrupt its metadata. See
1300 // https://github.com/google/sanitizers/issues/321.
1301 #define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
1302   {                                                                            \
1303     VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
1304     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
1305     if (common_flags()->check_printf) {                                        \
1306       printf_common(ctx, format, aq);                                          \
1307     }                                                                          \
1308     int res = REAL(vname)(strp, __VA_ARGS__);                                  \
1309     if (res >= 0) {                                                            \
1310       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
1311     }                                                                          \
1312     VPRINTF_INTERCEPTOR_RETURN();                                              \
1313     return res;                                                                \
1314   }
1315
1316 INTERCEPTOR(int, vprintf, const char *format, va_list ap)
1317 VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
1318
1319 INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
1320             va_list ap)
1321 VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
1322
1323 INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
1324             va_list ap)
1325 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1326
1327 #if SANITIZER_INTERCEPT_PRINTF_L
1328 INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
1329             const char *format, va_list ap)
1330 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
1331
1332 INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
1333             const char *format, ...)
1334 FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
1335 #endif  // SANITIZER_INTERCEPT_PRINTF_L
1336
1337 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
1338 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1339
1340 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
1341 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1342
1343 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1344 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
1345 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
1346
1347 INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
1348             const char *format, va_list ap)
1349 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
1350
1351 INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
1352             va_list ap)
1353 VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
1354
1355 INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
1356             va_list ap)
1357 VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
1358                           ap)
1359
1360 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1361
1362 INTERCEPTOR(int, printf, const char *format, ...)
1363 FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
1364
1365 INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
1366 FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
1367
1368 INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
1369 FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
1370
1371 INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
1372 FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
1373
1374 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
1375 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1376
1377 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1378 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
1379 FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
1380
1381 INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
1382             ...)
1383 FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
1384
1385 INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
1386 FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
1387
1388 INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
1389             const char *format, ...)
1390 FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
1391                         format)
1392
1393 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1394
1395 #endif  // SANITIZER_INTERCEPT_PRINTF
1396
1397 #if SANITIZER_INTERCEPT_PRINTF
1398 #define INIT_PRINTF                     \
1399   COMMON_INTERCEPT_FUNCTION(printf);    \
1400   COMMON_INTERCEPT_FUNCTION(sprintf);   \
1401   COMMON_INTERCEPT_FUNCTION(snprintf);  \
1402   COMMON_INTERCEPT_FUNCTION(asprintf);  \
1403   COMMON_INTERCEPT_FUNCTION(fprintf);   \
1404   COMMON_INTERCEPT_FUNCTION(vprintf);   \
1405   COMMON_INTERCEPT_FUNCTION(vsprintf);  \
1406   COMMON_INTERCEPT_FUNCTION(vsnprintf); \
1407   COMMON_INTERCEPT_FUNCTION(vasprintf); \
1408   COMMON_INTERCEPT_FUNCTION(vfprintf);
1409 #else
1410 #define INIT_PRINTF
1411 #endif
1412
1413 #if SANITIZER_INTERCEPT_PRINTF_L
1414 #define INIT_PRINTF_L                     \
1415   COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
1416   COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
1417 #else
1418 #define INIT_PRINTF_L
1419 #endif
1420
1421 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1422 #define INIT_ISOC99_PRINTF                       \
1423   COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
1424   COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
1425   COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
1426   COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
1427   COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
1428   COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
1429   COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
1430   COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
1431 #else
1432 #define INIT_ISOC99_PRINTF
1433 #endif
1434
1435 #if SANITIZER_INTERCEPT_IOCTL
1436 #include "sanitizer_common_interceptors_ioctl.inc"
1437 INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
1438   // We need a frame pointer, because we call into ioctl_common_[pre|post] which
1439   // can trigger a report and we need to be able to unwind through this
1440   // function.  On Mac in debug mode we might not have a frame pointer, because
1441   // ioctl_common_[pre|post] doesn't get inlined here.
1442   ENABLE_FRAME_POINTER;
1443
1444   void *ctx;
1445   va_list ap;
1446   va_start(ap, request);
1447   void *arg = va_arg(ap, void *);
1448   va_end(ap);
1449   COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1450
1451   CHECK(ioctl_initialized);
1452
1453   // Note: TSan does not use common flags, and they are zero-initialized.
1454   // This effectively disables ioctl handling in TSan.
1455   if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1456
1457   // Although request is unsigned long, the rest of the interceptor uses it
1458   // as just "unsigned" to save space, because we know that all values fit in
1459   // "unsigned" - they are compile-time constants.
1460
1461   const ioctl_desc *desc = ioctl_lookup(request);
1462   ioctl_desc decoded_desc;
1463   if (!desc) {
1464     VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
1465     if (!ioctl_decode(request, &decoded_desc))
1466       Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
1467     else
1468       desc = &decoded_desc;
1469   }
1470
1471   if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1472   int res = REAL(ioctl)(d, request, arg);
1473   // FIXME: some ioctls have different return values for success and failure.
1474   if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1475   return res;
1476 }
1477 #define INIT_IOCTL \
1478   ioctl_init();    \
1479   COMMON_INTERCEPT_FUNCTION(ioctl);
1480 #else
1481 #define INIT_IOCTL
1482 #endif
1483
1484 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
1485     SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
1486     SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1487 static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1488   if (pwd) {
1489     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1490     if (pwd->pw_name)
1491       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
1492                                           REAL(strlen)(pwd->pw_name) + 1);
1493     if (pwd->pw_passwd)
1494       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
1495                                           REAL(strlen)(pwd->pw_passwd) + 1);
1496 #if !SANITIZER_ANDROID
1497     if (pwd->pw_gecos)
1498       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
1499                                           REAL(strlen)(pwd->pw_gecos) + 1);
1500 #endif
1501 #if SANITIZER_MAC
1502     if (pwd->pw_class)
1503       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
1504                                           REAL(strlen)(pwd->pw_class) + 1);
1505 #endif
1506     if (pwd->pw_dir)
1507       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
1508                                           REAL(strlen)(pwd->pw_dir) + 1);
1509     if (pwd->pw_shell)
1510       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
1511                                           REAL(strlen)(pwd->pw_shell) + 1);
1512   }
1513 }
1514
1515 static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1516   if (grp) {
1517     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1518     if (grp->gr_name)
1519       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
1520                                           REAL(strlen)(grp->gr_name) + 1);
1521     if (grp->gr_passwd)
1522       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
1523                                           REAL(strlen)(grp->gr_passwd) + 1);
1524     char **p = grp->gr_mem;
1525     for (; *p; ++p) {
1526       COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
1527     }
1528     COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
1529                                         (p - grp->gr_mem + 1) * sizeof(*p));
1530   }
1531 }
1532 #endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
1533         // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
1534         // SANITIZER_INTERCEPT_GETPWENT_R ||
1535         // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1536
1537 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1538 INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1539   void *ctx;
1540   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1541   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1542   __sanitizer_passwd *res = REAL(getpwnam)(name);
1543   if (res) unpoison_passwd(ctx, res);
1544   return res;
1545 }
1546 INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1547   void *ctx;
1548   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
1549   __sanitizer_passwd *res = REAL(getpwuid)(uid);
1550   if (res) unpoison_passwd(ctx, res);
1551   return res;
1552 }
1553 INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1554   void *ctx;
1555   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1556   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1557   __sanitizer_group *res = REAL(getgrnam)(name);
1558   if (res) unpoison_group(ctx, res);
1559   return res;
1560 }
1561 INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1562   void *ctx;
1563   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
1564   __sanitizer_group *res = REAL(getgrgid)(gid);
1565   if (res) unpoison_group(ctx, res);
1566   return res;
1567 }
1568 #define INIT_GETPWNAM_AND_FRIENDS      \
1569   COMMON_INTERCEPT_FUNCTION(getpwnam); \
1570   COMMON_INTERCEPT_FUNCTION(getpwuid); \
1571   COMMON_INTERCEPT_FUNCTION(getgrnam); \
1572   COMMON_INTERCEPT_FUNCTION(getgrgid);
1573 #else
1574 #define INIT_GETPWNAM_AND_FRIENDS
1575 #endif
1576
1577 #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1578 INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
1579             char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1580   void *ctx;
1581   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1582   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1583   // FIXME: under ASan the call below may write to freed memory and corrupt
1584   // its metadata. See
1585   // https://github.com/google/sanitizers/issues/321.
1586   int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1587   if (!res) {
1588     if (result && *result) unpoison_passwd(ctx, *result);
1589     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1590   }
1591   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1592   return res;
1593 }
1594 INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
1595             SIZE_T buflen, __sanitizer_passwd **result) {
1596   void *ctx;
1597   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
1598   // FIXME: under ASan the call below may write to freed memory and corrupt
1599   // its metadata. See
1600   // https://github.com/google/sanitizers/issues/321.
1601   int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1602   if (!res) {
1603     if (result && *result) unpoison_passwd(ctx, *result);
1604     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1605   }
1606   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1607   return res;
1608 }
1609 INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
1610             char *buf, SIZE_T buflen, __sanitizer_group **result) {
1611   void *ctx;
1612   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1613   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1614   // FIXME: under ASan the call below may write to freed memory and corrupt
1615   // its metadata. See
1616   // https://github.com/google/sanitizers/issues/321.
1617   int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1618   if (!res) {
1619     if (result && *result) unpoison_group(ctx, *result);
1620     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1621   }
1622   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1623   return res;
1624 }
1625 INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
1626             SIZE_T buflen, __sanitizer_group **result) {
1627   void *ctx;
1628   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
1629   // FIXME: under ASan the call below may write to freed memory and corrupt
1630   // its metadata. See
1631   // https://github.com/google/sanitizers/issues/321.
1632   int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1633   if (!res) {
1634     if (result && *result) unpoison_group(ctx, *result);
1635     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1636   }
1637   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1638   return res;
1639 }
1640 #define INIT_GETPWNAM_R_AND_FRIENDS      \
1641   COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1642   COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
1643   COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
1644   COMMON_INTERCEPT_FUNCTION(getgrgid_r);
1645 #else
1646 #define INIT_GETPWNAM_R_AND_FRIENDS
1647 #endif
1648
1649 #if SANITIZER_INTERCEPT_GETPWENT
1650 INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
1651   void *ctx;
1652   COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
1653   __sanitizer_passwd *res = REAL(getpwent)(dummy);
1654   if (res) unpoison_passwd(ctx, res);
1655   return res;
1656 }
1657 INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
1658   void *ctx;
1659   COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
1660   __sanitizer_group *res = REAL(getgrent)(dummy);
1661   if (res) unpoison_group(ctx, res);;
1662   return res;
1663 }
1664 #define INIT_GETPWENT                  \
1665   COMMON_INTERCEPT_FUNCTION(getpwent); \
1666   COMMON_INTERCEPT_FUNCTION(getgrent);
1667 #else
1668 #define INIT_GETPWENT
1669 #endif
1670
1671 #if SANITIZER_INTERCEPT_FGETPWENT
1672 INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
1673   void *ctx;
1674   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
1675   __sanitizer_passwd *res = REAL(fgetpwent)(fp);
1676   if (res) unpoison_passwd(ctx, res);
1677   return res;
1678 }
1679 INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
1680   void *ctx;
1681   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
1682   __sanitizer_group *res = REAL(fgetgrent)(fp);
1683   if (res) unpoison_group(ctx, res);
1684   return res;
1685 }
1686 #define INIT_FGETPWENT                  \
1687   COMMON_INTERCEPT_FUNCTION(fgetpwent); \
1688   COMMON_INTERCEPT_FUNCTION(fgetgrent);
1689 #else
1690 #define INIT_FGETPWENT
1691 #endif
1692
1693 #if SANITIZER_INTERCEPT_GETPWENT_R
1694 INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
1695             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1696   void *ctx;
1697   COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
1698   // FIXME: under ASan the call below may write to freed memory and corrupt
1699   // its metadata. See
1700   // https://github.com/google/sanitizers/issues/321.
1701   int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
1702   if (!res) {
1703     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1704     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1705   }
1706   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1707   return res;
1708 }
1709 INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
1710             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1711   void *ctx;
1712   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
1713   // FIXME: under ASan the call below may write to freed memory and corrupt
1714   // its metadata. See
1715   // https://github.com/google/sanitizers/issues/321.
1716   int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
1717   if (!res) {
1718     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1719     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1720   }
1721   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1722   return res;
1723 }
1724 INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
1725             __sanitizer_group **pwbufp) {
1726   void *ctx;
1727   COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
1728   // FIXME: under ASan the call below may write to freed memory and corrupt
1729   // its metadata. See
1730   // https://github.com/google/sanitizers/issues/321.
1731   int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
1732   if (!res) {
1733     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1734     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1735   }
1736   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1737   return res;
1738 }
1739 INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
1740             SIZE_T buflen, __sanitizer_group **pwbufp) {
1741   void *ctx;
1742   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
1743   // FIXME: under ASan the call below may write to freed memory and corrupt
1744   // its metadata. See
1745   // https://github.com/google/sanitizers/issues/321.
1746   int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
1747   if (!res) {
1748     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1749     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1750   }
1751   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1752   return res;
1753 }
1754 #define INIT_GETPWENT_R                   \
1755   COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
1756   COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
1757   COMMON_INTERCEPT_FUNCTION(getgrent_r);  \
1758   COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
1759 #else
1760 #define INIT_GETPWENT_R
1761 #endif
1762
1763 #if SANITIZER_INTERCEPT_SETPWENT
1764 // The only thing these interceptors do is disable any nested interceptors.
1765 // These functions may open nss modules and call uninstrumented functions from
1766 // them, and we don't want things like strlen() to trigger.
1767 INTERCEPTOR(void, setpwent, int dummy) {
1768   void *ctx;
1769   COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
1770   REAL(setpwent)(dummy);
1771 }
1772 INTERCEPTOR(void, endpwent, int dummy) {
1773   void *ctx;
1774   COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
1775   REAL(endpwent)(dummy);
1776 }
1777 INTERCEPTOR(void, setgrent, int dummy) {
1778   void *ctx;
1779   COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
1780   REAL(setgrent)(dummy);
1781 }
1782 INTERCEPTOR(void, endgrent, int dummy) {
1783   void *ctx;
1784   COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
1785   REAL(endgrent)(dummy);
1786 }
1787 #define INIT_SETPWENT                  \
1788   COMMON_INTERCEPT_FUNCTION(setpwent); \
1789   COMMON_INTERCEPT_FUNCTION(endpwent); \
1790   COMMON_INTERCEPT_FUNCTION(setgrent); \
1791   COMMON_INTERCEPT_FUNCTION(endgrent);
1792 #else
1793 #define INIT_SETPWENT
1794 #endif
1795
1796 #if SANITIZER_INTERCEPT_CLOCK_GETTIME
1797 INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
1798   void *ctx;
1799   COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
1800   // FIXME: under ASan the call below may write to freed memory and corrupt
1801   // its metadata. See
1802   // https://github.com/google/sanitizers/issues/321.
1803   int res = REAL(clock_getres)(clk_id, tp);
1804   if (!res && tp) {
1805     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1806   }
1807   return res;
1808 }
1809 INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
1810   void *ctx;
1811   COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
1812   // FIXME: under ASan the call below may write to freed memory and corrupt
1813   // its metadata. See
1814   // https://github.com/google/sanitizers/issues/321.
1815   int res = REAL(clock_gettime)(clk_id, tp);
1816   if (!res) {
1817     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1818   }
1819   return res;
1820 }
1821 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
1822   void *ctx;
1823   COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
1824   COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
1825   return REAL(clock_settime)(clk_id, tp);
1826 }
1827 #define INIT_CLOCK_GETTIME                  \
1828   COMMON_INTERCEPT_FUNCTION(clock_getres);  \
1829   COMMON_INTERCEPT_FUNCTION(clock_gettime); \
1830   COMMON_INTERCEPT_FUNCTION(clock_settime);
1831 #else
1832 #define INIT_CLOCK_GETTIME
1833 #endif
1834
1835 #if SANITIZER_INTERCEPT_GETITIMER
1836 INTERCEPTOR(int, getitimer, int which, void *curr_value) {
1837   void *ctx;
1838   COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
1839   // FIXME: under ASan the call below may write to freed memory and corrupt
1840   // its metadata. See
1841   // https://github.com/google/sanitizers/issues/321.
1842   int res = REAL(getitimer)(which, curr_value);
1843   if (!res && curr_value) {
1844     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
1845   }
1846   return res;
1847 }
1848 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
1849   void *ctx;
1850   COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
1851   if (new_value)
1852     COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
1853   // FIXME: under ASan the call below may write to freed memory and corrupt
1854   // its metadata. See
1855   // https://github.com/google/sanitizers/issues/321.
1856   int res = REAL(setitimer)(which, new_value, old_value);
1857   if (!res && old_value) {
1858     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
1859   }
1860   return res;
1861 }
1862 #define INIT_GETITIMER                  \
1863   COMMON_INTERCEPT_FUNCTION(getitimer); \
1864   COMMON_INTERCEPT_FUNCTION(setitimer);
1865 #else
1866 #define INIT_GETITIMER
1867 #endif
1868
1869 #if SANITIZER_INTERCEPT_GLOB
1870 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
1871   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
1872   // +1 for NULL pointer at the end.
1873   if (pglob->gl_pathv)
1874     COMMON_INTERCEPTOR_WRITE_RANGE(
1875         ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
1876   for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
1877     char *p = pglob->gl_pathv[i];
1878     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
1879   }
1880 }
1881
1882 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
1883
1884 static void wrapped_gl_closedir(void *dir) {
1885   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1886   pglob_copy->gl_closedir(dir);
1887 }
1888
1889 static void *wrapped_gl_readdir(void *dir) {
1890   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1891   return pglob_copy->gl_readdir(dir);
1892 }
1893
1894 static void *wrapped_gl_opendir(const char *s) {
1895   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1896   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1897   return pglob_copy->gl_opendir(s);
1898 }
1899
1900 static int wrapped_gl_lstat(const char *s, void *st) {
1901   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1902   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1903   return pglob_copy->gl_lstat(s, st);
1904 }
1905
1906 static int wrapped_gl_stat(const char *s, void *st) {
1907   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1908   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1909   return pglob_copy->gl_stat(s, st);
1910 }
1911
1912 static const __sanitizer_glob_t kGlobCopy = {
1913       0,                  0,                   0,
1914       0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1915       wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
1916
1917 INTERCEPTOR(int, glob, const char *pattern, int flags,
1918             int (*errfunc)(const char *epath, int eerrno),
1919             __sanitizer_glob_t *pglob) {
1920   void *ctx;
1921   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
1922   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1923   __sanitizer_glob_t glob_copy;
1924   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
1925   if (flags & glob_altdirfunc) {
1926     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1927     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1928     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1929     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1930     Swap(pglob->gl_stat, glob_copy.gl_stat);
1931     pglob_copy = &glob_copy;
1932   }
1933   int res = REAL(glob)(pattern, flags, errfunc, pglob);
1934   if (flags & glob_altdirfunc) {
1935     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1936     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1937     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1938     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1939     Swap(pglob->gl_stat, glob_copy.gl_stat);
1940   }
1941   pglob_copy = 0;
1942   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1943   return res;
1944 }
1945
1946 INTERCEPTOR(int, glob64, const char *pattern, int flags,
1947             int (*errfunc)(const char *epath, int eerrno),
1948             __sanitizer_glob_t *pglob) {
1949   void *ctx;
1950   COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
1951   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1952   __sanitizer_glob_t glob_copy;
1953   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
1954   if (flags & glob_altdirfunc) {
1955     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1956     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1957     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1958     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1959     Swap(pglob->gl_stat, glob_copy.gl_stat);
1960     pglob_copy = &glob_copy;
1961   }
1962   int res = REAL(glob64)(pattern, flags, errfunc, pglob);
1963   if (flags & glob_altdirfunc) {
1964     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1965     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1966     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1967     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1968     Swap(pglob->gl_stat, glob_copy.gl_stat);
1969   }
1970   pglob_copy = 0;
1971   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1972   return res;
1973 }
1974 #define INIT_GLOB                  \
1975   COMMON_INTERCEPT_FUNCTION(glob); \
1976   COMMON_INTERCEPT_FUNCTION(glob64);
1977 #else  // SANITIZER_INTERCEPT_GLOB
1978 #define INIT_GLOB
1979 #endif  // SANITIZER_INTERCEPT_GLOB
1980
1981 #if SANITIZER_INTERCEPT_WAIT
1982 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
1983 // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
1984 // details.
1985 INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
1986   void *ctx;
1987   COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
1988   // FIXME: under ASan the call below may write to freed memory and corrupt
1989   // its metadata. See
1990   // https://github.com/google/sanitizers/issues/321.
1991   int res = REAL(wait)(status);
1992   if (res != -1 && status)
1993     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1994   return res;
1995 }
1996 // On FreeBSD id_t is always 64-bit wide.
1997 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
1998 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
1999                         int options) {
2000 #else
2001 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
2002                         int options) {
2003 #endif
2004   void *ctx;
2005   COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
2006   // FIXME: under ASan the call below may write to freed memory and corrupt
2007   // its metadata. See
2008   // https://github.com/google/sanitizers/issues/321.
2009   int res = REAL(waitid)(idtype, id, infop, options);
2010   if (res != -1 && infop)
2011     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
2012   return res;
2013 }
2014 INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
2015   void *ctx;
2016   COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
2017   // FIXME: under ASan the call below may write to freed memory and corrupt
2018   // its metadata. See
2019   // https://github.com/google/sanitizers/issues/321.
2020   int res = REAL(waitpid)(pid, status, options);
2021   if (res != -1 && status)
2022     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2023   return res;
2024 }
2025 INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
2026   void *ctx;
2027   COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
2028   // FIXME: under ASan the call below may write to freed memory and corrupt
2029   // its metadata. See
2030   // https://github.com/google/sanitizers/issues/321.
2031   int res = REAL(wait3)(status, options, rusage);
2032   if (res != -1) {
2033     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2034     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2035   }
2036   return res;
2037 }
2038 #if SANITIZER_ANDROID
2039 INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
2040   void *ctx;
2041   COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
2042   // FIXME: under ASan the call below may write to freed memory and corrupt
2043   // its metadata. See
2044   // https://github.com/google/sanitizers/issues/321.
2045   int res = REAL(__wait4)(pid, status, options, rusage);
2046   if (res != -1) {
2047     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2048     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2049   }
2050   return res;
2051 }
2052 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
2053 #else
2054 INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
2055   void *ctx;
2056   COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
2057   // FIXME: under ASan the call below may write to freed memory and corrupt
2058   // its metadata. See
2059   // https://github.com/google/sanitizers/issues/321.
2060   int res = REAL(wait4)(pid, status, options, rusage);
2061   if (res != -1) {
2062     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2063     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2064   }
2065   return res;
2066 }
2067 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
2068 #endif  // SANITIZER_ANDROID
2069 #define INIT_WAIT                     \
2070   COMMON_INTERCEPT_FUNCTION(wait);    \
2071   COMMON_INTERCEPT_FUNCTION(waitid);  \
2072   COMMON_INTERCEPT_FUNCTION(waitpid); \
2073   COMMON_INTERCEPT_FUNCTION(wait3);
2074 #else
2075 #define INIT_WAIT
2076 #define INIT_WAIT4
2077 #endif
2078
2079 #if SANITIZER_INTERCEPT_INET
2080 INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
2081   void *ctx;
2082   COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
2083   uptr sz = __sanitizer_in_addr_sz(af);
2084   if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
2085   // FIXME: figure out read size based on the address family.
2086   // FIXME: under ASan the call below may write to freed memory and corrupt
2087   // its metadata. See
2088   // https://github.com/google/sanitizers/issues/321.
2089   char *res = REAL(inet_ntop)(af, src, dst, size);
2090   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2091   return res;
2092 }
2093 INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
2094   void *ctx;
2095   COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
2096   COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
2097   // FIXME: figure out read size based on the address family.
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(inet_pton)(af, src, dst);
2102   if (res == 1) {
2103     uptr sz = __sanitizer_in_addr_sz(af);
2104     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2105   }
2106   return res;
2107 }
2108 #define INIT_INET                       \
2109   COMMON_INTERCEPT_FUNCTION(inet_ntop); \
2110   COMMON_INTERCEPT_FUNCTION(inet_pton);
2111 #else
2112 #define INIT_INET
2113 #endif
2114
2115 #if SANITIZER_INTERCEPT_INET
2116 INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
2117   void *ctx;
2118   COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
2119   if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
2120   // FIXME: under ASan the call below may write to freed memory and corrupt
2121   // its metadata. See
2122   // https://github.com/google/sanitizers/issues/321.
2123   int res = REAL(inet_aton)(cp, dst);
2124   if (res != 0) {
2125     uptr sz = __sanitizer_in_addr_sz(af_inet);
2126     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2127   }
2128   return res;
2129 }
2130 #define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
2131 #else
2132 #define INIT_INET_ATON
2133 #endif
2134
2135 #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
2136 INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
2137   void *ctx;
2138   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
2139   // FIXME: under ASan the call below may write to freed memory and corrupt
2140   // its metadata. See
2141   // https://github.com/google/sanitizers/issues/321.
2142   int res = REAL(pthread_getschedparam)(thread, policy, param);
2143   if (res == 0) {
2144     if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
2145     if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
2146   }
2147   return res;
2148 }
2149 #define INIT_PTHREAD_GETSCHEDPARAM \
2150   COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
2151 #else
2152 #define INIT_PTHREAD_GETSCHEDPARAM
2153 #endif
2154
2155 #if SANITIZER_INTERCEPT_GETADDRINFO
2156 INTERCEPTOR(int, getaddrinfo, char *node, char *service,
2157             struct __sanitizer_addrinfo *hints,
2158             struct __sanitizer_addrinfo **out) {
2159   void *ctx;
2160   COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
2161   if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
2162   if (service)
2163     COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
2164   if (hints)
2165     COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
2166   // FIXME: under ASan the call below may write to freed memory and corrupt
2167   // its metadata. See
2168   // https://github.com/google/sanitizers/issues/321.
2169   int res = REAL(getaddrinfo)(node, service, hints, out);
2170   if (res == 0 && out) {
2171     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
2172     struct __sanitizer_addrinfo *p = *out;
2173     while (p) {
2174       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2175       if (p->ai_addr)
2176         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
2177       if (p->ai_canonname)
2178         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
2179                                        REAL(strlen)(p->ai_canonname) + 1);
2180       p = p->ai_next;
2181     }
2182   }
2183   return res;
2184 }
2185 #define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
2186 #else
2187 #define INIT_GETADDRINFO
2188 #endif
2189
2190 #if SANITIZER_INTERCEPT_GETNAMEINFO
2191 INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
2192             unsigned hostlen, char *serv, unsigned servlen, int flags) {
2193   void *ctx;
2194   COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
2195                            serv, servlen, flags);
2196   // FIXME: consider adding READ_RANGE(sockaddr, salen)
2197   // There is padding in in_addr that may make this too noisy
2198   // FIXME: under ASan the call below may write to freed memory and corrupt
2199   // its metadata. See
2200   // https://github.com/google/sanitizers/issues/321.
2201   int res =
2202       REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
2203   if (res == 0) {
2204     if (host && hostlen)
2205       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
2206     if (serv && servlen)
2207       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
2208   }
2209   return res;
2210 }
2211 #define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
2212 #else
2213 #define INIT_GETNAMEINFO
2214 #endif
2215
2216 #if SANITIZER_INTERCEPT_GETSOCKNAME
2217 INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
2218   void *ctx;
2219   COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
2220   COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2221   int addrlen_in = *addrlen;
2222   // FIXME: under ASan the call below may write to freed memory and corrupt
2223   // its metadata. See
2224   // https://github.com/google/sanitizers/issues/321.
2225   int res = REAL(getsockname)(sock_fd, addr, addrlen);
2226   if (res == 0) {
2227     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
2228   }
2229   return res;
2230 }
2231 #define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
2232 #else
2233 #define INIT_GETSOCKNAME
2234 #endif
2235
2236 #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2237 static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
2238   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
2239   if (h->h_name)
2240     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
2241   char **p = h->h_aliases;
2242   while (*p) {
2243     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
2244     ++p;
2245   }
2246   COMMON_INTERCEPTOR_WRITE_RANGE(
2247       ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
2248   p = h->h_addr_list;
2249   while (*p) {
2250     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
2251     ++p;
2252   }
2253   COMMON_INTERCEPTOR_WRITE_RANGE(
2254       ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
2255 }
2256 #endif
2257
2258 #if SANITIZER_INTERCEPT_GETHOSTBYNAME
2259 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
2260   void *ctx;
2261   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
2262   struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
2263   if (res) write_hostent(ctx, res);
2264   return res;
2265 }
2266
2267 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
2268             int type) {
2269   void *ctx;
2270   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
2271   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2272   struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
2273   if (res) write_hostent(ctx, res);
2274   return res;
2275 }
2276
2277 INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
2278   void *ctx;
2279   COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
2280   struct __sanitizer_hostent *res = REAL(gethostent)(fake);
2281   if (res) write_hostent(ctx, res);
2282   return res;
2283 }
2284
2285 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
2286   void *ctx;
2287   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
2288   struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
2289   if (res) write_hostent(ctx, res);
2290   return res;
2291 }
2292 #define INIT_GETHOSTBYNAME                  \
2293   COMMON_INTERCEPT_FUNCTION(gethostent);    \
2294   COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2295   COMMON_INTERCEPT_FUNCTION(gethostbyname); \
2296   COMMON_INTERCEPT_FUNCTION(gethostbyname2);
2297 #else
2298 #define INIT_GETHOSTBYNAME
2299 #endif
2300
2301 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2302 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
2303             char *buf, SIZE_T buflen, __sanitizer_hostent **result,
2304             int *h_errnop) {
2305   void *ctx;
2306   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
2307                            h_errnop);
2308   // FIXME: under ASan the call below may write to freed memory and corrupt
2309   // its metadata. See
2310   // https://github.com/google/sanitizers/issues/321.
2311   int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
2312   if (result) {
2313     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2314     if (res == 0 && *result) write_hostent(ctx, *result);
2315   }
2316   if (h_errnop)
2317     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2318   return res;
2319 }
2320 #define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
2321 #else
2322 #define INIT_GETHOSTBYNAME_R
2323 #endif
2324
2325 #if SANITIZER_INTERCEPT_GETHOSTENT_R
2326 INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
2327             SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
2328   void *ctx;
2329   COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
2330                            h_errnop);
2331   // FIXME: under ASan the call below may write to freed memory and corrupt
2332   // its metadata. See
2333   // https://github.com/google/sanitizers/issues/321.
2334   int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
2335   if (result) {
2336     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2337     if (res == 0 && *result) write_hostent(ctx, *result);
2338   }
2339   if (h_errnop)
2340     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2341   return res;
2342 }
2343 #define INIT_GETHOSTENT_R                  \
2344   COMMON_INTERCEPT_FUNCTION(gethostent_r);
2345 #else
2346 #define INIT_GETHOSTENT_R
2347 #endif
2348
2349 #if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
2350 INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
2351             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2352             __sanitizer_hostent **result, int *h_errnop) {
2353   void *ctx;
2354   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
2355                            buflen, result, h_errnop);
2356   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2357   // FIXME: under ASan the call below may write to freed memory and corrupt
2358   // its metadata. See
2359   // https://github.com/google/sanitizers/issues/321.
2360   int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
2361                                   h_errnop);
2362   if (result) {
2363     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2364     if (res == 0 && *result) write_hostent(ctx, *result);
2365   }
2366   if (h_errnop)
2367     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2368   return res;
2369 }
2370 #define INIT_GETHOSTBYADDR_R                  \
2371   COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
2372 #else
2373 #define INIT_GETHOSTBYADDR_R
2374 #endif
2375
2376 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
2377 INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
2378             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2379             __sanitizer_hostent **result, int *h_errnop) {
2380   void *ctx;
2381   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
2382                            result, h_errnop);
2383   // FIXME: under ASan the call below may write to freed memory and corrupt
2384   // its metadata. See
2385   // https://github.com/google/sanitizers/issues/321.
2386   int res =
2387       REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
2388   if (result) {
2389     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2390     if (res == 0 && *result) write_hostent(ctx, *result);
2391   }
2392   if (h_errnop)
2393     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2394   return res;
2395 }
2396 #define INIT_GETHOSTBYNAME2_R                  \
2397   COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
2398 #else
2399 #define INIT_GETHOSTBYNAME2_R
2400 #endif
2401
2402 #if SANITIZER_INTERCEPT_GETSOCKOPT
2403 INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
2404             int *optlen) {
2405   void *ctx;
2406   COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
2407                            optlen);
2408   if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
2409   // FIXME: under ASan the call below may write to freed memory and corrupt
2410   // its metadata. See
2411   // https://github.com/google/sanitizers/issues/321.
2412   int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
2413   if (res == 0)
2414     if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
2415   return res;
2416 }
2417 #define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
2418 #else
2419 #define INIT_GETSOCKOPT
2420 #endif
2421
2422 #if SANITIZER_INTERCEPT_ACCEPT
2423 INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
2424   void *ctx;
2425   COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
2426   unsigned addrlen0 = 0;
2427   if (addrlen) {
2428     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2429     addrlen0 = *addrlen;
2430   }
2431   int fd2 = REAL(accept)(fd, addr, addrlen);
2432   if (fd2 >= 0) {
2433     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2434     if (addr && addrlen)
2435       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2436   }
2437   return fd2;
2438 }
2439 #define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
2440 #else
2441 #define INIT_ACCEPT
2442 #endif
2443
2444 #if SANITIZER_INTERCEPT_ACCEPT4
2445 INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
2446   void *ctx;
2447   COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
2448   unsigned addrlen0 = 0;
2449   if (addrlen) {
2450     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2451     addrlen0 = *addrlen;
2452   }
2453   // FIXME: under ASan the call below may write to freed memory and corrupt
2454   // its metadata. See
2455   // https://github.com/google/sanitizers/issues/321.
2456   int fd2 = REAL(accept4)(fd, addr, addrlen, f);
2457   if (fd2 >= 0) {
2458     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2459     if (addr && addrlen)
2460       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2461   }
2462   return fd2;
2463 }
2464 #define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
2465 #else
2466 #define INIT_ACCEPT4
2467 #endif
2468
2469 #if SANITIZER_INTERCEPT_MODF
2470 INTERCEPTOR(double, modf, double x, double *iptr) {
2471   void *ctx;
2472   COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
2473   // FIXME: under ASan the call below may write to freed memory and corrupt
2474   // its metadata. See
2475   // https://github.com/google/sanitizers/issues/321.
2476   double res = REAL(modf)(x, iptr);
2477   if (iptr) {
2478     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2479   }
2480   return res;
2481 }
2482 INTERCEPTOR(float, modff, float x, float *iptr) {
2483   void *ctx;
2484   COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
2485   // FIXME: under ASan the call below may write to freed memory and corrupt
2486   // its metadata. See
2487   // https://github.com/google/sanitizers/issues/321.
2488   float res = REAL(modff)(x, iptr);
2489   if (iptr) {
2490     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2491   }
2492   return res;
2493 }
2494 INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2495   void *ctx;
2496   COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
2497   // FIXME: under ASan the call below may write to freed memory and corrupt
2498   // its metadata. See
2499   // https://github.com/google/sanitizers/issues/321.
2500   long double res = REAL(modfl)(x, iptr);
2501   if (iptr) {
2502     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2503   }
2504   return res;
2505 }
2506 #define INIT_MODF                   \
2507   COMMON_INTERCEPT_FUNCTION(modf);  \
2508   COMMON_INTERCEPT_FUNCTION(modff); \
2509   COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
2510 #else
2511 #define INIT_MODF
2512 #endif
2513
2514 #if SANITIZER_INTERCEPT_RECVMSG
2515 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2516                          SSIZE_T maxlen) {
2517   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2518   if (msg->msg_name && msg->msg_namelen)
2519     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2520   if (msg->msg_iov && msg->msg_iovlen)
2521     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2522                                    sizeof(*msg->msg_iov) * msg->msg_iovlen);
2523   write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2524   if (msg->msg_control && msg->msg_controllen)
2525     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
2526 }
2527
2528 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
2529             int flags) {
2530   void *ctx;
2531   COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
2532   // FIXME: under ASan the call below may write to freed memory and corrupt
2533   // its metadata. See
2534   // https://github.com/google/sanitizers/issues/321.
2535   SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
2536   if (res >= 0) {
2537     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
2538     if (msg) {
2539       write_msghdr(ctx, msg, res);
2540       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
2541     }
2542   }
2543   return res;
2544 }
2545 #define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
2546 #else
2547 #define INIT_RECVMSG
2548 #endif
2549
2550 #if SANITIZER_INTERCEPT_SENDMSG
2551 static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
2552   const unsigned kCmsgDataOffset =
2553       RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
2554
2555   char *p = (char *)control;
2556   char *const control_end = p + controllen;
2557   while (true) {
2558     if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
2559     __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
2560     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
2561
2562     if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
2563
2564     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
2565                                   sizeof(cmsg->cmsg_level));
2566     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
2567                                   sizeof(cmsg->cmsg_type));
2568
2569     if (cmsg->cmsg_len > kCmsgDataOffset) {
2570       char *data = p + kCmsgDataOffset;
2571       unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
2572       if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
2573     }
2574
2575     p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
2576   }
2577 }
2578
2579 static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2580                         SSIZE_T maxlen) {
2581 #define R(f) \
2582   COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
2583   R(name);
2584   R(namelen);
2585   R(iov);
2586   R(iovlen);
2587   R(control);
2588   R(controllen);
2589   R(flags);
2590 #undef R
2591   if (msg->msg_name && msg->msg_namelen)
2592     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2593   if (msg->msg_iov && msg->msg_iovlen)
2594     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
2595                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
2596   read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2597   if (msg->msg_control && msg->msg_controllen)
2598     read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
2599 }
2600
2601 INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
2602             int flags) {
2603   void *ctx;
2604   COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
2605   if (fd >= 0) {
2606     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
2607     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
2608   }
2609   SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
2610   if (common_flags()->intercept_send && res >= 0 && msg)
2611     read_msghdr(ctx, msg, res);
2612   return res;
2613 }
2614 #define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
2615 #else
2616 #define INIT_SENDMSG
2617 #endif
2618
2619 #if SANITIZER_INTERCEPT_GETPEERNAME
2620 INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
2621   void *ctx;
2622   COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
2623   unsigned addr_sz;
2624   if (addrlen) addr_sz = *addrlen;
2625   // FIXME: under ASan the call below may write to freed memory and corrupt
2626   // its metadata. See
2627   // https://github.com/google/sanitizers/issues/321.
2628   int res = REAL(getpeername)(sockfd, addr, addrlen);
2629   if (!res && addr && addrlen)
2630     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2631   return res;
2632 }
2633 #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
2634 #else
2635 #define INIT_GETPEERNAME
2636 #endif
2637
2638 #if SANITIZER_INTERCEPT_SYSINFO
2639 INTERCEPTOR(int, sysinfo, void *info) {
2640   void *ctx;
2641   // FIXME: under ASan the call below may write to freed memory and corrupt
2642   // its metadata. See
2643   // https://github.com/google/sanitizers/issues/321.
2644   COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
2645   int res = REAL(sysinfo)(info);
2646   if (!res && info)
2647     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
2648   return res;
2649 }
2650 #define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
2651 #else
2652 #define INIT_SYSINFO
2653 #endif
2654
2655 #if SANITIZER_INTERCEPT_READDIR
2656 INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
2657   void *ctx;
2658   COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
2659   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2660   __sanitizer_dirent *res = REAL(opendir)(path);
2661   if (res)
2662     COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
2663   return res;
2664 }
2665
2666 INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
2667   void *ctx;
2668   COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
2669   // FIXME: under ASan the call below may write to freed memory and corrupt
2670   // its metadata. See
2671   // https://github.com/google/sanitizers/issues/321.
2672   __sanitizer_dirent *res = REAL(readdir)(dirp);
2673   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2674   return res;
2675 }
2676
2677 INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
2678             __sanitizer_dirent **result) {
2679   void *ctx;
2680   COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
2681   // FIXME: under ASan the call below may write to freed memory and corrupt
2682   // its metadata. See
2683   // https://github.com/google/sanitizers/issues/321.
2684   int res = REAL(readdir_r)(dirp, entry, result);
2685   if (!res) {
2686     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2687     if (*result)
2688       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2689   }
2690   return res;
2691 }
2692
2693 #define INIT_READDIR                  \
2694   COMMON_INTERCEPT_FUNCTION(opendir); \
2695   COMMON_INTERCEPT_FUNCTION(readdir); \
2696   COMMON_INTERCEPT_FUNCTION(readdir_r);
2697 #else
2698 #define INIT_READDIR
2699 #endif
2700
2701 #if SANITIZER_INTERCEPT_READDIR64
2702 INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
2703   void *ctx;
2704   COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
2705   // FIXME: under ASan the call below may write to freed memory and corrupt
2706   // its metadata. See
2707   // https://github.com/google/sanitizers/issues/321.
2708   __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
2709   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2710   return res;
2711 }
2712
2713 INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
2714             __sanitizer_dirent64 **result) {
2715   void *ctx;
2716   COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
2717   // FIXME: under ASan the call below may write to freed memory and corrupt
2718   // its metadata. See
2719   // https://github.com/google/sanitizers/issues/321.
2720   int res = REAL(readdir64_r)(dirp, entry, result);
2721   if (!res) {
2722     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2723     if (*result)
2724       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2725   }
2726   return res;
2727 }
2728 #define INIT_READDIR64                  \
2729   COMMON_INTERCEPT_FUNCTION(readdir64); \
2730   COMMON_INTERCEPT_FUNCTION(readdir64_r);
2731 #else
2732 #define INIT_READDIR64
2733 #endif
2734
2735 #if SANITIZER_INTERCEPT_PTRACE
2736 INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
2737   void *ctx;
2738   COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
2739   __sanitizer_iovec local_iovec;
2740
2741   if (data) {
2742     if (request == ptrace_setregs)
2743       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
2744     else if (request == ptrace_setfpregs)
2745       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2746     else if (request == ptrace_setfpxregs)
2747       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2748     else if (request == ptrace_setvfpregs)
2749       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
2750     else if (request == ptrace_setsiginfo)
2751       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
2752     // Some kernel might zero the iovec::iov_base in case of invalid
2753     // write access.  In this case copy the invalid address for further
2754     // inspection.
2755     else if (request == ptrace_setregset || request == ptrace_getregset) {
2756       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2757       COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
2758       local_iovec = *iovec;
2759       if (request == ptrace_setregset)
2760         COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
2761     }
2762   }
2763
2764   // FIXME: under ASan the call below may write to freed memory and corrupt
2765   // its metadata. See
2766   // https://github.com/google/sanitizers/issues/321.
2767   uptr res = REAL(ptrace)(request, pid, addr, data);
2768
2769   if (!res && data) {
2770     // Note that PEEK* requests assign different meaning to the return value.
2771     // This function does not handle them (nor does it need to).
2772     if (request == ptrace_getregs)
2773       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
2774     else if (request == ptrace_getfpregs)
2775       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2776     else if (request == ptrace_getfpxregs)
2777       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2778     else if (request == ptrace_getvfpregs)
2779       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
2780     else if (request == ptrace_getsiginfo)
2781       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
2782     else if (request == ptrace_geteventmsg)
2783       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
2784     else if (request == ptrace_getregset) {
2785       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2786       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
2787       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
2788                                      local_iovec.iov_len);
2789     }
2790   }
2791   return res;
2792 }
2793
2794 #define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
2795 #else
2796 #define INIT_PTRACE
2797 #endif
2798
2799 #if SANITIZER_INTERCEPT_SETLOCALE
2800 INTERCEPTOR(char *, setlocale, int category, char *locale) {
2801   void *ctx;
2802   COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
2803   if (locale)
2804     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
2805   char *res = REAL(setlocale)(category, locale);
2806   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2807   return res;
2808 }
2809
2810 #define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
2811 #else
2812 #define INIT_SETLOCALE
2813 #endif
2814
2815 #if SANITIZER_INTERCEPT_GETCWD
2816 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
2817   void *ctx;
2818   COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
2819   // FIXME: under ASan the call below may write to freed memory and corrupt
2820   // its metadata. See
2821   // https://github.com/google/sanitizers/issues/321.
2822   char *res = REAL(getcwd)(buf, size);
2823   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2824   return res;
2825 }
2826 #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
2827 #else
2828 #define INIT_GETCWD
2829 #endif
2830
2831 #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
2832 INTERCEPTOR(char *, get_current_dir_name, int fake) {
2833   void *ctx;
2834   COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
2835   // FIXME: under ASan the call below may write to freed memory and corrupt
2836   // its metadata. See
2837   // https://github.com/google/sanitizers/issues/321.
2838   char *res = REAL(get_current_dir_name)(fake);
2839   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2840   return res;
2841 }
2842
2843 #define INIT_GET_CURRENT_DIR_NAME \
2844   COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
2845 #else
2846 #define INIT_GET_CURRENT_DIR_NAME
2847 #endif
2848
2849 UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
2850   CHECK(endptr);
2851   if (nptr == *endptr) {
2852     // No digits were found at strtol call, we need to find out the last
2853     // symbol accessed by strtoll on our own.
2854     // We get this symbol by skipping leading blanks and optional +/- sign.
2855     while (IsSpace(*nptr)) nptr++;
2856     if (*nptr == '+' || *nptr == '-') nptr++;
2857     *endptr = const_cast<char *>(nptr);
2858   }
2859   CHECK(*endptr >= nptr);
2860 }
2861
2862 UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
2863                              char **endptr, char *real_endptr, int base) {
2864   if (endptr) {
2865     *endptr = real_endptr;
2866     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2867   }
2868   // If base has unsupported value, strtol can exit with EINVAL
2869   // without reading any characters. So do additional checks only
2870   // if base is valid.
2871   bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
2872   if (is_valid_base) {
2873     FixRealStrtolEndptr(nptr, &real_endptr);
2874   }
2875   COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
2876                                  (real_endptr - nptr) + 1 : 0);
2877 }
2878
2879
2880 #if SANITIZER_INTERCEPT_STRTOIMAX
2881 INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
2882   void *ctx;
2883   COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
2884   // FIXME: under ASan the call below may write to freed memory and corrupt
2885   // its metadata. See
2886   // https://github.com/google/sanitizers/issues/321.
2887   char *real_endptr;
2888   INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
2889   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2890   return res;
2891 }
2892
2893 INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
2894   void *ctx;
2895   COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
2896   // FIXME: under ASan the call below may write to freed memory and corrupt
2897   // its metadata. See
2898   // https://github.com/google/sanitizers/issues/321.
2899   char *real_endptr;
2900   INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
2901   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2902   return res;
2903 }
2904
2905 #define INIT_STRTOIMAX                  \
2906   COMMON_INTERCEPT_FUNCTION(strtoimax); \
2907   COMMON_INTERCEPT_FUNCTION(strtoumax);
2908 #else
2909 #define INIT_STRTOIMAX
2910 #endif
2911
2912 #if SANITIZER_INTERCEPT_MBSTOWCS
2913 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
2914   void *ctx;
2915   COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
2916   // FIXME: under ASan the call below may write to freed memory and corrupt
2917   // its metadata. See
2918   // https://github.com/google/sanitizers/issues/321.
2919   SIZE_T res = REAL(mbstowcs)(dest, src, len);
2920   if (res != (SIZE_T) - 1 && dest) {
2921     SIZE_T write_cnt = res + (res < len);
2922     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2923   }
2924   return res;
2925 }
2926
2927 INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
2928             void *ps) {
2929   void *ctx;
2930   COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
2931   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2932   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2933   // FIXME: under ASan the call below may write to freed memory and corrupt
2934   // its metadata. See
2935   // https://github.com/google/sanitizers/issues/321.
2936   SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
2937   if (res != (SIZE_T)(-1) && dest && src) {
2938     // This function, and several others, may or may not write the terminating
2939     // \0 character. They write it iff they clear *src.
2940     SIZE_T write_cnt = res + !*src;
2941     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2942   }
2943   return res;
2944 }
2945
2946 #define INIT_MBSTOWCS                  \
2947   COMMON_INTERCEPT_FUNCTION(mbstowcs); \
2948   COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
2949 #else
2950 #define INIT_MBSTOWCS
2951 #endif
2952
2953 #if SANITIZER_INTERCEPT_MBSNRTOWCS
2954 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
2955             SIZE_T len, void *ps) {
2956   void *ctx;
2957   COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
2958   if (src) {
2959     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2960     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2961   }
2962   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2963   // FIXME: under ASan the call below may write to freed memory and corrupt
2964   // its metadata. See
2965   // https://github.com/google/sanitizers/issues/321.
2966   SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
2967   if (res != (SIZE_T)(-1) && dest && src) {
2968     SIZE_T write_cnt = res + !*src;
2969     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2970   }
2971   return res;
2972 }
2973
2974 #define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
2975 #else
2976 #define INIT_MBSNRTOWCS
2977 #endif
2978
2979 #if SANITIZER_INTERCEPT_WCSTOMBS
2980 INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
2981   void *ctx;
2982   COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
2983   // FIXME: under ASan the call below may write to freed memory and corrupt
2984   // its metadata. See
2985   // https://github.com/google/sanitizers/issues/321.
2986   SIZE_T res = REAL(wcstombs)(dest, src, len);
2987   if (res != (SIZE_T) - 1 && dest) {
2988     SIZE_T write_cnt = res + (res < len);
2989     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2990   }
2991   return res;
2992 }
2993
2994 INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
2995             void *ps) {
2996   void *ctx;
2997   COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
2998   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2999   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3000   // FIXME: under ASan the call below may write to freed memory and corrupt
3001   // its metadata. See
3002   // https://github.com/google/sanitizers/issues/321.
3003   SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
3004   if (res != (SIZE_T) - 1 && dest && src) {
3005     SIZE_T write_cnt = res + !*src;
3006     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3007   }
3008   return res;
3009 }
3010
3011 #define INIT_WCSTOMBS                  \
3012   COMMON_INTERCEPT_FUNCTION(wcstombs); \
3013   COMMON_INTERCEPT_FUNCTION(wcsrtombs);
3014 #else
3015 #define INIT_WCSTOMBS
3016 #endif
3017
3018 #if SANITIZER_INTERCEPT_WCSNRTOMBS
3019 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
3020             SIZE_T len, void *ps) {
3021   void *ctx;
3022   COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
3023   if (src) {
3024     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3025     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3026   }
3027   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3028   // FIXME: under ASan the call below may write to freed memory and corrupt
3029   // its metadata. See
3030   // https://github.com/google/sanitizers/issues/321.
3031   SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
3032   if (res != ((SIZE_T)-1) && dest && src) {
3033     SIZE_T write_cnt = res + !*src;
3034     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3035   }
3036   return res;
3037 }
3038
3039 #define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
3040 #else
3041 #define INIT_WCSNRTOMBS
3042 #endif
3043
3044
3045 #if SANITIZER_INTERCEPT_WCRTOMB
3046 INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
3047   void *ctx;
3048   COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
3049   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3050   // FIXME: under ASan the call below may write to freed memory and corrupt
3051   // its metadata. See
3052   // https://github.com/google/sanitizers/issues/321.
3053   SIZE_T res = REAL(wcrtomb)(dest, src, ps);
3054   if (res != ((SIZE_T)-1) && dest) {
3055     SIZE_T write_cnt = res;
3056     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3057   }
3058   return res;
3059 }
3060
3061 #define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
3062 #else
3063 #define INIT_WCRTOMB
3064 #endif
3065
3066 #if SANITIZER_INTERCEPT_TCGETATTR
3067 INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
3068   void *ctx;
3069   COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
3070   // FIXME: under ASan the call below may write to freed memory and corrupt
3071   // its metadata. See
3072   // https://github.com/google/sanitizers/issues/321.
3073   int res = REAL(tcgetattr)(fd, termios_p);
3074   if (!res && termios_p)
3075     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
3076   return res;
3077 }
3078
3079 #define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
3080 #else
3081 #define INIT_TCGETATTR
3082 #endif
3083
3084 #if SANITIZER_INTERCEPT_REALPATH
3085 INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
3086   void *ctx;
3087   COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
3088   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3089
3090   // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
3091   // version of a versioned symbol. For realpath(), this gives us something
3092   // (called __old_realpath) that does not handle NULL in the second argument.
3093   // Handle it as part of the interceptor.
3094   char *allocated_path = nullptr;
3095   if (!resolved_path)
3096     allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
3097
3098   char *res = REAL(realpath)(path, resolved_path);
3099   if (allocated_path && !res) WRAP(free)(allocated_path);
3100   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3101   return res;
3102 }
3103 #define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
3104 #else
3105 #define INIT_REALPATH
3106 #endif
3107
3108 #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
3109 INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
3110   void *ctx;
3111   COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
3112   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3113   char *res = REAL(canonicalize_file_name)(path);
3114   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3115   return res;
3116 }
3117 #define INIT_CANONICALIZE_FILE_NAME \
3118   COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
3119 #else
3120 #define INIT_CANONICALIZE_FILE_NAME
3121 #endif
3122
3123 #if SANITIZER_INTERCEPT_CONFSTR
3124 INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
3125   void *ctx;
3126   COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
3127   // FIXME: under ASan the call below may write to freed memory and corrupt
3128   // its metadata. See
3129   // https://github.com/google/sanitizers/issues/321.
3130   SIZE_T res = REAL(confstr)(name, buf, len);
3131   if (buf && res)
3132     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
3133   return res;
3134 }
3135 #define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
3136 #else
3137 #define INIT_CONFSTR
3138 #endif
3139
3140 #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
3141 INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
3142   void *ctx;
3143   COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
3144   // FIXME: under ASan the call below may write to freed memory and corrupt
3145   // its metadata. See
3146   // https://github.com/google/sanitizers/issues/321.
3147   int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
3148   if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
3149   return res;
3150 }
3151 #define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
3152 #else
3153 #define INIT_SCHED_GETAFFINITY
3154 #endif
3155
3156 #if SANITIZER_INTERCEPT_SCHED_GETPARAM
3157 INTERCEPTOR(int, sched_getparam, int pid, void *param) {
3158   void *ctx;
3159   COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
3160   int res = REAL(sched_getparam)(pid, param);
3161   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
3162   return res;
3163 }
3164 #define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
3165 #else
3166 #define INIT_SCHED_GETPARAM
3167 #endif
3168
3169 #if SANITIZER_INTERCEPT_STRERROR
3170 INTERCEPTOR(char *, strerror, int errnum) {
3171   void *ctx;
3172   COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
3173   char *res = REAL(strerror)(errnum);
3174   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3175   return res;
3176 }
3177 #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
3178 #else
3179 #define INIT_STRERROR
3180 #endif
3181
3182 #if SANITIZER_INTERCEPT_STRERROR_R
3183 INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
3184   void *ctx;
3185   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
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   char *res = REAL(strerror_r)(errnum, buf, buflen);
3190   // There are 2 versions of strerror_r:
3191   //  * POSIX version returns 0 on success, negative error code on failure,
3192   //    writes message to buf.
3193   //  * GNU version returns message pointer, which points to either buf or some
3194   //    static storage.
3195   SIZE_T posix_res = (SIZE_T)res;
3196   if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
3197     // POSIX version. Spec is not clear on whether buf is NULL-terminated.
3198     // At least on OSX, buf contents are valid even when the call fails.
3199     SIZE_T sz = internal_strnlen(buf, buflen);
3200     if (sz < buflen) ++sz;
3201     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3202   } else {
3203     // GNU version.
3204     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3205   }
3206   return res;
3207 }
3208 #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
3209 #else
3210 #define INIT_STRERROR_R
3211 #endif
3212
3213 #if SANITIZER_INTERCEPT_XPG_STRERROR_R
3214 INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
3215   void *ctx;
3216   COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
3217   // FIXME: under ASan the call below may write to freed memory and corrupt
3218   // its metadata. See
3219   // https://github.com/google/sanitizers/issues/321.
3220   int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
3221   // This version always returns a null-terminated string.
3222   if (buf && buflen)
3223     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3224   return res;
3225 }
3226 #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
3227 #else
3228 #define INIT_XPG_STRERROR_R
3229 #endif
3230
3231 #if SANITIZER_INTERCEPT_SCANDIR
3232 typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
3233 typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
3234                                 const struct __sanitizer_dirent **);
3235
3236 static THREADLOCAL scandir_filter_f scandir_filter;
3237 static THREADLOCAL scandir_compar_f scandir_compar;
3238
3239 static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
3240   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3241   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3242   return scandir_filter(dir);
3243 }
3244
3245 static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
3246                                   const struct __sanitizer_dirent **b) {
3247   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3248   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3249   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3250   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3251   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3252   return scandir_compar(a, b);
3253 }
3254
3255 INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
3256             scandir_filter_f filter, scandir_compar_f compar) {
3257   void *ctx;
3258   COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
3259   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3260   scandir_filter = filter;
3261   scandir_compar = compar;
3262   // FIXME: under ASan the call below may write to freed memory and corrupt
3263   // its metadata. See
3264   // https://github.com/google/sanitizers/issues/321.
3265   int res = REAL(scandir)(dirp, namelist,
3266                           filter ? wrapped_scandir_filter : nullptr,
3267                           compar ? wrapped_scandir_compar : nullptr);
3268   scandir_filter = nullptr;
3269   scandir_compar = nullptr;
3270   if (namelist && res > 0) {
3271     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3272     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3273     for (int i = 0; i < res; ++i)
3274       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3275                                      (*namelist)[i]->d_reclen);
3276   }
3277   return res;
3278 }
3279 #define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
3280 #else
3281 #define INIT_SCANDIR
3282 #endif
3283
3284 #if SANITIZER_INTERCEPT_SCANDIR64
3285 typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
3286 typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
3287                                   const struct __sanitizer_dirent64 **);
3288
3289 static THREADLOCAL scandir64_filter_f scandir64_filter;
3290 static THREADLOCAL scandir64_compar_f scandir64_compar;
3291
3292 static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
3293   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3294   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3295   return scandir64_filter(dir);
3296 }
3297
3298 static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
3299                                     const struct __sanitizer_dirent64 **b) {
3300   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3301   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3302   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3303   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3304   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3305   return scandir64_compar(a, b);
3306 }
3307
3308 INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
3309             scandir64_filter_f filter, scandir64_compar_f compar) {
3310   void *ctx;
3311   COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
3312   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3313   scandir64_filter = filter;
3314   scandir64_compar = compar;
3315   // FIXME: under ASan the call below may write to freed memory and corrupt
3316   // its metadata. See
3317   // https://github.com/google/sanitizers/issues/321.
3318   int res =
3319       REAL(scandir64)(dirp, namelist,
3320                       filter ? wrapped_scandir64_filter : nullptr,
3321                       compar ? wrapped_scandir64_compar : nullptr);
3322   scandir64_filter = nullptr;
3323   scandir64_compar = nullptr;
3324   if (namelist && res > 0) {
3325     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3326     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3327     for (int i = 0; i < res; ++i)
3328       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3329                                      (*namelist)[i]->d_reclen);
3330   }
3331   return res;
3332 }
3333 #define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
3334 #else
3335 #define INIT_SCANDIR64
3336 #endif
3337
3338 #if SANITIZER_INTERCEPT_GETGROUPS
3339 INTERCEPTOR(int, getgroups, int size, u32 *lst) {
3340   void *ctx;
3341   COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
3342   // FIXME: under ASan the call below may write to freed memory and corrupt
3343   // its metadata. See
3344   // https://github.com/google/sanitizers/issues/321.
3345   int res = REAL(getgroups)(size, lst);
3346   if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
3347   return res;
3348 }
3349 #define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
3350 #else
3351 #define INIT_GETGROUPS
3352 #endif
3353
3354 #if SANITIZER_INTERCEPT_POLL
3355 static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
3356                         __sanitizer_nfds_t nfds) {
3357   for (unsigned i = 0; i < nfds; ++i) {
3358     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
3359     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
3360   }
3361 }
3362
3363 static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
3364                          __sanitizer_nfds_t nfds) {
3365   for (unsigned i = 0; i < nfds; ++i)
3366     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
3367                                    sizeof(fds[i].revents));
3368 }
3369
3370 INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3371             int timeout) {
3372   void *ctx;
3373   COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
3374   if (fds && nfds) read_pollfd(ctx, fds, nfds);
3375   int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
3376   if (fds && nfds) write_pollfd(ctx, fds, nfds);
3377   return res;
3378 }
3379 #define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
3380 #else
3381 #define INIT_POLL
3382 #endif
3383
3384 #if SANITIZER_INTERCEPT_PPOLL
3385 INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3386             void *timeout_ts, __sanitizer_sigset_t *sigmask) {
3387   void *ctx;
3388   COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
3389   if (fds && nfds) read_pollfd(ctx, fds, nfds);
3390   if (timeout_ts)
3391     COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
3392   // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
3393   int res =
3394       COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
3395   if (fds && nfds) write_pollfd(ctx, fds, nfds);
3396   return res;
3397 }
3398 #define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
3399 #else
3400 #define INIT_PPOLL
3401 #endif
3402
3403 #if SANITIZER_INTERCEPT_WORDEXP
3404 INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
3405   void *ctx;
3406   COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
3407   if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
3408   // FIXME: under ASan the call below may write to freed memory and corrupt
3409   // its metadata. See
3410   // https://github.com/google/sanitizers/issues/321.
3411   int res = REAL(wordexp)(s, p, flags);
3412   if (!res && p) {
3413     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
3414     if (p->we_wordc)
3415       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
3416                                      sizeof(*p->we_wordv) * p->we_wordc);
3417     for (uptr i = 0; i < p->we_wordc; ++i) {
3418       char *w = p->we_wordv[i];
3419       if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
3420     }
3421   }
3422   return res;
3423 }
3424 #define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
3425 #else
3426 #define INIT_WORDEXP
3427 #endif
3428
3429 #if SANITIZER_INTERCEPT_SIGWAIT
3430 INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
3431   void *ctx;
3432   COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
3433   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3434   // FIXME: under ASan the call below may write to freed memory and corrupt
3435   // its metadata. See
3436   // https://github.com/google/sanitizers/issues/321.
3437   int res = REAL(sigwait)(set, sig);
3438   if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
3439   return res;
3440 }
3441 #define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
3442 #else
3443 #define INIT_SIGWAIT
3444 #endif
3445
3446 #if SANITIZER_INTERCEPT_SIGWAITINFO
3447 INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
3448   void *ctx;
3449   COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
3450   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3451   // FIXME: under ASan the call below may write to freed memory and corrupt
3452   // its metadata. See
3453   // https://github.com/google/sanitizers/issues/321.
3454   int res = REAL(sigwaitinfo)(set, info);
3455   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3456   return res;
3457 }
3458 #define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
3459 #else
3460 #define INIT_SIGWAITINFO
3461 #endif
3462
3463 #if SANITIZER_INTERCEPT_SIGTIMEDWAIT
3464 INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
3465             void *timeout) {
3466   void *ctx;
3467   COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
3468   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
3469   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3470   // FIXME: under ASan the call below may write to freed memory and corrupt
3471   // its metadata. See
3472   // https://github.com/google/sanitizers/issues/321.
3473   int res = REAL(sigtimedwait)(set, info, timeout);
3474   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3475   return res;
3476 }
3477 #define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
3478 #else
3479 #define INIT_SIGTIMEDWAIT
3480 #endif
3481
3482 #if SANITIZER_INTERCEPT_SIGSETOPS
3483 INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
3484   void *ctx;
3485   COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
3486   // FIXME: under ASan the call below may write to freed memory and corrupt
3487   // its metadata. See
3488   // https://github.com/google/sanitizers/issues/321.
3489   int res = REAL(sigemptyset)(set);
3490   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3491   return res;
3492 }
3493
3494 INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
3495   void *ctx;
3496   COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
3497   // FIXME: under ASan the call below may write to freed memory and corrupt
3498   // its metadata. See
3499   // https://github.com/google/sanitizers/issues/321.
3500   int res = REAL(sigfillset)(set);
3501   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3502   return res;
3503 }
3504 #define INIT_SIGSETOPS                    \
3505   COMMON_INTERCEPT_FUNCTION(sigemptyset); \
3506   COMMON_INTERCEPT_FUNCTION(sigfillset);
3507 #else
3508 #define INIT_SIGSETOPS
3509 #endif
3510
3511 #if SANITIZER_INTERCEPT_SIGPENDING
3512 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
3513   void *ctx;
3514   COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
3515   // FIXME: under ASan the call below may write to freed memory and corrupt
3516   // its metadata. See
3517   // https://github.com/google/sanitizers/issues/321.
3518   int res = REAL(sigpending)(set);
3519   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3520   return res;
3521 }
3522 #define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
3523 #else
3524 #define INIT_SIGPENDING
3525 #endif
3526
3527 #if SANITIZER_INTERCEPT_SIGPROCMASK
3528 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
3529             __sanitizer_sigset_t *oldset) {
3530   void *ctx;
3531   COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
3532   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3533   // FIXME: under ASan the call below may write to freed memory and corrupt
3534   // its metadata. See
3535   // https://github.com/google/sanitizers/issues/321.
3536   int res = REAL(sigprocmask)(how, set, oldset);
3537   if (!res && oldset)
3538     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
3539   return res;
3540 }
3541 #define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
3542 #else
3543 #define INIT_SIGPROCMASK
3544 #endif
3545
3546 #if SANITIZER_INTERCEPT_BACKTRACE
3547 INTERCEPTOR(int, backtrace, void **buffer, int size) {
3548   void *ctx;
3549   COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
3550   // FIXME: under ASan the call below may write to freed memory and corrupt
3551   // its metadata. See
3552   // https://github.com/google/sanitizers/issues/321.
3553   int res = REAL(backtrace)(buffer, size);
3554   if (res && buffer)
3555     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
3556   return res;
3557 }
3558
3559 INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
3560   void *ctx;
3561   COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
3562   if (buffer && size)
3563     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
3564   // FIXME: under ASan the call below may write to freed memory and corrupt
3565   // its metadata. See
3566   // https://github.com/google/sanitizers/issues/321.
3567   char **res = REAL(backtrace_symbols)(buffer, size);
3568   if (res && size) {
3569     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
3570     for (int i = 0; i < size; ++i)
3571       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
3572   }
3573   return res;
3574 }
3575 #define INIT_BACKTRACE                  \
3576   COMMON_INTERCEPT_FUNCTION(backtrace); \
3577   COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
3578 #else
3579 #define INIT_BACKTRACE
3580 #endif
3581
3582 #if SANITIZER_INTERCEPT__EXIT
3583 INTERCEPTOR(void, _exit, int status) {
3584   void *ctx;
3585   COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
3586   COMMON_INTERCEPTOR_USER_CALLBACK_START();
3587   int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
3588   COMMON_INTERCEPTOR_USER_CALLBACK_END();
3589   if (status == 0) status = status1;
3590   REAL(_exit)(status);
3591 }
3592 #define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
3593 #else
3594 #define INIT__EXIT
3595 #endif
3596
3597 #if SANITIZER_INTERCEPT_PHTREAD_MUTEX
3598 INTERCEPTOR(int, pthread_mutex_lock, void *m) {
3599   void *ctx;
3600   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
3601   int res = REAL(pthread_mutex_lock)(m);
3602   if (res == errno_EOWNERDEAD)
3603     COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
3604   if (res == 0 || res == errno_EOWNERDEAD)
3605     COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
3606   if (res == errno_EINVAL)
3607     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
3608   return res;
3609 }
3610
3611 INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
3612   void *ctx;
3613   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
3614   COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
3615   int res = REAL(pthread_mutex_unlock)(m);
3616   if (res == errno_EINVAL)
3617     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
3618   return res;
3619 }
3620
3621 #define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
3622 #define INIT_PTHREAD_MUTEX_UNLOCK \
3623   COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
3624 #else
3625 #define INIT_PTHREAD_MUTEX_LOCK
3626 #define INIT_PTHREAD_MUTEX_UNLOCK
3627 #endif
3628
3629 #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
3630 static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
3631   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
3632   if (mnt->mnt_fsname)
3633     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
3634                                    REAL(strlen)(mnt->mnt_fsname) + 1);
3635   if (mnt->mnt_dir)
3636     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
3637                                    REAL(strlen)(mnt->mnt_dir) + 1);
3638   if (mnt->mnt_type)
3639     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
3640                                    REAL(strlen)(mnt->mnt_type) + 1);
3641   if (mnt->mnt_opts)
3642     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
3643                                    REAL(strlen)(mnt->mnt_opts) + 1);
3644 }
3645 #endif
3646
3647 #if SANITIZER_INTERCEPT_GETMNTENT
3648 INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
3649   void *ctx;
3650   COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
3651   __sanitizer_mntent *res = REAL(getmntent)(fp);
3652   if (res) write_mntent(ctx, res);
3653   return res;
3654 }
3655 #define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
3656 #else
3657 #define INIT_GETMNTENT
3658 #endif
3659
3660 #if SANITIZER_INTERCEPT_GETMNTENT_R
3661 INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
3662             __sanitizer_mntent *mntbuf, char *buf, int buflen) {
3663   void *ctx;
3664   COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
3665   __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
3666   if (res) write_mntent(ctx, res);
3667   return res;
3668 }
3669 #define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
3670 #else
3671 #define INIT_GETMNTENT_R
3672 #endif
3673
3674 #if SANITIZER_INTERCEPT_STATFS
3675 INTERCEPTOR(int, statfs, char *path, void *buf) {
3676   void *ctx;
3677   COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
3678   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3679   // FIXME: under ASan the call below may write to freed memory and corrupt
3680   // its metadata. See
3681   // https://github.com/google/sanitizers/issues/321.
3682   int res = REAL(statfs)(path, buf);
3683   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3684   return res;
3685 }
3686 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
3687   void *ctx;
3688   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
3689   // FIXME: under ASan the call below may write to freed memory and corrupt
3690   // its metadata. See
3691   // https://github.com/google/sanitizers/issues/321.
3692   int res = REAL(fstatfs)(fd, buf);
3693   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3694   return res;
3695 }
3696 #define INIT_STATFS                  \
3697   COMMON_INTERCEPT_FUNCTION(statfs); \
3698   COMMON_INTERCEPT_FUNCTION(fstatfs);
3699 #else
3700 #define INIT_STATFS
3701 #endif
3702
3703 #if SANITIZER_INTERCEPT_STATFS64
3704 INTERCEPTOR(int, statfs64, char *path, void *buf) {
3705   void *ctx;
3706   COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
3707   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3708   // FIXME: under ASan the call below may write to freed memory and corrupt
3709   // its metadata. See
3710   // https://github.com/google/sanitizers/issues/321.
3711   int res = REAL(statfs64)(path, buf);
3712   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3713   return res;
3714 }
3715 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
3716   void *ctx;
3717   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
3718   // FIXME: under ASan the call below may write to freed memory and corrupt
3719   // its metadata. See
3720   // https://github.com/google/sanitizers/issues/321.
3721   int res = REAL(fstatfs64)(fd, buf);
3722   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3723   return res;
3724 }
3725 #define INIT_STATFS64                  \
3726   COMMON_INTERCEPT_FUNCTION(statfs64); \
3727   COMMON_INTERCEPT_FUNCTION(fstatfs64);
3728 #else
3729 #define INIT_STATFS64
3730 #endif
3731
3732 #if SANITIZER_INTERCEPT_STATVFS
3733 INTERCEPTOR(int, statvfs, char *path, void *buf) {
3734   void *ctx;
3735   COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
3736   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3737   // FIXME: under ASan the call below may write to freed memory and corrupt
3738   // its metadata. See
3739   // https://github.com/google/sanitizers/issues/321.
3740   int res = REAL(statvfs)(path, buf);
3741   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3742   return res;
3743 }
3744 INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
3745   void *ctx;
3746   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
3747   // FIXME: under ASan the call below may write to freed memory and corrupt
3748   // its metadata. See
3749   // https://github.com/google/sanitizers/issues/321.
3750   int res = REAL(fstatvfs)(fd, buf);
3751   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3752   return res;
3753 }
3754 #define INIT_STATVFS                  \
3755   COMMON_INTERCEPT_FUNCTION(statvfs); \
3756   COMMON_INTERCEPT_FUNCTION(fstatvfs);
3757 #else
3758 #define INIT_STATVFS
3759 #endif
3760
3761 #if SANITIZER_INTERCEPT_STATVFS64
3762 INTERCEPTOR(int, statvfs64, char *path, void *buf) {
3763   void *ctx;
3764   COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
3765   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3766   // FIXME: under ASan the call below may write to freed memory and corrupt
3767   // its metadata. See
3768   // https://github.com/google/sanitizers/issues/321.
3769   int res = REAL(statvfs64)(path, buf);
3770   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3771   return res;
3772 }
3773 INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
3774   void *ctx;
3775   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
3776   // FIXME: under ASan the call below may write to freed memory and corrupt
3777   // its metadata. See
3778   // https://github.com/google/sanitizers/issues/321.
3779   int res = REAL(fstatvfs64)(fd, buf);
3780   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3781   return res;
3782 }
3783 #define INIT_STATVFS64                  \
3784   COMMON_INTERCEPT_FUNCTION(statvfs64); \
3785   COMMON_INTERCEPT_FUNCTION(fstatvfs64);
3786 #else
3787 #define INIT_STATVFS64
3788 #endif
3789
3790 #if SANITIZER_INTERCEPT_INITGROUPS
3791 INTERCEPTOR(int, initgroups, char *user, u32 group) {
3792   void *ctx;
3793   COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
3794   if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
3795   int res = REAL(initgroups)(user, group);
3796   return res;
3797 }
3798 #define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
3799 #else
3800 #define INIT_INITGROUPS
3801 #endif
3802
3803 #if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
3804 INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
3805   void *ctx;
3806   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
3807   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3808   char *res = REAL(ether_ntoa)(addr);
3809   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3810   return res;
3811 }
3812 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
3813   void *ctx;
3814   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
3815   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3816   __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
3817   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
3818   return res;
3819 }
3820 #define INIT_ETHER_NTOA_ATON             \
3821   COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
3822   COMMON_INTERCEPT_FUNCTION(ether_aton);
3823 #else
3824 #define INIT_ETHER_NTOA_ATON
3825 #endif
3826
3827 #if SANITIZER_INTERCEPT_ETHER_HOST
3828 INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
3829   void *ctx;
3830   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
3831   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3832   // FIXME: under ASan the call below may write to freed memory and corrupt
3833   // its metadata. See
3834   // https://github.com/google/sanitizers/issues/321.
3835   int res = REAL(ether_ntohost)(hostname, addr);
3836   if (!res && hostname)
3837     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3838   return res;
3839 }
3840 INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
3841   void *ctx;
3842   COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
3843   if (hostname)
3844     COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3845   // FIXME: under ASan the call below may write to freed memory and corrupt
3846   // its metadata. See
3847   // https://github.com/google/sanitizers/issues/321.
3848   int res = REAL(ether_hostton)(hostname, addr);
3849   if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3850   return res;
3851 }
3852 INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
3853             char *hostname) {
3854   void *ctx;
3855   COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
3856   if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
3857   // FIXME: under ASan the call below may write to freed memory and corrupt
3858   // its metadata. See
3859   // https://github.com/google/sanitizers/issues/321.
3860   int res = REAL(ether_line)(line, addr, hostname);
3861   if (!res) {
3862     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3863     if (hostname)
3864       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3865   }
3866   return res;
3867 }
3868 #define INIT_ETHER_HOST                     \
3869   COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
3870   COMMON_INTERCEPT_FUNCTION(ether_hostton); \
3871   COMMON_INTERCEPT_FUNCTION(ether_line);
3872 #else
3873 #define INIT_ETHER_HOST
3874 #endif
3875
3876 #if SANITIZER_INTERCEPT_ETHER_R
3877 INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
3878   void *ctx;
3879   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
3880   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3881   // FIXME: under ASan the call below may write to freed memory and corrupt
3882   // its metadata. See
3883   // https://github.com/google/sanitizers/issues/321.
3884   char *res = REAL(ether_ntoa_r)(addr, buf);
3885   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3886   return res;
3887 }
3888 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
3889             __sanitizer_ether_addr *addr) {
3890   void *ctx;
3891   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
3892   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3893   // FIXME: under ASan the call below may write to freed memory and corrupt
3894   // its metadata. See
3895   // https://github.com/google/sanitizers/issues/321.
3896   __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
3897   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
3898   return res;
3899 }
3900 #define INIT_ETHER_R                       \
3901   COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
3902   COMMON_INTERCEPT_FUNCTION(ether_aton_r);
3903 #else
3904 #define INIT_ETHER_R
3905 #endif
3906
3907 #if SANITIZER_INTERCEPT_SHMCTL
3908 INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
3909   void *ctx;
3910   COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
3911   // FIXME: under ASan the call below may write to freed memory and corrupt
3912   // its metadata. See
3913   // https://github.com/google/sanitizers/issues/321.
3914   int res = REAL(shmctl)(shmid, cmd, buf);
3915   if (res >= 0) {
3916     unsigned sz = 0;
3917     if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
3918       sz = sizeof(__sanitizer_shmid_ds);
3919     else if (cmd == shmctl_ipc_info)
3920       sz = struct_shminfo_sz;
3921     else if (cmd == shmctl_shm_info)
3922       sz = struct_shm_info_sz;
3923     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3924   }
3925   return res;
3926 }
3927 #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
3928 #else
3929 #define INIT_SHMCTL
3930 #endif
3931
3932 #if SANITIZER_INTERCEPT_RANDOM_R
3933 INTERCEPTOR(int, random_r, void *buf, u32 *result) {
3934   void *ctx;
3935   COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
3936   // FIXME: under ASan the call below may write to freed memory and corrupt
3937   // its metadata. See
3938   // https://github.com/google/sanitizers/issues/321.
3939   int res = REAL(random_r)(buf, result);
3940   if (!res && result)
3941     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3942   return res;
3943 }
3944 #define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
3945 #else
3946 #define INIT_RANDOM_R
3947 #endif
3948
3949 // FIXME: under ASan the REAL() call below may write to freed memory and corrupt
3950 // its metadata. See
3951 // https://github.com/google/sanitizers/issues/321.
3952 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
3953     SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
3954     SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
3955     SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
3956     SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
3957     SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
3958 #define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
3959   INTERCEPTOR(int, fn, void *attr, void *r) {                  \
3960     void *ctx;                                                 \
3961     COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
3962     int res = REAL(fn)(attr, r);                               \
3963     if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
3964     return res;                                                \
3965   }
3966 #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
3967   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
3968 #define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
3969   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
3970 #define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
3971   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
3972 #define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
3973   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
3974 #define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
3975   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
3976 #endif
3977
3978 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
3979 INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
3980 INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
3981 INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
3982 INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
3983 INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
3984 INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
3985 INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
3986   void *ctx;
3987   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
3988   // FIXME: under ASan the call below may write to freed memory and corrupt
3989   // its metadata. See
3990   // https://github.com/google/sanitizers/issues/321.
3991   int res = REAL(pthread_attr_getstack)(attr, addr, size);
3992   if (!res) {
3993     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3994     if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
3995   }
3996   return res;
3997 }
3998
3999 // We may need to call the real pthread_attr_getstack from the run-time
4000 // in sanitizer_common, but we don't want to include the interception headers
4001 // there. So, just define this function here.
4002 namespace __sanitizer {
4003 extern "C" {
4004 int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
4005   return REAL(pthread_attr_getstack)(attr, addr, size);
4006 }
4007 }  // extern "C"
4008 }  // namespace __sanitizer
4009
4010 #define INIT_PTHREAD_ATTR_GET                             \
4011   COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
4012   COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
4013   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \
4014   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
4015   COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
4016   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
4017   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
4018 #else
4019 #define INIT_PTHREAD_ATTR_GET
4020 #endif
4021
4022 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
4023 INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
4024
4025 #define INIT_PTHREAD_ATTR_GETINHERITSCHED \
4026   COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
4027 #else
4028 #define INIT_PTHREAD_ATTR_GETINHERITSCHED
4029 #endif
4030
4031 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
4032 INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
4033             void *cpuset) {
4034   void *ctx;
4035   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
4036                            cpuset);
4037   // FIXME: under ASan the call below may write to freed memory and corrupt
4038   // its metadata. See
4039   // https://github.com/google/sanitizers/issues/321.
4040   int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
4041   if (!res && cpusetsize && cpuset)
4042     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
4043   return res;
4044 }
4045
4046 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
4047   COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
4048 #else
4049 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP
4050 #endif
4051
4052 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
4053 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
4054 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
4055   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
4056 #else
4057 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED
4058 #endif
4059
4060 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
4061 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
4062 #define INIT_PTHREAD_MUTEXATTR_GETTYPE \
4063   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
4064 #else
4065 #define INIT_PTHREAD_MUTEXATTR_GETTYPE
4066 #endif
4067
4068 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
4069 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
4070 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
4071   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
4072 #else
4073 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
4074 #endif
4075
4076 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
4077 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
4078 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
4079   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
4080 #else
4081 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
4082 #endif
4083
4084 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
4085 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
4086 #define INIT_PTHREAD_MUTEXATTR_GETROBUST \
4087   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
4088 #else
4089 #define INIT_PTHREAD_MUTEXATTR_GETROBUST
4090 #endif
4091
4092 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
4093 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
4094 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
4095   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
4096 #else
4097 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
4098 #endif
4099
4100 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
4101 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
4102 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
4103   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
4104 #else
4105 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
4106 #endif
4107
4108 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
4109 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
4110 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
4111   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
4112 #else
4113 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
4114 #endif
4115
4116 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
4117 INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
4118 #define INIT_PTHREAD_CONDATTR_GETPSHARED \
4119   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
4120 #else
4121 #define INIT_PTHREAD_CONDATTR_GETPSHARED
4122 #endif
4123
4124 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
4125 INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
4126 #define INIT_PTHREAD_CONDATTR_GETCLOCK \
4127   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
4128 #else
4129 #define INIT_PTHREAD_CONDATTR_GETCLOCK
4130 #endif
4131
4132 #if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
4133 INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
4134 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
4135   COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
4136 #else
4137 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED
4138 #endif
4139
4140 #if SANITIZER_INTERCEPT_TMPNAM
4141 INTERCEPTOR(char *, tmpnam, char *s) {
4142   void *ctx;
4143   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
4144   char *res = REAL(tmpnam)(s);
4145   if (res) {
4146     if (s)
4147       // FIXME: under ASan the call below may write to freed memory and corrupt
4148       // its metadata. See
4149       // https://github.com/google/sanitizers/issues/321.
4150       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
4151     else
4152       COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4153   }
4154   return res;
4155 }
4156 #define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
4157 #else
4158 #define INIT_TMPNAM
4159 #endif
4160
4161 #if SANITIZER_INTERCEPT_TMPNAM_R
4162 INTERCEPTOR(char *, tmpnam_r, char *s) {
4163   void *ctx;
4164   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
4165   // FIXME: under ASan the call below may write to freed memory and corrupt
4166   // its metadata. See
4167   // https://github.com/google/sanitizers/issues/321.
4168   char *res = REAL(tmpnam_r)(s);
4169   if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
4170   return res;
4171 }
4172 #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
4173 #else
4174 #define INIT_TMPNAM_R
4175 #endif
4176
4177 #if SANITIZER_INTERCEPT_TEMPNAM
4178 INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
4179   void *ctx;
4180   COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
4181   if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
4182   if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
4183   char *res = REAL(tempnam)(dir, pfx);
4184   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4185   return res;
4186 }
4187 #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
4188 #else
4189 #define INIT_TEMPNAM
4190 #endif
4191
4192 #if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
4193 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
4194   void *ctx;
4195   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
4196   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
4197   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
4198   return REAL(pthread_setname_np)(thread, name);
4199 }
4200 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
4201 #else
4202 #define INIT_PTHREAD_SETNAME_NP
4203 #endif
4204
4205 #if SANITIZER_INTERCEPT_SINCOS
4206 INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
4207   void *ctx;
4208   COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
4209   // FIXME: under ASan the call below may write to freed memory and corrupt
4210   // its metadata. See
4211   // https://github.com/google/sanitizers/issues/321.
4212   REAL(sincos)(x, sin, cos);
4213   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4214   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4215 }
4216 INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
4217   void *ctx;
4218   COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
4219   // FIXME: under ASan the call below may write to freed memory and corrupt
4220   // its metadata. See
4221   // https://github.com/google/sanitizers/issues/321.
4222   REAL(sincosf)(x, sin, cos);
4223   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4224   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4225 }
4226 INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
4227   void *ctx;
4228   COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
4229   // FIXME: under ASan the call below may write to freed memory and corrupt
4230   // its metadata. See
4231   // https://github.com/google/sanitizers/issues/321.
4232   REAL(sincosl)(x, sin, cos);
4233   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4234   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4235 }
4236 #define INIT_SINCOS                   \
4237   COMMON_INTERCEPT_FUNCTION(sincos);  \
4238   COMMON_INTERCEPT_FUNCTION(sincosf); \
4239   COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
4240 #else
4241 #define INIT_SINCOS
4242 #endif
4243
4244 #if SANITIZER_INTERCEPT_REMQUO
4245 INTERCEPTOR(double, remquo, double x, double y, int *quo) {
4246   void *ctx;
4247   COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
4248   // FIXME: under ASan the call below may write to freed memory and corrupt
4249   // its metadata. See
4250   // https://github.com/google/sanitizers/issues/321.
4251   double res = REAL(remquo)(x, y, quo);
4252   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4253   return res;
4254 }
4255 INTERCEPTOR(float, remquof, float x, float y, int *quo) {
4256   void *ctx;
4257   COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
4258   // FIXME: under ASan the call below may write to freed memory and corrupt
4259   // its metadata. See
4260   // https://github.com/google/sanitizers/issues/321.
4261   float res = REAL(remquof)(x, y, quo);
4262   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4263   return res;
4264 }
4265 INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
4266   void *ctx;
4267   COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
4268   // FIXME: under ASan the call below may write to freed memory and corrupt
4269   // its metadata. See
4270   // https://github.com/google/sanitizers/issues/321.
4271   long double res = REAL(remquol)(x, y, quo);
4272   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4273   return res;
4274 }
4275 #define INIT_REMQUO                   \
4276   COMMON_INTERCEPT_FUNCTION(remquo);  \
4277   COMMON_INTERCEPT_FUNCTION(remquof); \
4278   COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
4279 #else
4280 #define INIT_REMQUO
4281 #endif
4282
4283 #if SANITIZER_INTERCEPT_LGAMMA
4284 extern int signgam;
4285 INTERCEPTOR(double, lgamma, double x) {
4286   void *ctx;
4287   COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
4288   double res = REAL(lgamma)(x);
4289   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4290   return res;
4291 }
4292 INTERCEPTOR(float, lgammaf, float x) {
4293   void *ctx;
4294   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
4295   float res = REAL(lgammaf)(x);
4296   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4297   return res;
4298 }
4299 INTERCEPTOR(long double, lgammal, long double x) {
4300   void *ctx;
4301   COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
4302   long double res = REAL(lgammal)(x);
4303   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4304   return res;
4305 }
4306 #define INIT_LGAMMA                   \
4307   COMMON_INTERCEPT_FUNCTION(lgamma);  \
4308   COMMON_INTERCEPT_FUNCTION(lgammaf); \
4309   COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
4310 #else
4311 #define INIT_LGAMMA
4312 #endif
4313
4314 #if SANITIZER_INTERCEPT_LGAMMA_R
4315 INTERCEPTOR(double, lgamma_r, double x, int *signp) {
4316   void *ctx;
4317   COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
4318   // FIXME: under ASan the call below may write to freed memory and corrupt
4319   // its metadata. See
4320   // https://github.com/google/sanitizers/issues/321.
4321   double res = REAL(lgamma_r)(x, signp);
4322   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4323   return res;
4324 }
4325 INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
4326   void *ctx;
4327   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
4328   // FIXME: under ASan the call below may write to freed memory and corrupt
4329   // its metadata. See
4330   // https://github.com/google/sanitizers/issues/321.
4331   float res = REAL(lgammaf_r)(x, signp);
4332   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4333   return res;
4334 }
4335 #define INIT_LGAMMA_R                   \
4336   COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
4337   COMMON_INTERCEPT_FUNCTION(lgammaf_r);
4338 #else
4339 #define INIT_LGAMMA_R
4340 #endif
4341
4342 #if SANITIZER_INTERCEPT_LGAMMAL_R
4343 INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
4344   void *ctx;
4345   COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
4346   // FIXME: under ASan the call below may write to freed memory and corrupt
4347   // its metadata. See
4348   // https://github.com/google/sanitizers/issues/321.
4349   long double res = REAL(lgammal_r)(x, signp);
4350   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4351   return res;
4352 }
4353 #define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
4354 #else
4355 #define INIT_LGAMMAL_R
4356 #endif
4357
4358 #if SANITIZER_INTERCEPT_DRAND48_R
4359 INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
4360   void *ctx;
4361   COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
4362   // FIXME: under ASan the call below may write to freed memory and corrupt
4363   // its metadata. See
4364   // https://github.com/google/sanitizers/issues/321.
4365   int res = REAL(drand48_r)(buffer, result);
4366   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4367   return res;
4368 }
4369 INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
4370   void *ctx;
4371   COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
4372   // FIXME: under ASan the call below may write to freed memory and corrupt
4373   // its metadata. See
4374   // https://github.com/google/sanitizers/issues/321.
4375   int res = REAL(lrand48_r)(buffer, result);
4376   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4377   return res;
4378 }
4379 #define INIT_DRAND48_R                  \
4380   COMMON_INTERCEPT_FUNCTION(drand48_r); \
4381   COMMON_INTERCEPT_FUNCTION(lrand48_r);
4382 #else
4383 #define INIT_DRAND48_R
4384 #endif
4385
4386 #if SANITIZER_INTERCEPT_RAND_R
4387 INTERCEPTOR(int, rand_r, unsigned *seedp) {
4388   void *ctx;
4389   COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
4390   COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
4391   return REAL(rand_r)(seedp);
4392 }
4393 #define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
4394 #else
4395 #define INIT_RAND_R
4396 #endif
4397
4398 #if SANITIZER_INTERCEPT_GETLINE
4399 INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
4400   void *ctx;
4401   COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
4402   // FIXME: under ASan the call below may write to freed memory and corrupt
4403   // its metadata. See
4404   // https://github.com/google/sanitizers/issues/321.
4405   SSIZE_T res = REAL(getline)(lineptr, n, stream);
4406   if (res > 0) {
4407     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
4408     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
4409     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
4410   }
4411   return res;
4412 }
4413
4414 // FIXME: under ASan the call below may write to freed memory and corrupt its
4415 // metadata. See
4416 // https://github.com/google/sanitizers/issues/321.
4417 #define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
4418   {                                                                            \
4419     void *ctx;                                                                 \
4420     COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
4421     SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
4422     if (res > 0) {                                                             \
4423       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
4424       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
4425       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
4426     }                                                                          \
4427     return res;                                                                \
4428   }
4429
4430 INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
4431             void *stream)
4432 GETDELIM_INTERCEPTOR_IMPL(__getdelim)
4433
4434 // There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
4435 // with its own body.
4436 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
4437             void *stream)
4438 GETDELIM_INTERCEPTOR_IMPL(getdelim)
4439
4440 #define INIT_GETLINE                     \
4441   COMMON_INTERCEPT_FUNCTION(getline);    \
4442   COMMON_INTERCEPT_FUNCTION(__getdelim); \
4443   COMMON_INTERCEPT_FUNCTION(getdelim);
4444 #else
4445 #define INIT_GETLINE
4446 #endif
4447
4448 #if SANITIZER_INTERCEPT_ICONV
4449 INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
4450             char **outbuf, SIZE_T *outbytesleft) {
4451   void *ctx;
4452   COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
4453                            outbytesleft);
4454   if (inbytesleft)
4455     COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
4456   if (inbuf && inbytesleft)
4457     COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
4458   if (outbytesleft)
4459     COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
4460   void *outbuf_orig = outbuf ? *outbuf : nullptr;
4461   // FIXME: under ASan the call below may write to freed memory and corrupt
4462   // its metadata. See
4463   // https://github.com/google/sanitizers/issues/321.
4464   SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
4465   if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
4466     SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
4467     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
4468   }
4469   return res;
4470 }
4471 #define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
4472 #else
4473 #define INIT_ICONV
4474 #endif
4475
4476 #if SANITIZER_INTERCEPT_TIMES
4477 INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
4478   void *ctx;
4479   COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
4480   // FIXME: under ASan the call below may write to freed memory and corrupt
4481   // its metadata. See
4482   // https://github.com/google/sanitizers/issues/321.
4483   __sanitizer_clock_t res = REAL(times)(tms);
4484   if (res != (__sanitizer_clock_t)-1 && tms)
4485     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
4486   return res;
4487 }
4488 #define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
4489 #else
4490 #define INIT_TIMES
4491 #endif
4492
4493 #if SANITIZER_INTERCEPT_TLS_GET_ADDR
4494 #if !SANITIZER_S390
4495 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
4496 // If you see any crashes around this functions, there are 2 known issues with
4497 // it: 1. __tls_get_addr can be called with mis-aligned stack due to:
4498 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
4499 // 2. It can be called recursively if sanitizer code uses __tls_get_addr
4500 // to access thread local variables (it should not happen normally,
4501 // because sanitizers use initial-exec tls model).
4502 INTERCEPTOR(void *, __tls_get_addr, void *arg) {
4503   void *ctx;
4504   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
4505   void *res = REAL(__tls_get_addr)(arg);
4506   uptr tls_begin, tls_end;
4507   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
4508   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
4509   if (dtv) {
4510     // New DTLS block has been allocated.
4511     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
4512   }
4513   return res;
4514 }
4515 #if SANITIZER_PPC
4516 // On PowerPC, we also need to intercept __tls_get_addr_opt, which has
4517 // mostly the same semantics as __tls_get_addr, but its presence enables
4518 // some optimizations in linker (which are safe to ignore here).
4519 extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
4520                           visibility("default")))
4521 void *__tls_get_addr_opt(void *arg);
4522 #endif
4523 #else // SANITIZER_S390
4524 // On s390, we have to intercept two functions here:
4525 // - __tls_get_addr_internal, which is a glibc-internal function that is like
4526 //   the usual __tls_get_addr, but returns a TP-relative offset instead of
4527 //   a proper pointer.  It is used by dlsym for TLS symbols.
4528 // - __tls_get_offset, which is like the above, but also takes a GOT-relative
4529 //   descriptor offset as an argument instead of a pointer.  GOT address
4530 //   is passed in r12, so it's necessary to write it in assembly.  This is
4531 //   the function used by the compiler.
4532 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr_internal)
4533 INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
4534   void *ctx;
4535   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
4536   uptr res = REAL(__tls_get_addr_internal)(arg);
4537   uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
4538   void *ptr = reinterpret_cast<void *>(res + tp);
4539   uptr tls_begin, tls_end;
4540   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
4541   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
4542   if (dtv) {
4543     // New DTLS block has been allocated.
4544     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
4545   }
4546   return res;
4547 }
4548 // We need a protected symbol aliasing the above, so that we can jump
4549 // directly to it from the assembly below.
4550 extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
4551                           visibility("protected")))
4552 uptr __interceptor___tls_get_addr_internal_protected(void *arg);
4553 // Now carefully intercept __tls_get_offset.
4554 asm(
4555   ".text\n"
4556   ".global __tls_get_offset\n"
4557   "__tls_get_offset:\n"
4558 // The __intercept_ version has to exist, so that gen_dynamic_list.py
4559 // exports our symbol.
4560   ".global __interceptor___tls_get_offset\n"
4561   "__interceptor___tls_get_offset:\n"
4562 #ifdef __s390x__
4563   "la %r2, 0(%r2,%r12)\n"
4564   "jg __interceptor___tls_get_addr_internal_protected\n"
4565 #else
4566   "basr %r3,0\n"
4567   "0: la %r2,0(%r2,%r12)\n"
4568   "l %r4,1f-0b(%r3)\n"
4569   "b 0(%r4,%r3)\n"
4570   "1: .long __interceptor___tls_get_addr_internal_protected - 0b\n"
4571 #endif
4572   ".type __tls_get_offset, @function\n"
4573   ".size __tls_get_offset, .-__tls_get_offset\n"
4574 );
4575 #endif // SANITIZER_S390
4576 #else
4577 #define INIT_TLS_GET_ADDR
4578 #endif
4579
4580 #if SANITIZER_INTERCEPT_LISTXATTR
4581 INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
4582   void *ctx;
4583   COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
4584   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4585   // FIXME: under ASan the call below may write to freed memory and corrupt
4586   // its metadata. See
4587   // https://github.com/google/sanitizers/issues/321.
4588   SSIZE_T res = REAL(listxattr)(path, list, size);
4589   // Here and below, size == 0 is a special case where nothing is written to the
4590   // buffer, and res contains the desired buffer size.
4591   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4592   return res;
4593 }
4594 INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
4595   void *ctx;
4596   COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
4597   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4598   // FIXME: under ASan the call below may write to freed memory and corrupt
4599   // its metadata. See
4600   // https://github.com/google/sanitizers/issues/321.
4601   SSIZE_T res = REAL(llistxattr)(path, list, size);
4602   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4603   return res;
4604 }
4605 INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
4606   void *ctx;
4607   COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
4608   // FIXME: under ASan the call below may write to freed memory and corrupt
4609   // its metadata. See
4610   // https://github.com/google/sanitizers/issues/321.
4611   SSIZE_T res = REAL(flistxattr)(fd, list, size);
4612   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4613   return res;
4614 }
4615 #define INIT_LISTXATTR                   \
4616   COMMON_INTERCEPT_FUNCTION(listxattr);  \
4617   COMMON_INTERCEPT_FUNCTION(llistxattr); \
4618   COMMON_INTERCEPT_FUNCTION(flistxattr);
4619 #else
4620 #define INIT_LISTXATTR
4621 #endif
4622
4623 #if SANITIZER_INTERCEPT_GETXATTR
4624 INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
4625             SIZE_T size) {
4626   void *ctx;
4627   COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
4628   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4629   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
4630   // FIXME: under ASan the call below may write to freed memory and corrupt
4631   // its metadata. See
4632   // https://github.com/google/sanitizers/issues/321.
4633   SSIZE_T res = REAL(getxattr)(path, name, value, size);
4634   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4635   return res;
4636 }
4637 INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
4638             SIZE_T size) {
4639   void *ctx;
4640   COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
4641   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4642   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
4643   // FIXME: under ASan the call below may write to freed memory and corrupt
4644   // its metadata. See
4645   // https://github.com/google/sanitizers/issues/321.
4646   SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
4647   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4648   return res;
4649 }
4650 INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
4651             SIZE_T size) {
4652   void *ctx;
4653   COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
4654   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
4655   // FIXME: under ASan the call below may write to freed memory and corrupt
4656   // its metadata. See
4657   // https://github.com/google/sanitizers/issues/321.
4658   SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
4659   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4660   return res;
4661 }
4662 #define INIT_GETXATTR                   \
4663   COMMON_INTERCEPT_FUNCTION(getxattr);  \
4664   COMMON_INTERCEPT_FUNCTION(lgetxattr); \
4665   COMMON_INTERCEPT_FUNCTION(fgetxattr);
4666 #else
4667 #define INIT_GETXATTR
4668 #endif
4669
4670 #if SANITIZER_INTERCEPT_GETRESID
4671 INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
4672   void *ctx;
4673   COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
4674   // FIXME: under ASan the call below may write to freed memory and corrupt
4675   // its metadata. See
4676   // https://github.com/google/sanitizers/issues/321.
4677   int res = REAL(getresuid)(ruid, euid, suid);
4678   if (res >= 0) {
4679     if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
4680     if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
4681     if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
4682   }
4683   return res;
4684 }
4685 INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
4686   void *ctx;
4687   COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
4688   // FIXME: under ASan the call below may write to freed memory and corrupt
4689   // its metadata. See
4690   // https://github.com/google/sanitizers/issues/321.
4691   int res = REAL(getresgid)(rgid, egid, sgid);
4692   if (res >= 0) {
4693     if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
4694     if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
4695     if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
4696   }
4697   return res;
4698 }
4699 #define INIT_GETRESID                   \
4700   COMMON_INTERCEPT_FUNCTION(getresuid); \
4701   COMMON_INTERCEPT_FUNCTION(getresgid);
4702 #else
4703 #define INIT_GETRESID
4704 #endif
4705
4706 #if SANITIZER_INTERCEPT_GETIFADDRS
4707 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
4708 // intercept freeifaddrs(). If that ceases to be the case, we might need to
4709 // intercept it to poison the memory again.
4710 INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
4711   void *ctx;
4712   COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
4713   // FIXME: under ASan the call below may write to freed memory and corrupt
4714   // its metadata. See
4715   // https://github.com/google/sanitizers/issues/321.
4716   int res = REAL(getifaddrs)(ifap);
4717   if (res == 0 && ifap) {
4718     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
4719     __sanitizer_ifaddrs *p = *ifap;
4720     while (p) {
4721       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
4722       if (p->ifa_name)
4723         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
4724                                        REAL(strlen)(p->ifa_name) + 1);
4725       if (p->ifa_addr)
4726         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
4727       if (p->ifa_netmask)
4728         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
4729       // On Linux this is a union, but the other member also points to a
4730       // struct sockaddr, so the following is sufficient.
4731       if (p->ifa_dstaddr)
4732         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
4733       // FIXME(smatveev): Unpoison p->ifa_data as well.
4734       p = p->ifa_next;
4735     }
4736   }
4737   return res;
4738 }
4739 #define INIT_GETIFADDRS                  \
4740   COMMON_INTERCEPT_FUNCTION(getifaddrs);
4741 #else
4742 #define INIT_GETIFADDRS
4743 #endif
4744
4745 #if SANITIZER_INTERCEPT_IF_INDEXTONAME
4746 INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
4747   void *ctx;
4748   COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
4749   // FIXME: under ASan the call below may write to freed memory and corrupt
4750   // its metadata. See
4751   // https://github.com/google/sanitizers/issues/321.
4752   char *res = REAL(if_indextoname)(ifindex, ifname);
4753   if (res && ifname)
4754     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4755   return res;
4756 }
4757 INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
4758   void *ctx;
4759   COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
4760   if (ifname)
4761     COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4762   return REAL(if_nametoindex)(ifname);
4763 }
4764 #define INIT_IF_INDEXTONAME                  \
4765   COMMON_INTERCEPT_FUNCTION(if_indextoname); \
4766   COMMON_INTERCEPT_FUNCTION(if_nametoindex);
4767 #else
4768 #define INIT_IF_INDEXTONAME
4769 #endif
4770
4771 #if SANITIZER_INTERCEPT_CAPGET
4772 INTERCEPTOR(int, capget, void *hdrp, void *datap) {
4773   void *ctx;
4774   COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
4775   if (hdrp)
4776     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4777   // FIXME: under ASan the call below may write to freed memory and corrupt
4778   // its metadata. See
4779   // https://github.com/google/sanitizers/issues/321.
4780   int res = REAL(capget)(hdrp, datap);
4781   if (res == 0 && datap)
4782     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
4783   // We can also return -1 and write to hdrp->version if the version passed in
4784   // hdrp->version is unsupported. But that's not a trivial condition to check,
4785   // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
4786   return res;
4787 }
4788 INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
4789   void *ctx;
4790   COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
4791   if (hdrp)
4792     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4793   if (datap)
4794     COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
4795   return REAL(capset)(hdrp, datap);
4796 }
4797 #define INIT_CAPGET                  \
4798   COMMON_INTERCEPT_FUNCTION(capget); \
4799   COMMON_INTERCEPT_FUNCTION(capset);
4800 #else
4801 #define INIT_CAPGET
4802 #endif
4803
4804 #if SANITIZER_INTERCEPT_AEABI_MEM
4805 DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr)
4806 DECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr)
4807 DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr)
4808
4809 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
4810   return WRAP(memmove)(to, from, size);
4811 }
4812 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
4813   return WRAP(memmove)(to, from, size);
4814 }
4815 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
4816   return WRAP(memmove)(to, from, size);
4817 }
4818 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
4819   return WRAP(memcpy)(to, from, size);
4820 }
4821 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
4822   return WRAP(memcpy)(to, from, size);
4823 }
4824 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
4825   return WRAP(memcpy)(to, from, size);
4826 }
4827 // Note the argument order.
4828 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
4829   return WRAP(memset)(block, c, size);
4830 }
4831 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
4832   return WRAP(memset)(block, c, size);
4833 }
4834 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
4835   return WRAP(memset)(block, c, size);
4836 }
4837 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
4838   return WRAP(memset)(block, 0, size);
4839 }
4840 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
4841   return WRAP(memset)(block, 0, size);
4842 }
4843 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
4844   return WRAP(memset)(block, 0, size);
4845 }
4846 #define INIT_AEABI_MEM                         \
4847   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
4848   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
4849   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
4850   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
4851   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
4852   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
4853   COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
4854   COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
4855   COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
4856   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
4857   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
4858   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
4859 #else
4860 #define INIT_AEABI_MEM
4861 #endif  // SANITIZER_INTERCEPT_AEABI_MEM
4862
4863 #if SANITIZER_INTERCEPT___BZERO
4864 DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
4865
4866 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
4867   return WRAP(memset)(block, 0, size);
4868 }
4869 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
4870 #else
4871 #define INIT___BZERO
4872 #endif  // SANITIZER_INTERCEPT___BZERO
4873
4874 #if SANITIZER_INTERCEPT_FTIME
4875 INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
4876   void *ctx;
4877   COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
4878   // FIXME: under ASan the call below may write to freed memory and corrupt
4879   // its metadata. See
4880   // https://github.com/google/sanitizers/issues/321.
4881   int res = REAL(ftime)(tp);
4882   if (tp)
4883     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
4884   return res;
4885 }
4886 #define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
4887 #else
4888 #define INIT_FTIME
4889 #endif  // SANITIZER_INTERCEPT_FTIME
4890
4891 #if SANITIZER_INTERCEPT_XDR
4892 INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
4893             unsigned size, int op) {
4894   void *ctx;
4895   COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
4896   // FIXME: under ASan the call below may write to freed memory and corrupt
4897   // its metadata. See
4898   // https://github.com/google/sanitizers/issues/321.
4899   REAL(xdrmem_create)(xdrs, addr, size, op);
4900   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
4901   if (op == __sanitizer_XDR_ENCODE) {
4902     // It's not obvious how much data individual xdr_ routines write.
4903     // Simply unpoison the entire target buffer in advance.
4904     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
4905   }
4906 }
4907
4908 INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
4909   void *ctx;
4910   COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
4911   // FIXME: under ASan the call below may write to freed memory and corrupt
4912   // its metadata. See
4913   // https://github.com/google/sanitizers/issues/321.
4914   REAL(xdrstdio_create)(xdrs, file, op);
4915   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
4916 }
4917
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 #define XDR_INTERCEPTOR(F, T)                             \
4922   INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
4923     void *ctx;                                            \
4924     COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
4925     if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
4926       COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
4927     int res = REAL(F)(xdrs, p);                           \
4928     if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
4929       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
4930     return res;                                           \
4931   }
4932
4933 XDR_INTERCEPTOR(xdr_short, short)
4934 XDR_INTERCEPTOR(xdr_u_short, unsigned short)
4935 XDR_INTERCEPTOR(xdr_int, int)
4936 XDR_INTERCEPTOR(xdr_u_int, unsigned)
4937 XDR_INTERCEPTOR(xdr_long, long)
4938 XDR_INTERCEPTOR(xdr_u_long, unsigned long)
4939 XDR_INTERCEPTOR(xdr_hyper, long long)
4940 XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
4941 XDR_INTERCEPTOR(xdr_longlong_t, long long)
4942 XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
4943 XDR_INTERCEPTOR(xdr_int8_t, u8)
4944 XDR_INTERCEPTOR(xdr_uint8_t, u8)
4945 XDR_INTERCEPTOR(xdr_int16_t, u16)
4946 XDR_INTERCEPTOR(xdr_uint16_t, u16)
4947 XDR_INTERCEPTOR(xdr_int32_t, u32)
4948 XDR_INTERCEPTOR(xdr_uint32_t, u32)
4949 XDR_INTERCEPTOR(xdr_int64_t, u64)
4950 XDR_INTERCEPTOR(xdr_uint64_t, u64)
4951 XDR_INTERCEPTOR(xdr_quad_t, long long)
4952 XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
4953 XDR_INTERCEPTOR(xdr_bool, bool)
4954 XDR_INTERCEPTOR(xdr_enum, int)
4955 XDR_INTERCEPTOR(xdr_char, char)
4956 XDR_INTERCEPTOR(xdr_u_char, unsigned char)
4957 XDR_INTERCEPTOR(xdr_float, float)
4958 XDR_INTERCEPTOR(xdr_double, double)
4959
4960 // FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
4961 // wrapstring, sizeof
4962
4963 INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
4964             unsigned maxsize) {
4965   void *ctx;
4966   COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
4967   if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4968     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4969     COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
4970     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
4971   }
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(xdr_bytes)(xdrs, p, sizep, maxsize);
4976   if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
4977     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4978     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
4979     if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
4980   }
4981   return res;
4982 }
4983
4984 INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
4985             unsigned maxsize) {
4986   void *ctx;
4987   COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
4988   if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4989     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4990     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4991   }
4992   // FIXME: under ASan the call below may write to freed memory and corrupt
4993   // its metadata. See
4994   // https://github.com/google/sanitizers/issues/321.
4995   int res = REAL(xdr_string)(xdrs, p, maxsize);
4996   if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
4997     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4998     if (res && *p)
4999       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
5000   }
5001   return res;
5002 }
5003
5004 #define INIT_XDR                               \
5005   COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
5006   COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
5007   COMMON_INTERCEPT_FUNCTION(xdr_short);        \
5008   COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
5009   COMMON_INTERCEPT_FUNCTION(xdr_int);          \
5010   COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
5011   COMMON_INTERCEPT_FUNCTION(xdr_long);         \
5012   COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
5013   COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
5014   COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
5015   COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
5016   COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
5017   COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
5018   COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
5019   COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
5020   COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
5021   COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
5022   COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
5023   COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
5024   COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
5025   COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
5026   COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
5027   COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
5028   COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
5029   COMMON_INTERCEPT_FUNCTION(xdr_char);         \
5030   COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
5031   COMMON_INTERCEPT_FUNCTION(xdr_float);        \
5032   COMMON_INTERCEPT_FUNCTION(xdr_double);       \
5033   COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
5034   COMMON_INTERCEPT_FUNCTION(xdr_string);
5035 #else
5036 #define INIT_XDR
5037 #endif  // SANITIZER_INTERCEPT_XDR
5038
5039 #if SANITIZER_INTERCEPT_TSEARCH
5040 INTERCEPTOR(void *, tsearch, void *key, void **rootp,
5041             int (*compar)(const void *, const void *)) {
5042   void *ctx;
5043   COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
5044   // FIXME: under ASan the call below may write to freed memory and corrupt
5045   // its metadata. See
5046   // https://github.com/google/sanitizers/issues/321.
5047   void *res = REAL(tsearch)(key, rootp, compar);
5048   if (res && *(void **)res == key)
5049     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
5050   return res;
5051 }
5052 #define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
5053 #else
5054 #define INIT_TSEARCH
5055 #endif
5056
5057 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
5058     SANITIZER_INTERCEPT_OPEN_MEMSTREAM
5059 void unpoison_file(__sanitizer_FILE *fp) {
5060 #if SANITIZER_HAS_STRUCT_FILE
5061   COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
5062   if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
5063     COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
5064                                         fp->_IO_read_end - fp->_IO_read_base);
5065 #endif  // SANITIZER_HAS_STRUCT_FILE
5066 }
5067 #endif
5068
5069 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS
5070 // These guys are called when a .c source is built with -O2.
5071 INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
5072   void *ctx;
5073   COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
5074   int res = REAL(__uflow)(fp);
5075   unpoison_file(fp);
5076   return res;
5077 }
5078 INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
5079   void *ctx;
5080   COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
5081   int res = REAL(__underflow)(fp);
5082   unpoison_file(fp);
5083   return res;
5084 }
5085 INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
5086   void *ctx;
5087   COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
5088   int res = REAL(__overflow)(fp, ch);
5089   unpoison_file(fp);
5090   return res;
5091 }
5092 INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
5093   void *ctx;
5094   COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
5095   int res = REAL(__wuflow)(fp);
5096   unpoison_file(fp);
5097   return res;
5098 }
5099 INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
5100   void *ctx;
5101   COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
5102   int res = REAL(__wunderflow)(fp);
5103   unpoison_file(fp);
5104   return res;
5105 }
5106 INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
5107   void *ctx;
5108   COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
5109   int res = REAL(__woverflow)(fp, ch);
5110   unpoison_file(fp);
5111   return res;
5112 }
5113 #define INIT_LIBIO_INTERNALS               \
5114   COMMON_INTERCEPT_FUNCTION(__uflow);      \
5115   COMMON_INTERCEPT_FUNCTION(__underflow);  \
5116   COMMON_INTERCEPT_FUNCTION(__overflow);   \
5117   COMMON_INTERCEPT_FUNCTION(__wuflow);     \
5118   COMMON_INTERCEPT_FUNCTION(__wunderflow); \
5119   COMMON_INTERCEPT_FUNCTION(__woverflow);
5120 #else
5121 #define INIT_LIBIO_INTERNALS
5122 #endif
5123
5124 #if SANITIZER_INTERCEPT_FOPEN
5125 INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
5126   void *ctx;
5127   COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
5128   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5129   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5130   __sanitizer_FILE *res = REAL(fopen)(path, mode);
5131   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5132   if (res) unpoison_file(res);
5133   return res;
5134 }
5135 INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
5136   void *ctx;
5137   COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
5138   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5139   __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
5140   if (res) unpoison_file(res);
5141   return res;
5142 }
5143 INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
5144             __sanitizer_FILE *fp) {
5145   void *ctx;
5146   COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
5147   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5148   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5149   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
5150   __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
5151   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5152   if (res) unpoison_file(res);
5153   return res;
5154 }
5155 #define INIT_FOPEN                   \
5156   COMMON_INTERCEPT_FUNCTION(fopen);  \
5157   COMMON_INTERCEPT_FUNCTION(fdopen); \
5158   COMMON_INTERCEPT_FUNCTION(freopen);
5159 #else
5160 #define INIT_FOPEN
5161 #endif
5162
5163 #if SANITIZER_INTERCEPT_FOPEN64
5164 INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
5165   void *ctx;
5166   COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
5167   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5168   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5169   __sanitizer_FILE *res = REAL(fopen64)(path, mode);
5170   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5171   if (res) unpoison_file(res);
5172   return res;
5173 }
5174 INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
5175             __sanitizer_FILE *fp) {
5176   void *ctx;
5177   COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
5178   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5179   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5180   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
5181   __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
5182   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5183   if (res) unpoison_file(res);
5184   return res;
5185 }
5186 #define INIT_FOPEN64                  \
5187   COMMON_INTERCEPT_FUNCTION(fopen64); \
5188   COMMON_INTERCEPT_FUNCTION(freopen64);
5189 #else
5190 #define INIT_FOPEN64
5191 #endif
5192
5193 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
5194 INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
5195   void *ctx;
5196   COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
5197   // FIXME: under ASan the call below may write to freed memory and corrupt
5198   // its metadata. See
5199   // https://github.com/google/sanitizers/issues/321.
5200   __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
5201   if (res) {
5202     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
5203     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
5204     unpoison_file(res);
5205     FileMetadata file = {ptr, sizeloc};
5206     SetInterceptorMetadata(res, file);
5207   }
5208   return res;
5209 }
5210 INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
5211             SIZE_T *sizeloc) {
5212   void *ctx;
5213   COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
5214   __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
5215   if (res) {
5216     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
5217     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
5218     unpoison_file(res);
5219     FileMetadata file = {(char **)ptr, sizeloc};
5220     SetInterceptorMetadata(res, file);
5221   }
5222   return res;
5223 }
5224 INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
5225             const char *mode) {
5226   void *ctx;
5227   COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
5228   // FIXME: under ASan the call below may write to freed memory and corrupt
5229   // its metadata. See
5230   // https://github.com/google/sanitizers/issues/321.
5231   __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
5232   if (res) unpoison_file(res);
5233   return res;
5234 }
5235 #define INIT_OPEN_MEMSTREAM                   \
5236   COMMON_INTERCEPT_FUNCTION(open_memstream);  \
5237   COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
5238   COMMON_INTERCEPT_FUNCTION(fmemopen);
5239 #else
5240 #define INIT_OPEN_MEMSTREAM
5241 #endif
5242
5243 #if SANITIZER_INTERCEPT_OBSTACK
5244 static void initialize_obstack(__sanitizer_obstack *obstack) {
5245   COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
5246   if (obstack->chunk)
5247     COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
5248                                         sizeof(*obstack->chunk));
5249 }
5250
5251 INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
5252             int align, void *(*alloc_fn)(uptr arg, uptr sz),
5253             void (*free_fn)(uptr arg, void *p)) {
5254   void *ctx;
5255   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
5256                            free_fn);
5257   int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
5258   if (res) initialize_obstack(obstack);
5259   return res;
5260 }
5261 INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
5262             int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
5263   void *ctx;
5264   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
5265                            free_fn);
5266   int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
5267   if (res) initialize_obstack(obstack);
5268   return res;
5269 }
5270 INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
5271   void *ctx;
5272   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
5273   REAL(_obstack_newchunk)(obstack, length);
5274   if (obstack->chunk)
5275     COMMON_INTERCEPTOR_INITIALIZE_RANGE(
5276         obstack->chunk, obstack->next_free - (char *)obstack->chunk);
5277 }
5278 #define INIT_OBSTACK                           \
5279   COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
5280   COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
5281   COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
5282 #else
5283 #define INIT_OBSTACK
5284 #endif
5285
5286 #if SANITIZER_INTERCEPT_FFLUSH
5287 INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
5288   void *ctx;
5289   COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
5290   int res = REAL(fflush)(fp);
5291   // FIXME: handle fp == NULL
5292   if (fp) {
5293     const FileMetadata *m = GetInterceptorMetadata(fp);
5294     if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
5295   }
5296   return res;
5297 }
5298 #define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
5299 #else
5300 #define INIT_FFLUSH
5301 #endif
5302
5303 #if SANITIZER_INTERCEPT_FCLOSE
5304 INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
5305   void *ctx;
5306   COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
5307   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
5308   const FileMetadata *m = GetInterceptorMetadata(fp);
5309   int res = REAL(fclose)(fp);
5310   if (m) {
5311     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
5312     DeleteInterceptorMetadata(fp);
5313   }
5314   return res;
5315 }
5316 #define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
5317 #else
5318 #define INIT_FCLOSE
5319 #endif
5320
5321 #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
5322 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
5323   void *ctx;
5324   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
5325   if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
5326   COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
5327   void *res = REAL(dlopen)(filename, flag);
5328   COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
5329   return res;
5330 }
5331
5332 INTERCEPTOR(int, dlclose, void *handle) {
5333   void *ctx;
5334   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
5335   int res = REAL(dlclose)(handle);
5336   COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
5337   return res;
5338 }
5339 #define INIT_DLOPEN_DLCLOSE          \
5340   COMMON_INTERCEPT_FUNCTION(dlopen); \
5341   COMMON_INTERCEPT_FUNCTION(dlclose);
5342 #else
5343 #define INIT_DLOPEN_DLCLOSE
5344 #endif
5345
5346 #if SANITIZER_INTERCEPT_GETPASS
5347 INTERCEPTOR(char *, getpass, const char *prompt) {
5348   void *ctx;
5349   COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
5350   if (prompt)
5351     COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
5352   char *res = REAL(getpass)(prompt);
5353   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
5354   return res;
5355 }
5356
5357 #define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
5358 #else
5359 #define INIT_GETPASS
5360 #endif
5361
5362 #if SANITIZER_INTERCEPT_TIMERFD
5363 INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
5364             void *old_value) {
5365   void *ctx;
5366   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
5367                            old_value);
5368   COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
5369   int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
5370   if (res != -1 && old_value)
5371     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
5372   return res;
5373 }
5374
5375 INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
5376   void *ctx;
5377   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
5378   int res = REAL(timerfd_gettime)(fd, curr_value);
5379   if (res != -1 && curr_value)
5380     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
5381   return res;
5382 }
5383 #define INIT_TIMERFD                          \
5384   COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
5385   COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
5386 #else
5387 #define INIT_TIMERFD
5388 #endif
5389
5390 #if SANITIZER_INTERCEPT_MLOCKX
5391 // Linux kernel has a bug that leads to kernel deadlock if a process
5392 // maps TBs of memory and then calls mlock().
5393 static void MlockIsUnsupported() {
5394   static atomic_uint8_t printed;
5395   if (atomic_exchange(&printed, 1, memory_order_relaxed))
5396     return;
5397   VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
5398           SanitizerToolName);
5399 }
5400
5401 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
5402   MlockIsUnsupported();
5403   return 0;
5404 }
5405
5406 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
5407   MlockIsUnsupported();
5408   return 0;
5409 }
5410
5411 INTERCEPTOR(int, mlockall, int flags) {
5412   MlockIsUnsupported();
5413   return 0;
5414 }
5415
5416 INTERCEPTOR(int, munlockall, void) {
5417   MlockIsUnsupported();
5418   return 0;
5419 }
5420
5421 #define INIT_MLOCKX                                                            \
5422   COMMON_INTERCEPT_FUNCTION(mlock);                                            \
5423   COMMON_INTERCEPT_FUNCTION(munlock);                                          \
5424   COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
5425   COMMON_INTERCEPT_FUNCTION(munlockall);
5426
5427 #else
5428 #define INIT_MLOCKX
5429 #endif  // SANITIZER_INTERCEPT_MLOCKX
5430
5431 #if SANITIZER_INTERCEPT_FOPENCOOKIE
5432 struct WrappedCookie {
5433   void *real_cookie;
5434   __sanitizer_cookie_io_functions_t real_io_funcs;
5435 };
5436
5437 static uptr wrapped_read(void *cookie, char *buf, uptr size) {
5438   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5439   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5440   __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
5441   return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
5442 }
5443
5444 static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
5445   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5446   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5447   __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
5448   return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
5449 }
5450
5451 static int wrapped_seek(void *cookie, u64 *offset, int whence) {
5452   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5453   COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
5454   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5455   __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
5456   return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
5457                    : -1;
5458 }
5459
5460 static int wrapped_close(void *cookie) {
5461   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
5462   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5463   __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
5464   int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
5465   InternalFree(wrapped_cookie);
5466   return res;
5467 }
5468
5469 INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
5470             __sanitizer_cookie_io_functions_t io_funcs) {
5471   void *ctx;
5472   COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
5473   WrappedCookie *wrapped_cookie =
5474       (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
5475   wrapped_cookie->real_cookie = cookie;
5476   wrapped_cookie->real_io_funcs = io_funcs;
5477   __sanitizer_FILE *res =
5478       REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
5479                                                wrapped_seek, wrapped_close});
5480   return res;
5481 }
5482
5483 #define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
5484 #else
5485 #define INIT_FOPENCOOKIE
5486 #endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
5487
5488 #if SANITIZER_INTERCEPT_SEM
5489 INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
5490   void *ctx;
5491   COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
5492   // Workaround a bug in glibc's "old" semaphore implementation by
5493   // zero-initializing the sem_t contents. This has to be done here because
5494   // interceptors bind to the lowest symbols version by default, hitting the
5495   // buggy code path while the non-sanitized build of the same code works fine.
5496   REAL(memset)(s, 0, sizeof(*s));
5497   int res = REAL(sem_init)(s, pshared, value);
5498   return res;
5499 }
5500
5501 INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
5502   void *ctx;
5503   COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
5504   int res = REAL(sem_destroy)(s);
5505   return res;
5506 }
5507
5508 INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
5509   void *ctx;
5510   COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
5511   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
5512   if (res == 0) {
5513     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5514   }
5515   return res;
5516 }
5517
5518 INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
5519   void *ctx;
5520   COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
5521   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
5522   if (res == 0) {
5523     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5524   }
5525   return res;
5526 }
5527
5528 INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
5529   void *ctx;
5530   COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
5531   COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
5532   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
5533   if (res == 0) {
5534     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5535   }
5536   return res;
5537 }
5538
5539 INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
5540   void *ctx;
5541   COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
5542   COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
5543   int res = REAL(sem_post)(s);
5544   return res;
5545 }
5546
5547 INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
5548   void *ctx;
5549   COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
5550   int res = REAL(sem_getvalue)(s, sval);
5551   if (res == 0) {
5552     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5553     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
5554   }
5555   return res;
5556 }
5557 #define INIT_SEM                                                               \
5558   COMMON_INTERCEPT_FUNCTION(sem_init);                                         \
5559   COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \
5560   COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \
5561   COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \
5562   COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \
5563   COMMON_INTERCEPT_FUNCTION(sem_post);                                         \
5564   COMMON_INTERCEPT_FUNCTION(sem_getvalue);
5565 #else
5566 #define INIT_SEM
5567 #endif // SANITIZER_INTERCEPT_SEM
5568
5569 #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
5570 INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
5571   void *ctx;
5572   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
5573   int res = REAL(pthread_setcancelstate)(state, oldstate);
5574   if (res == 0)
5575     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
5576   return res;
5577 }
5578
5579 INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
5580   void *ctx;
5581   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
5582   int res = REAL(pthread_setcanceltype)(type, oldtype);
5583   if (res == 0)
5584     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
5585   return res;
5586 }
5587 #define INIT_PTHREAD_SETCANCEL                                                 \
5588   COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
5589   COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
5590 #else
5591 #define INIT_PTHREAD_SETCANCEL
5592 #endif
5593
5594 #if SANITIZER_INTERCEPT_MINCORE
5595 INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
5596   void *ctx;
5597   COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
5598   int res = REAL(mincore)(addr, length, vec);
5599   if (res == 0) {
5600     uptr page_size = GetPageSizeCached();
5601     uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
5602     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
5603   }
5604   return res;
5605 }
5606 #define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
5607 #else
5608 #define INIT_MINCORE
5609 #endif
5610
5611 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
5612 INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
5613             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5614             uptr flags) {
5615   void *ctx;
5616   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
5617                            remote_iov, riovcnt, flags);
5618   SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
5619                                        riovcnt, flags);
5620   if (res > 0)
5621     write_iovec(ctx, local_iov, liovcnt, res);
5622   return res;
5623 }
5624
5625 INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
5626             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5627             uptr flags) {
5628   void *ctx;
5629   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
5630                            remote_iov, riovcnt, flags);
5631   SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
5632                                         riovcnt, flags);
5633   if (res > 0)
5634     read_iovec(ctx, local_iov, liovcnt, res);
5635   return res;
5636 }
5637 #define INIT_PROCESS_VM_READV                                                  \
5638   COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
5639   COMMON_INTERCEPT_FUNCTION(process_vm_writev);
5640 #else
5641 #define INIT_PROCESS_VM_READV
5642 #endif
5643
5644 #if SANITIZER_INTERCEPT_CTERMID
5645 INTERCEPTOR(char *, ctermid, char *s) {
5646   void *ctx;
5647   COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
5648   char *res = REAL(ctermid)(s);
5649   if (res) {
5650     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
5651   }
5652   return res;
5653 }
5654 #define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
5655 #else
5656 #define INIT_CTERMID
5657 #endif
5658
5659 #if SANITIZER_INTERCEPT_CTERMID_R
5660 INTERCEPTOR(char *, ctermid_r, char *s) {
5661   void *ctx;
5662   COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
5663   char *res = REAL(ctermid_r)(s);
5664   if (res) {
5665     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
5666   }
5667   return res;
5668 }
5669 #define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
5670 #else
5671 #define INIT_CTERMID_R
5672 #endif
5673
5674 #if SANITIZER_INTERCEPT_RECV_RECVFROM
5675 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
5676   void *ctx;
5677   COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
5678   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5679   SSIZE_T res = REAL(recv)(fd, buf, len, flags);
5680   if (res > 0) {
5681     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
5682   }
5683   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
5684   return res;
5685 }
5686
5687 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
5688             void *srcaddr, int *addrlen) {
5689   void *ctx;
5690   COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
5691                            addrlen);
5692   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5693   SIZE_T srcaddr_sz;
5694   if (srcaddr) srcaddr_sz = *addrlen;
5695   (void)srcaddr_sz;  // prevent "set but not used" warning
5696   SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
5697   if (res > 0) {
5698     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
5699     if (srcaddr)
5700       COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
5701                                           Min((SIZE_T)*addrlen, srcaddr_sz));
5702   }
5703   return res;
5704 }
5705 #define INIT_RECV_RECVFROM          \
5706   COMMON_INTERCEPT_FUNCTION(recv);  \
5707   COMMON_INTERCEPT_FUNCTION(recvfrom);
5708 #else
5709 #define INIT_RECV_RECVFROM
5710 #endif
5711
5712 #if SANITIZER_INTERCEPT_SEND_SENDTO
5713 INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
5714   void *ctx;
5715   COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
5716   if (fd >= 0) {
5717     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5718     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
5719   }
5720   SSIZE_T res = REAL(send)(fd, buf, len, flags);
5721   if (common_flags()->intercept_send && res > 0)
5722     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
5723   return res;
5724 }
5725
5726 INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
5727             void *dstaddr, int addrlen) {
5728   void *ctx;
5729   COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
5730   if (fd >= 0) {
5731     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5732     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
5733   }
5734   // Can't check dstaddr as it may have uninitialized padding at the end.
5735   SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
5736   if (common_flags()->intercept_send && res > 0)
5737     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
5738   return res;
5739 }
5740 #define INIT_SEND_SENDTO           \
5741   COMMON_INTERCEPT_FUNCTION(send); \
5742   COMMON_INTERCEPT_FUNCTION(sendto);
5743 #else
5744 #define INIT_SEND_SENDTO
5745 #endif
5746
5747 #if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
5748 INTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
5749   void *ctx;
5750   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
5751   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5752   int res = REAL(eventfd_read)(fd, value);
5753   if (res == 0) {
5754     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
5755     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
5756   }
5757   return res;
5758 }
5759 INTERCEPTOR(int, eventfd_write, int fd, u64 value) {
5760   void *ctx;
5761   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
5762   if (fd >= 0) {
5763     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5764     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
5765   }
5766   int res = REAL(eventfd_write)(fd, value);
5767   return res;
5768 }
5769 #define INIT_EVENTFD_READ_WRITE            \
5770   COMMON_INTERCEPT_FUNCTION(eventfd_read); \
5771   COMMON_INTERCEPT_FUNCTION(eventfd_write)
5772 #else
5773 #define INIT_EVENTFD_READ_WRITE
5774 #endif
5775
5776 #if SANITIZER_INTERCEPT_STAT
5777 INTERCEPTOR(int, stat, const char *path, void *buf) {
5778   void *ctx;
5779   COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
5780   if (common_flags()->intercept_stat)
5781     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5782   int res = REAL(stat)(path, buf);
5783   if (!res)
5784     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
5785   return res;
5786 }
5787 #define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
5788 #else
5789 #define INIT_STAT
5790 #endif
5791
5792 #if SANITIZER_INTERCEPT___XSTAT
5793 INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
5794   void *ctx;
5795   COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
5796   if (common_flags()->intercept_stat)
5797     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5798   int res = REAL(__xstat)(version, path, buf);
5799   if (!res)
5800     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
5801   return res;
5802 }
5803 #define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
5804 #else
5805 #define INIT___XSTAT
5806 #endif
5807
5808 #if SANITIZER_INTERCEPT___XSTAT64
5809 INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
5810   void *ctx;
5811   COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
5812   if (common_flags()->intercept_stat)
5813     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5814   int res = REAL(__xstat64)(version, path, buf);
5815   if (!res)
5816     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
5817   return res;
5818 }
5819 #define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
5820 #else
5821 #define INIT___XSTAT64
5822 #endif
5823
5824 #if SANITIZER_INTERCEPT___LXSTAT
5825 INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
5826   void *ctx;
5827   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
5828   if (common_flags()->intercept_stat)
5829     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5830   int res = REAL(__lxstat)(version, path, buf);
5831   if (!res)
5832     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
5833   return res;
5834 }
5835 #define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
5836 #else
5837 #define INIT___LXSTAT
5838 #endif
5839
5840 #if SANITIZER_INTERCEPT___LXSTAT64
5841 INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
5842   void *ctx;
5843   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
5844   if (common_flags()->intercept_stat)
5845     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5846   int res = REAL(__lxstat64)(version, path, buf);
5847   if (!res)
5848     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
5849   return res;
5850 }
5851 #define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
5852 #else
5853 #define INIT___LXSTAT64
5854 #endif
5855
5856 // FIXME: add other *stat interceptor
5857
5858 static void InitializeCommonInterceptors() {
5859   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
5860   interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
5861
5862   INIT_TEXTDOMAIN;
5863   INIT_STRLEN;
5864   INIT_STRNLEN;
5865   INIT_STRCMP;
5866   INIT_STRNCMP;
5867   INIT_STRCASECMP;
5868   INIT_STRNCASECMP;
5869   INIT_STRSTR;
5870   INIT_STRCASESTR;
5871   INIT_STRCHR;
5872   INIT_STRCHRNUL;
5873   INIT_STRRCHR;
5874   INIT_STRSPN;
5875   INIT_STRPBRK;
5876   INIT_MEMSET;
5877   INIT_MEMMOVE;
5878   INIT_MEMCPY;
5879   INIT_MEMCHR;
5880   INIT_MEMCMP;
5881   INIT_MEMRCHR;
5882   INIT_MEMMEM;
5883   INIT_READ;
5884   INIT_PREAD;
5885   INIT_PREAD64;
5886   INIT_READV;
5887   INIT_PREADV;
5888   INIT_PREADV64;
5889   INIT_WRITE;
5890   INIT_PWRITE;
5891   INIT_PWRITE64;
5892   INIT_WRITEV;
5893   INIT_PWRITEV;
5894   INIT_PWRITEV64;
5895   INIT_PRCTL;
5896   INIT_LOCALTIME_AND_FRIENDS;
5897   INIT_STRPTIME;
5898   INIT_SCANF;
5899   INIT_ISOC99_SCANF;
5900   INIT_PRINTF;
5901   INIT_PRINTF_L;
5902   INIT_ISOC99_PRINTF;
5903   INIT_FREXP;
5904   INIT_FREXPF_FREXPL;
5905   INIT_GETPWNAM_AND_FRIENDS;
5906   INIT_GETPWNAM_R_AND_FRIENDS;
5907   INIT_GETPWENT;
5908   INIT_FGETPWENT;
5909   INIT_GETPWENT_R;
5910   INIT_SETPWENT;
5911   INIT_CLOCK_GETTIME;
5912   INIT_GETITIMER;
5913   INIT_TIME;
5914   INIT_GLOB;
5915   INIT_WAIT;
5916   INIT_WAIT4;
5917   INIT_INET;
5918   INIT_PTHREAD_GETSCHEDPARAM;
5919   INIT_GETADDRINFO;
5920   INIT_GETNAMEINFO;
5921   INIT_GETSOCKNAME;
5922   INIT_GETHOSTBYNAME;
5923   INIT_GETHOSTBYNAME_R;
5924   INIT_GETHOSTBYNAME2_R;
5925   INIT_GETHOSTBYADDR_R;
5926   INIT_GETHOSTENT_R;
5927   INIT_GETSOCKOPT;
5928   INIT_ACCEPT;
5929   INIT_ACCEPT4;
5930   INIT_MODF;
5931   INIT_RECVMSG;
5932   INIT_SENDMSG;
5933   INIT_GETPEERNAME;
5934   INIT_IOCTL;
5935   INIT_INET_ATON;
5936   INIT_SYSINFO;
5937   INIT_READDIR;
5938   INIT_READDIR64;
5939   INIT_PTRACE;
5940   INIT_SETLOCALE;
5941   INIT_GETCWD;
5942   INIT_GET_CURRENT_DIR_NAME;
5943   INIT_STRTOIMAX;
5944   INIT_MBSTOWCS;
5945   INIT_MBSNRTOWCS;
5946   INIT_WCSTOMBS;
5947   INIT_WCSNRTOMBS;
5948   INIT_WCRTOMB;
5949   INIT_TCGETATTR;
5950   INIT_REALPATH;
5951   INIT_CANONICALIZE_FILE_NAME;
5952   INIT_CONFSTR;
5953   INIT_SCHED_GETAFFINITY;
5954   INIT_SCHED_GETPARAM;
5955   INIT_STRERROR;
5956   INIT_STRERROR_R;
5957   INIT_XPG_STRERROR_R;
5958   INIT_SCANDIR;
5959   INIT_SCANDIR64;
5960   INIT_GETGROUPS;
5961   INIT_POLL;
5962   INIT_PPOLL;
5963   INIT_WORDEXP;
5964   INIT_SIGWAIT;
5965   INIT_SIGWAITINFO;
5966   INIT_SIGTIMEDWAIT;
5967   INIT_SIGSETOPS;
5968   INIT_SIGPENDING;
5969   INIT_SIGPROCMASK;
5970   INIT_BACKTRACE;
5971   INIT__EXIT;
5972   INIT_PTHREAD_MUTEX_LOCK;
5973   INIT_PTHREAD_MUTEX_UNLOCK;
5974   INIT_GETMNTENT;
5975   INIT_GETMNTENT_R;
5976   INIT_STATFS;
5977   INIT_STATFS64;
5978   INIT_STATVFS;
5979   INIT_STATVFS64;
5980   INIT_INITGROUPS;
5981   INIT_ETHER_NTOA_ATON;
5982   INIT_ETHER_HOST;
5983   INIT_ETHER_R;
5984   INIT_SHMCTL;
5985   INIT_RANDOM_R;
5986   INIT_PTHREAD_ATTR_GET;
5987   INIT_PTHREAD_ATTR_GETINHERITSCHED;
5988   INIT_PTHREAD_ATTR_GETAFFINITY_NP;
5989   INIT_PTHREAD_MUTEXATTR_GETPSHARED;
5990   INIT_PTHREAD_MUTEXATTR_GETTYPE;
5991   INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
5992   INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
5993   INIT_PTHREAD_MUTEXATTR_GETROBUST;
5994   INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
5995   INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
5996   INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
5997   INIT_PTHREAD_CONDATTR_GETPSHARED;
5998   INIT_PTHREAD_CONDATTR_GETCLOCK;
5999   INIT_PTHREAD_BARRIERATTR_GETPSHARED;
6000   INIT_TMPNAM;
6001   INIT_TMPNAM_R;
6002   INIT_TEMPNAM;
6003   INIT_PTHREAD_SETNAME_NP;
6004   INIT_SINCOS;
6005   INIT_REMQUO;
6006   INIT_LGAMMA;
6007   INIT_LGAMMA_R;
6008   INIT_LGAMMAL_R;
6009   INIT_DRAND48_R;
6010   INIT_RAND_R;
6011   INIT_GETLINE;
6012   INIT_ICONV;
6013   INIT_TIMES;
6014   INIT_TLS_GET_ADDR;
6015   INIT_LISTXATTR;
6016   INIT_GETXATTR;
6017   INIT_GETRESID;
6018   INIT_GETIFADDRS;
6019   INIT_IF_INDEXTONAME;
6020   INIT_CAPGET;
6021   INIT_AEABI_MEM;
6022   INIT___BZERO;
6023   INIT_FTIME;
6024   INIT_XDR;
6025   INIT_TSEARCH;
6026   INIT_LIBIO_INTERNALS;
6027   INIT_FOPEN;
6028   INIT_FOPEN64;
6029   INIT_OPEN_MEMSTREAM;
6030   INIT_OBSTACK;
6031   INIT_FFLUSH;
6032   INIT_FCLOSE;
6033   INIT_DLOPEN_DLCLOSE;
6034   INIT_GETPASS;
6035   INIT_TIMERFD;
6036   INIT_MLOCKX;
6037   INIT_FOPENCOOKIE;
6038   INIT_SEM;
6039   INIT_PTHREAD_SETCANCEL;
6040   INIT_MINCORE;
6041   INIT_PROCESS_VM_READV;
6042   INIT_CTERMID;
6043   INIT_CTERMID_R;
6044   INIT_RECV_RECVFROM;
6045   INIT_SEND_SENDTO;
6046   INIT_STAT;
6047   INIT_EVENTFD_READ_WRITE;
6048   INIT___XSTAT;
6049   INIT___XSTAT64;
6050   INIT___LXSTAT;
6051   INIT___LXSTAT64;
6052   // FIXME: add other *stat interceptors.
6053 }