sanitizer_common_interceptors.inc revision 78d77c2638b8e02020737c9b296ce2198e4c58e6
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 it's own macros:
15//   COMMON_INTERCEPTOR_ENTER
16//   COMMON_INTERCEPTOR_READ_RANGE
17//   COMMON_INTERCEPTOR_WRITE_RANGE
18//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
19//   COMMON_INTERCEPTOR_FD_ACQUIRE
20//   COMMON_INTERCEPTOR_FD_RELEASE
21//   COMMON_INTERCEPTOR_FD_ACCESS
22//   COMMON_INTERCEPTOR_SET_THREAD_NAME
23//   COMMON_INTERCEPTOR_ON_EXIT
24//   COMMON_INTERCEPTOR_MUTEX_LOCK
25//   COMMON_INTERCEPTOR_MUTEX_UNLOCK
26//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
27//===----------------------------------------------------------------------===//
28#include "interception/interception.h"
29#include "sanitizer_platform_interceptors.h"
30
31#include <stdarg.h>
32
33#if SANITIZER_WINDOWS
34#define va_copy(dst, src) ((dst) = (src))
35#endif // _WIN32
36
37#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
38#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {}
39#endif
40
41#ifndef COMMON_INTERCEPTOR_FD_ACCESS
42#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
43#endif
44
45#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
46#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
47#endif
48
49#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
50#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
51#endif
52
53#if SANITIZER_INTERCEPT_STRCMP
54static inline int CharCmpX(unsigned char c1, unsigned char c2) {
55  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
56}
57
58INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
59  void *ctx;
60  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
61  unsigned char c1, c2;
62  uptr i;
63  for (i = 0; ; i++) {
64    c1 = (unsigned char)s1[i];
65    c2 = (unsigned char)s2[i];
66    if (c1 != c2 || c1 == '\0') break;
67  }
68  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
69  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
70  return CharCmpX(c1, c2);
71}
72
73INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
74  void *ctx;
75  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
76  unsigned char c1 = 0, c2 = 0;
77  uptr i;
78  for (i = 0; i < size; i++) {
79    c1 = (unsigned char)s1[i];
80    c2 = (unsigned char)s2[i];
81    if (c1 != c2 || c1 == '\0') break;
82  }
83  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
84  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
85  return CharCmpX(c1, c2);
86}
87
88#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp)
89#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp)
90#else
91#define INIT_STRCMP
92#define INIT_STRNCMP
93#endif
94
95#if SANITIZER_INTERCEPT_STRCASECMP
96static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
97  int c1_low = ToLower(c1);
98  int c2_low = ToLower(c2);
99  return c1_low - c2_low;
100}
101
102INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
103  void *ctx;
104  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
105  unsigned char c1 = 0, c2 = 0;
106  uptr i;
107  for (i = 0; ; i++) {
108    c1 = (unsigned char)s1[i];
109    c2 = (unsigned char)s2[i];
110    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
111      break;
112  }
113  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
114  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
115  return CharCaseCmp(c1, c2);
116}
117
118INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
119  void *ctx;
120  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
121  unsigned char c1 = 0, c2 = 0;
122  uptr i;
123  for (i = 0; i < n; i++) {
124    c1 = (unsigned char)s1[i];
125    c2 = (unsigned char)s2[i];
126    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
127      break;
128  }
129  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
130  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
131  return CharCaseCmp(c1, c2);
132}
133
134#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
135#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
136#else
137#define INIT_STRCASECMP
138#define INIT_STRNCASECMP
139#endif
140
141#if SANITIZER_INTERCEPT_FREXP
142INTERCEPTOR(double, frexp, double x, int *exp) {
143  void *ctx;
144  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
145  double res = REAL(frexp)(x, exp);
146  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
147  return res;
148}
149
150#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
151#else
152#define INIT_FREXP
153#endif // SANITIZER_INTERCEPT_FREXP
154
155#if SANITIZER_INTERCEPT_FREXPF_FREXPL
156INTERCEPTOR(float, frexpf, float x, int *exp) {
157  void *ctx;
158  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
159  float res = REAL(frexpf)(x, exp);
160  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
161  return res;
162}
163
164INTERCEPTOR(long double, frexpl, long double x, int *exp) {
165  void *ctx;
166  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
167  long double res = REAL(frexpl)(x, exp);
168  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
169  return res;
170}
171
172#define INIT_FREXPF_FREXPL                       \
173  INTERCEPT_FUNCTION(frexpf);                    \
174  INTERCEPT_FUNCTION(frexpl)
175#else
176#define INIT_FREXPF_FREXPL
177#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
178
179#if SI_NOT_WINDOWS
180static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
181                        SIZE_T iovlen, SIZE_T maxlen) {
182  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
183    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
184    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
185    maxlen -= sz;
186  }
187}
188
189static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
190                       SIZE_T iovlen, SIZE_T maxlen) {
191  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
192  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
193    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
194    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
195    maxlen -= sz;
196  }
197}
198#endif
199
200#if SANITIZER_INTERCEPT_READ
201INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
202  void *ctx;
203  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
204  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
205  SSIZE_T res = REAL(read)(fd, ptr, count);
206  if (res > 0)
207    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
208  if (res >= 0 && fd >= 0)
209    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
210  return res;
211}
212#define INIT_READ INTERCEPT_FUNCTION(read)
213#else
214#define INIT_READ
215#endif
216
217#if SANITIZER_INTERCEPT_PREAD
218INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
219  void *ctx;
220  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
221  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
222  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
223  if (res > 0)
224    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
225  if (res >= 0 && fd >= 0)
226    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
227  return res;
228}
229#define INIT_PREAD INTERCEPT_FUNCTION(pread)
230#else
231#define INIT_PREAD
232#endif
233
234#if SANITIZER_INTERCEPT_PREAD64
235INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
236  void *ctx;
237  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
238  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
239  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
240  if (res > 0)
241    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
242  if (res >= 0 && fd >= 0)
243    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
244  return res;
245}
246#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
247#else
248#define INIT_PREAD64
249#endif
250
251#if SANITIZER_INTERCEPT_READV
252INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
253                        int iovcnt) {
254  void *ctx;
255  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
256  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
257  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
258  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
259  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
260  return res;
261}
262#define INIT_READV INTERCEPT_FUNCTION(readv)
263#else
264#define INIT_READV
265#endif
266
267#if SANITIZER_INTERCEPT_PREADV
268INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
269            OFF_T offset) {
270  void *ctx;
271  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
272  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
273  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
274  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
275  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
276  return res;
277}
278#define INIT_PREADV INTERCEPT_FUNCTION(preadv)
279#else
280#define INIT_PREADV
281#endif
282
283#if SANITIZER_INTERCEPT_PREADV64
284INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
285            OFF64_T offset) {
286  void *ctx;
287  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
288  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
289  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
290  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
291  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
292  return res;
293}
294#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64)
295#else
296#define INIT_PREADV64
297#endif
298
299#if SANITIZER_INTERCEPT_WRITE
300INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
301  void *ctx;
302  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
303  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
304  if (fd >= 0)
305    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
306  SSIZE_T res = REAL(write)(fd, ptr, count);
307  // FIXME: this check should be _before_ the call to REAL(write), not after
308  if (res > 0)
309    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
310  return res;
311}
312#define INIT_WRITE INTERCEPT_FUNCTION(write)
313#else
314#define INIT_WRITE
315#endif
316
317#if SANITIZER_INTERCEPT_PWRITE
318INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
319  void *ctx;
320  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
321  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
322  if (fd >= 0)
323    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
324  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
325  if (res > 0)
326    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
327  return res;
328}
329#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
330#else
331#define INIT_PWRITE
332#endif
333
334#if SANITIZER_INTERCEPT_PWRITE64
335INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
336            OFF64_T offset) {
337  void *ctx;
338  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
339  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
340  if (fd >= 0)
341    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
342  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
343  if (res > 0)
344    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
345  return res;
346}
347#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
348#else
349#define INIT_PWRITE64
350#endif
351
352#if SANITIZER_INTERCEPT_WRITEV
353INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
354                        int iovcnt) {
355  void *ctx;
356  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
357  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
358  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
359  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
360  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
361  return res;
362}
363#define INIT_WRITEV INTERCEPT_FUNCTION(writev)
364#else
365#define INIT_WRITEV
366#endif
367
368#if SANITIZER_INTERCEPT_PWRITEV
369INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
370            OFF_T offset) {
371  void *ctx;
372  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
373  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
374  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
375  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
376  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
377  return res;
378}
379#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev)
380#else
381#define INIT_PWRITEV
382#endif
383
384#if SANITIZER_INTERCEPT_PWRITEV64
385INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
386            OFF64_T offset) {
387  void *ctx;
388  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
389  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
390  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
391  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
392  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
393  return res;
394}
395#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64)
396#else
397#define INIT_PWRITEV64
398#endif
399
400#if SANITIZER_INTERCEPT_PRCTL
401INTERCEPTOR(int, prctl, int option,
402            unsigned long arg2, unsigned long arg3,   // NOLINT
403            unsigned long arg4, unsigned long arg5) { // NOLINT
404  void *ctx;
405  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
406  static const int PR_SET_NAME = 15;
407  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
408  if (option == PR_SET_NAME) {
409    char buff[16];
410    internal_strncpy(buff, (char *)arg2, 15);
411    buff[15] = 0;
412    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
413  }
414  return res;
415}
416#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
417#else
418#define INIT_PRCTL
419#endif // SANITIZER_INTERCEPT_PRCTL
420
421
422#if SANITIZER_INTERCEPT_TIME
423INTERCEPTOR(unsigned long, time, unsigned long *t) {
424  void *ctx;
425  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
426  unsigned long res = REAL(time)(t);
427  if (t && res != (unsigned long)-1) {
428    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
429  }
430  return res;
431}
432#define INIT_TIME                                \
433  INTERCEPT_FUNCTION(time);
434#else
435#define INIT_TIME
436#endif // SANITIZER_INTERCEPT_TIME
437
438
439#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
440static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
441  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
442  if (tm->tm_zone) {
443    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
444    // can point to shared memory and tsan would report a data race.
445    COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone,
446                                        REAL(strlen(tm->tm_zone)) + 1);
447  }
448}
449
450INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
451  void *ctx;
452  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
453  __sanitizer_tm *res = REAL(localtime)(timep);
454  if (res) {
455    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
456    unpoison_tm(ctx, res);
457  }
458  return res;
459}
460INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
461  void *ctx;
462  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
463  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
464  if (res) {
465    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
466    unpoison_tm(ctx, res);
467  }
468  return res;
469}
470INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
471  void *ctx;
472  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
473  __sanitizer_tm *res = REAL(gmtime)(timep);
474  if (res) {
475    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
476    unpoison_tm(ctx, res);
477  }
478  return res;
479}
480INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
481  void *ctx;
482  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
483  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
484  if (res) {
485    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
486    unpoison_tm(ctx, res);
487  }
488  return res;
489}
490INTERCEPTOR(char *, ctime, unsigned long *timep) {
491  void *ctx;
492  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
493  char *res = REAL(ctime)(timep);
494  if (res) {
495    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
496    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
497  }
498  return res;
499}
500INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
501  void *ctx;
502  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
503  char *res = REAL(ctime_r)(timep, result);
504  if (res) {
505    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
506    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
507  }
508  return res;
509}
510INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
511  void *ctx;
512  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
513  char *res = REAL(asctime)(tm);
514  if (res) {
515    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
516    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
517  }
518  return res;
519}
520INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
521  void *ctx;
522  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
523  char *res = REAL(asctime_r)(tm, result);
524  if (res) {
525    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
526    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
527  }
528  return res;
529}
530#define INIT_LOCALTIME_AND_FRIENDS               \
531  INTERCEPT_FUNCTION(localtime);                 \
532  INTERCEPT_FUNCTION(localtime_r);               \
533  INTERCEPT_FUNCTION(gmtime);                    \
534  INTERCEPT_FUNCTION(gmtime_r);                  \
535  INTERCEPT_FUNCTION(ctime);                     \
536  INTERCEPT_FUNCTION(ctime_r);                   \
537  INTERCEPT_FUNCTION(asctime);                   \
538  INTERCEPT_FUNCTION(asctime_r);
539#else
540#define INIT_LOCALTIME_AND_FRIENDS
541#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
542
543#if SANITIZER_INTERCEPT_SCANF
544
545#include "sanitizer_common_interceptors_scanf.inc"
546
547#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
548  {                                                                            \
549    void *ctx;                                                                 \
550    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
551    va_list aq;                                                                \
552    va_copy(aq, ap);                                                           \
553    int res = REAL(vname)(__VA_ARGS__);                                        \
554    if (res > 0)                                                               \
555      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
556    va_end(aq);                                                                \
557    return res;                                                                \
558  }
559
560INTERCEPTOR(int, vscanf, const char *format, va_list ap)
561VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
562
563INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
564VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
565
566INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
567VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
568
569#if SANITIZER_INTERCEPT_ISOC99_SCANF
570INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
571VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
572
573INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
574            va_list ap)
575VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
576
577INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
578VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
579#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
580
581#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
582  {                                                                            \
583    void *ctx;                                                                 \
584    va_list ap;                                                                \
585    va_start(ap, format);                                                      \
586    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
587    int res = vname(__VA_ARGS__, ap);                                          \
588    va_end(ap);                                                                \
589    return res;                                                                \
590  }
591
592INTERCEPTOR(int, scanf, const char *format, ...)
593SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
594
595INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
596SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
597
598INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
599SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
600
601#if SANITIZER_INTERCEPT_ISOC99_SCANF
602INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
603SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
604
605INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
606SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
607
608INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
609SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
610#endif
611
612#endif
613
614#if SANITIZER_INTERCEPT_SCANF
615#define INIT_SCANF             \
616  INTERCEPT_FUNCTION(scanf);   \
617  INTERCEPT_FUNCTION(sscanf);  \
618  INTERCEPT_FUNCTION(fscanf);  \
619  INTERCEPT_FUNCTION(vscanf);  \
620  INTERCEPT_FUNCTION(vsscanf); \
621  INTERCEPT_FUNCTION(vfscanf);
622#else
623#define INIT_SCANF
624#endif
625
626#if SANITIZER_INTERCEPT_ISOC99_SCANF
627#define INIT_ISOC99_SCANF               \
628  INTERCEPT_FUNCTION(__isoc99_scanf);   \
629  INTERCEPT_FUNCTION(__isoc99_sscanf);  \
630  INTERCEPT_FUNCTION(__isoc99_fscanf);  \
631  INTERCEPT_FUNCTION(__isoc99_vscanf);  \
632  INTERCEPT_FUNCTION(__isoc99_vsscanf); \
633  INTERCEPT_FUNCTION(__isoc99_vfscanf);
634#else
635#define INIT_ISOC99_SCANF
636#endif
637
638#if SANITIZER_INTERCEPT_IOCTL
639#include "sanitizer_common_interceptors_ioctl.inc"
640INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
641  void *ctx;
642  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
643
644  CHECK(ioctl_initialized);
645
646  // Note: TSan does not use common flags, and they are zero-initialized.
647  // This effectively disables ioctl handling in TSan.
648  if (!common_flags()->handle_ioctl)
649    return REAL(ioctl)(d, request, arg);
650
651  const ioctl_desc *desc = ioctl_lookup(request);
652  if (!desc)
653    Printf("WARNING: unknown ioctl %x\n", request);
654
655  if (desc)
656    ioctl_common_pre(ctx, desc, d, request, arg);
657  int res = REAL(ioctl)(d, request, arg);
658  // FIXME: some ioctls have different return values for success and failure.
659  if (desc && res != -1)
660    ioctl_common_post(ctx, desc, res, d, request, arg);
661  return res;
662}
663#define INIT_IOCTL \
664  ioctl_init();    \
665  INTERCEPT_FUNCTION(ioctl);
666#else
667#define INIT_IOCTL
668#endif
669
670
671#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
672INTERCEPTOR(void *, getpwnam, const char *name) {
673  void *ctx;
674  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
675  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
676  void *res = REAL(getpwnam)(name);
677  if (res != 0)
678    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
679  return res;
680}
681INTERCEPTOR(void *, getpwuid, u32 uid) {
682  void *ctx;
683  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
684  void *res = REAL(getpwuid)(uid);
685  if (res != 0)
686    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
687  return res;
688}
689INTERCEPTOR(void *, getgrnam, const char *name) {
690  void *ctx;
691  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
692  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
693  void *res = REAL(getgrnam)(name);
694  if (res != 0)
695    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
696  return res;
697}
698INTERCEPTOR(void *, getgrgid, u32 gid) {
699  void *ctx;
700  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
701  void *res = REAL(getgrgid)(gid);
702  if (res != 0)
703    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
704  return res;
705}
706#define INIT_GETPWNAM_AND_FRIENDS                  \
707  INTERCEPT_FUNCTION(getpwnam);                    \
708  INTERCEPT_FUNCTION(getpwuid);                    \
709  INTERCEPT_FUNCTION(getgrnam);                    \
710  INTERCEPT_FUNCTION(getgrgid);
711#else
712#define INIT_GETPWNAM_AND_FRIENDS
713#endif
714
715
716#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
717INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
718    char *buf, SIZE_T buflen, void **result) {
719  void *ctx;
720  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
721  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
722  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
723  if (!res) {
724    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
725    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
726  }
727  return res;
728}
729INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
730    char *buf, SIZE_T buflen, void **result) {
731  void *ctx;
732  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
733  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
734  if (!res) {
735    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
736    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
737  }
738  return res;
739}
740INTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
741    char *buf, SIZE_T buflen, void **result) {
742  void *ctx;
743  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
744  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
745  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
746  if (!res) {
747    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
748    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
749  }
750  return res;
751}
752INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
753    char *buf, SIZE_T buflen, void **result) {
754  void *ctx;
755  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
756  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
757  if (!res) {
758    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
759    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
760  }
761  return res;
762}
763#define INIT_GETPWNAM_R_AND_FRIENDS                \
764  INTERCEPT_FUNCTION(getpwnam_r);                  \
765  INTERCEPT_FUNCTION(getpwuid_r);                  \
766  INTERCEPT_FUNCTION(getgrnam_r);                  \
767  INTERCEPT_FUNCTION(getgrgid_r);
768#else
769#define INIT_GETPWNAM_R_AND_FRIENDS
770#endif
771
772
773#if SANITIZER_INTERCEPT_CLOCK_GETTIME
774INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
775  void *ctx;
776  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
777  int res = REAL(clock_getres)(clk_id, tp);
778  if (!res && tp) {
779    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
780  }
781  return res;
782}
783INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
784  void *ctx;
785  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
786  int res = REAL(clock_gettime)(clk_id, tp);
787  if (!res) {
788    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
789  }
790  return res;
791}
792INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
793  void *ctx;
794  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
795  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
796  return REAL(clock_settime)(clk_id, tp);
797}
798#define INIT_CLOCK_GETTIME                         \
799  INTERCEPT_FUNCTION(clock_getres);                \
800  INTERCEPT_FUNCTION(clock_gettime);               \
801  INTERCEPT_FUNCTION(clock_settime);
802#else
803#define INIT_CLOCK_GETTIME
804#endif
805
806
807#if SANITIZER_INTERCEPT_GETITIMER
808INTERCEPTOR(int, getitimer, int which, void *curr_value) {
809  void *ctx;
810  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
811  int res = REAL(getitimer)(which, curr_value);
812  if (!res && curr_value) {
813    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
814  }
815  return res;
816}
817INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
818  void *ctx;
819  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
820  if (new_value)
821    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
822  int res = REAL(setitimer)(which, new_value, old_value);
823  if (!res && old_value) {
824    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
825  }
826  return res;
827}
828#define INIT_GETITIMER                             \
829  INTERCEPT_FUNCTION(getitimer);                   \
830  INTERCEPT_FUNCTION(setitimer);
831#else
832#define INIT_GETITIMER
833#endif
834
835#if SANITIZER_INTERCEPT_GLOB
836static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
837  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
838  // +1 for NULL pointer at the end.
839  if (pglob->gl_pathv)
840    COMMON_INTERCEPTOR_WRITE_RANGE(
841        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
842  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
843    char *p = pglob->gl_pathv[i];
844    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
845  }
846}
847
848static THREADLOCAL __sanitizer_glob_t* pglob_copy;
849static THREADLOCAL void* glob_ctx;
850
851static void wrapped_gl_closedir(void *dir) {
852  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
853  pglob_copy->gl_closedir(dir);
854}
855
856static void *wrapped_gl_readdir(void *dir) {
857  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
858  return pglob_copy->gl_readdir(dir);
859}
860
861static void *wrapped_gl_opendir(const char *s) {
862  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
863  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
864  return pglob_copy->gl_opendir(s);
865}
866
867static int wrapped_gl_lstat(const char *s, void *st) {
868  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
869  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
870  return pglob_copy->gl_lstat(s, st);
871}
872
873static int wrapped_gl_stat(const char *s, void *st) {
874  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
875  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
876  return pglob_copy->gl_stat(s, st);
877}
878
879INTERCEPTOR(int, glob, const char *pattern, int flags,
880            int (*errfunc)(const char *epath, int eerrno),
881            __sanitizer_glob_t *pglob) {
882  void *ctx;
883  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
884  __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
885                                  wrapped_gl_readdir, wrapped_gl_opendir,
886                                  wrapped_gl_lstat, wrapped_gl_stat};
887  if (flags & glob_altdirfunc) {
888    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
889    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
890    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
891    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
892    Swap(pglob->gl_stat, glob_copy.gl_stat);
893    pglob_copy = &glob_copy;
894    glob_ctx = ctx;
895  }
896  int res = REAL(glob)(pattern, flags, errfunc, pglob);
897  if (flags & glob_altdirfunc) {
898    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
899    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
900    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
901    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
902    Swap(pglob->gl_stat, glob_copy.gl_stat);
903  }
904  pglob_copy = 0;
905  glob_ctx = 0;
906  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
907  return res;
908}
909
910INTERCEPTOR(int, glob64, const char *pattern, int flags,
911            int (*errfunc)(const char *epath, int eerrno),
912            __sanitizer_glob_t *pglob) {
913  void *ctx;
914  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
915  __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
916                                  wrapped_gl_readdir, wrapped_gl_opendir,
917                                  wrapped_gl_lstat, wrapped_gl_stat};
918  if (flags & glob_altdirfunc) {
919    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
920    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
921    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
922    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
923    Swap(pglob->gl_stat, glob_copy.gl_stat);
924    pglob_copy = &glob_copy;
925    glob_ctx = ctx;
926  }
927  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
928  if (flags & glob_altdirfunc) {
929    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
930    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
931    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
932    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
933    Swap(pglob->gl_stat, glob_copy.gl_stat);
934  }
935  pglob_copy = 0;
936  glob_ctx = 0;
937  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
938  return res;
939}
940#define INIT_GLOB           \
941  INTERCEPT_FUNCTION(glob); \
942  INTERCEPT_FUNCTION(glob64);
943#else  // SANITIZER_INTERCEPT_GLOB
944#define INIT_GLOB
945#endif  // SANITIZER_INTERCEPT_GLOB
946
947#if SANITIZER_INTERCEPT_WAIT
948// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
949// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
950// details.
951INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
952  void *ctx;
953  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
954  int res = REAL(wait)(status);
955  if (res != -1 && status)
956    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
957  return res;
958}
959INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
960  int options) {
961  void *ctx;
962  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
963  int res = REAL(waitid)(idtype, id, infop, options);
964  if (res != -1 && infop)
965    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
966  return res;
967}
968INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
969  void *ctx;
970  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
971  int res = REAL(waitpid)(pid, status, options);
972  if (res != -1 && status)
973    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
974  return res;
975}
976INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
977  void *ctx;
978  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
979  int res = REAL(wait3)(status, options, rusage);
980  if (res != -1) {
981    if (status)
982      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
983    if (rusage)
984      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
985  }
986  return res;
987}
988INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
989  void *ctx;
990  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
991  int res = REAL(wait4)(pid, status, options, rusage);
992  if (res != -1) {
993    if (status)
994      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
995    if (rusage)
996      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
997  }
998  return res;
999}
1000#define INIT_WAIT                                \
1001  INTERCEPT_FUNCTION(wait);                      \
1002  INTERCEPT_FUNCTION(waitid);                    \
1003  INTERCEPT_FUNCTION(waitpid);                   \
1004  INTERCEPT_FUNCTION(wait3);                     \
1005  INTERCEPT_FUNCTION(wait4);
1006#else
1007#define INIT_WAIT
1008#endif
1009
1010#if SANITIZER_INTERCEPT_INET
1011INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
1012  void *ctx;
1013  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
1014  uptr sz = __sanitizer_in_addr_sz(af);
1015  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
1016  // FIXME: figure out read size based on the address family.
1017  char *res = REAL(inet_ntop)(af, src, dst, size);
1018  if (res)
1019    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1020  return res;
1021}
1022INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
1023  void *ctx;
1024  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
1025  // FIXME: figure out read size based on the address family.
1026  int res = REAL(inet_pton)(af, src, dst);
1027  if (res == 1) {
1028    uptr sz = __sanitizer_in_addr_sz(af);
1029    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1030  }
1031  return res;
1032}
1033#define INIT_INET                                \
1034  INTERCEPT_FUNCTION(inet_ntop);                 \
1035  INTERCEPT_FUNCTION(inet_pton);
1036#else
1037#define INIT_INET
1038#endif
1039
1040#if SANITIZER_INTERCEPT_INET
1041INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
1042  void *ctx;
1043  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
1044  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
1045  int res = REAL(inet_aton)(cp, dst);
1046  if (res != 0) {
1047    uptr sz = __sanitizer_in_addr_sz(af_inet);
1048    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1049  }
1050  return res;
1051}
1052#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton);
1053#else
1054#define INIT_INET_ATON
1055#endif
1056
1057#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
1058INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
1059  void *ctx;
1060  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
1061  int res = REAL(pthread_getschedparam)(thread, policy, param);
1062  if (res == 0) {
1063    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
1064    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
1065  }
1066  return res;
1067}
1068#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
1069#else
1070#define INIT_PTHREAD_GETSCHEDPARAM
1071#endif
1072
1073#if SANITIZER_INTERCEPT_GETADDRINFO
1074INTERCEPTOR(int, getaddrinfo, char *node, char *service,
1075            struct __sanitizer_addrinfo *hints,
1076            struct __sanitizer_addrinfo **out) {
1077  void *ctx;
1078  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1079  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1080  if (service)
1081    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1082  if (hints)
1083    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
1084  int res = REAL(getaddrinfo)(node, service, hints, out);
1085  if (res == 0 && out) {
1086    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
1087    struct __sanitizer_addrinfo *p = *out;
1088    while (p) {
1089      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
1090      if (p->ai_addr)
1091        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
1092      if (p->ai_canonname)
1093        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1094                                       REAL(strlen)(p->ai_canonname) + 1);
1095      p = p->ai_next;
1096    }
1097  }
1098  return res;
1099}
1100#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
1101#else
1102#define INIT_GETADDRINFO
1103#endif
1104
1105#if SANITIZER_INTERCEPT_GETNAMEINFO
1106INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
1107            unsigned hostlen, char *serv, unsigned servlen, int flags) {
1108  void *ctx;
1109  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
1110                           serv, servlen, flags);
1111  // FIXME: consider adding READ_RANGE(sockaddr, salen)
1112  // There is padding in in_addr that may make this too noisy
1113  int res =
1114      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
1115  if (res == 0) {
1116    if (host && hostlen)
1117      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
1118    if (serv && servlen)
1119      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
1120  }
1121  return res;
1122}
1123#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo);
1124#else
1125#define INIT_GETNAMEINFO
1126#endif
1127
1128#if SANITIZER_INTERCEPT_GETSOCKNAME
1129INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
1130  void *ctx;
1131  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
1132  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1133  int addrlen_in = *addrlen;
1134  int res = REAL(getsockname)(sock_fd, addr, addrlen);
1135  if (res == 0) {
1136    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
1137  }
1138  return res;
1139}
1140#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
1141#else
1142#define INIT_GETSOCKNAME
1143#endif
1144
1145#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1146static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
1147  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
1148  if (h->h_name)
1149    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
1150  char **p = h->h_aliases;
1151  while (*p) {
1152    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
1153    ++p;
1154  }
1155  COMMON_INTERCEPTOR_WRITE_RANGE(
1156      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
1157  p = h->h_addr_list;
1158  while (*p) {
1159    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
1160    ++p;
1161  }
1162  COMMON_INTERCEPTOR_WRITE_RANGE(
1163      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
1164}
1165#endif
1166
1167#if SANITIZER_INTERCEPT_GETHOSTBYNAME
1168INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
1169  void *ctx;
1170  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
1171  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
1172  if (res) write_hostent(ctx, res);
1173  return res;
1174}
1175
1176INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
1177            int type) {
1178  void *ctx;
1179  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
1180  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1181  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
1182  if (res) write_hostent(ctx, res);
1183  return res;
1184}
1185
1186INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
1187  void *ctx;
1188  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
1189  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
1190  if (res) write_hostent(ctx, res);
1191  return res;
1192}
1193
1194INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
1195  void *ctx;
1196  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
1197  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
1198  if (res) write_hostent(ctx, res);
1199  return res;
1200}
1201#define INIT_GETHOSTBYNAME           \
1202  INTERCEPT_FUNCTION(gethostent);    \
1203  INTERCEPT_FUNCTION(gethostbyaddr); \
1204  INTERCEPT_FUNCTION(gethostbyname); \
1205  INTERCEPT_FUNCTION(gethostbyname2);
1206#else
1207#define INIT_GETHOSTBYNAME
1208#endif
1209
1210#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1211INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
1212            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
1213  void *ctx;
1214  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
1215                           h_errnop);
1216  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
1217  if (res == 0) {
1218    if (result) {
1219      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1220      if (*result) write_hostent(ctx, *result);
1221    }
1222    if (h_errnop)
1223      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1224  }
1225  return res;
1226}
1227
1228INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
1229            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1230            __sanitizer_hostent **result, int *h_errnop) {
1231  void *ctx;
1232  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
1233                           buflen, result, h_errnop);
1234  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1235  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
1236                                  h_errnop);
1237  if (res == 0) {
1238    if (result) {
1239      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1240      if (*result) write_hostent(ctx, *result);
1241    }
1242    if (h_errnop)
1243      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1244  }
1245  return res;
1246}
1247
1248INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
1249            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
1250            int *h_errnop) {
1251  void *ctx;
1252  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
1253                           h_errnop);
1254  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
1255  if (res == 0) {
1256    if (result) {
1257      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1258      if (*result) write_hostent(ctx, *result);
1259    }
1260    if (h_errnop)
1261      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1262  }
1263  return res;
1264}
1265
1266INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
1267            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1268            __sanitizer_hostent **result, int *h_errnop) {
1269  void *ctx;
1270  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
1271                           result, h_errnop);
1272  int res =
1273      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
1274  if (res == 0) {
1275    if (result) {
1276      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1277      if (*result) write_hostent(ctx, *result);
1278    }
1279    if (h_errnop)
1280      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1281  }
1282  return res;
1283}
1284#define INIT_GETHOSTBYNAME_R           \
1285  INTERCEPT_FUNCTION(gethostent_r);    \
1286  INTERCEPT_FUNCTION(gethostbyaddr_r); \
1287  INTERCEPT_FUNCTION(gethostbyname_r); \
1288  INTERCEPT_FUNCTION(gethostbyname2_r);
1289#else
1290#define INIT_GETHOSTBYNAME_R
1291#endif
1292
1293#if SANITIZER_INTERCEPT_GETSOCKOPT
1294INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1295            int *optlen) {
1296  void *ctx;
1297  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1298                           optlen);
1299  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1300  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1301  if (res == 0)
1302    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1303  return res;
1304}
1305#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
1306#else
1307#define INIT_GETSOCKOPT
1308#endif
1309
1310#if SANITIZER_INTERCEPT_ACCEPT
1311INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
1312  void *ctx;
1313  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
1314  unsigned addrlen0;
1315  if (addrlen) {
1316    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1317    addrlen0 = *addrlen;
1318  }
1319  int fd2 = REAL(accept)(fd, addr, addrlen);
1320  if (fd2 >= 0) {
1321    if (fd >= 0)
1322      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1323    if (addr && addrlen)
1324      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1325  }
1326  return fd2;
1327}
1328#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
1329#else
1330#define INIT_ACCEPT
1331#endif
1332
1333#if SANITIZER_INTERCEPT_ACCEPT4
1334INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
1335  void *ctx;
1336  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
1337  unsigned addrlen0;
1338  if (addrlen) {
1339    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1340    addrlen0 = *addrlen;
1341  }
1342  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
1343  if (fd2 >= 0) {
1344    if (fd >= 0)
1345      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1346    if (addr && addrlen)
1347      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1348  }
1349  return fd2;
1350}
1351#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
1352#else
1353#define INIT_ACCEPT4
1354#endif
1355
1356#if SANITIZER_INTERCEPT_MODF
1357INTERCEPTOR(double, modf, double x, double *iptr) {
1358  void *ctx;
1359  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1360  double res = REAL(modf)(x, iptr);
1361  if (iptr) {
1362    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1363  }
1364  return res;
1365}
1366INTERCEPTOR(float, modff, float x, float *iptr) {
1367  void *ctx;
1368  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1369  float res = REAL(modff)(x, iptr);
1370  if (iptr) {
1371    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1372  }
1373  return res;
1374}
1375INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1376  void *ctx;
1377  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1378  long double res = REAL(modfl)(x, iptr);
1379  if (iptr) {
1380    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1381  }
1382  return res;
1383}
1384#define INIT_MODF            \
1385  INTERCEPT_FUNCTION(modf);  \
1386  INTERCEPT_FUNCTION(modff); \
1387  INTERCEPT_FUNCTION(modfl);
1388#else
1389#define INIT_MODF
1390#endif
1391
1392#if SANITIZER_INTERCEPT_RECVMSG
1393static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
1394                         SSIZE_T maxlen) {
1395  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
1396  if (msg->msg_name && msg->msg_namelen)
1397    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
1398  if (msg->msg_iov && msg->msg_iovlen)
1399    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
1400                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
1401  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
1402  if (msg->msg_control && msg->msg_controllen)
1403    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
1404}
1405
1406INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
1407            int flags) {
1408  void *ctx;
1409  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
1410  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
1411  if (res >= 0) {
1412    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1413    if (msg) write_msghdr(ctx, msg, res);
1414  }
1415  return res;
1416}
1417#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
1418#else
1419#define INIT_RECVMSG
1420#endif
1421
1422#if SANITIZER_INTERCEPT_GETPEERNAME
1423INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1424  void *ctx;
1425  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1426  unsigned addr_sz;
1427  if (addrlen) addr_sz = *addrlen;
1428  int res = REAL(getpeername)(sockfd, addr, addrlen);
1429  if (!res && addr && addrlen)
1430    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1431  return res;
1432}
1433#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1434#else
1435#define INIT_GETPEERNAME
1436#endif
1437
1438#if SANITIZER_INTERCEPT_SYSINFO
1439INTERCEPTOR(int, sysinfo, void *info) {
1440  void *ctx;
1441  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
1442  int res = REAL(sysinfo)(info);
1443  if (!res && info)
1444    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
1445  return res;
1446}
1447#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo);
1448#else
1449#define INIT_SYSINFO
1450#endif
1451
1452#if SANITIZER_INTERCEPT_READDIR
1453INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
1454  void *ctx;
1455  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
1456  __sanitizer_dirent *res = REAL(readdir)(dirp);
1457  if (res)
1458    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1459  return res;
1460}
1461
1462INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
1463            __sanitizer_dirent **result) {
1464  void *ctx;
1465  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
1466  int res = REAL(readdir_r)(dirp, entry, result);
1467  if (!res) {
1468    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1469    if (*result)
1470      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
1471  }
1472  return res;
1473}
1474
1475#define INIT_READDIR           \
1476  INTERCEPT_FUNCTION(readdir); \
1477  INTERCEPT_FUNCTION(readdir_r);
1478#else
1479#define INIT_READDIR
1480#endif
1481
1482#if SANITIZER_INTERCEPT_READDIR64
1483INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
1484  void *ctx;
1485  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
1486  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
1487  if (res)
1488    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1489  return res;
1490}
1491
1492INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
1493            __sanitizer_dirent64 **result) {
1494  void *ctx;
1495  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
1496  int res = REAL(readdir64_r)(dirp, entry, result);
1497  if (!res) {
1498    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1499    if (*result)
1500      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
1501  }
1502  return res;
1503}
1504#define INIT_READDIR64           \
1505  INTERCEPT_FUNCTION(readdir64); \
1506  INTERCEPT_FUNCTION(readdir64_r);
1507#else
1508#define INIT_READDIR64
1509#endif
1510
1511#if SANITIZER_INTERCEPT_PTRACE
1512INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
1513  void *ctx;
1514  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
1515
1516  if (data) {
1517    if (request == ptrace_setregs)
1518      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
1519    else if (request == ptrace_setfpregs)
1520      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1521    else if (request == ptrace_setfpxregs)
1522      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1523    else if (request == ptrace_setsiginfo)
1524      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
1525    else if (request == ptrace_setregset) {
1526      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1527      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
1528    }
1529  }
1530
1531  uptr res = REAL(ptrace)(request, pid, addr, data);
1532
1533  if (!res && data) {
1534    // Note that PEEK* requests assing different meaning to the return value.
1535    // This function does not handle them (nor does it need to).
1536    if (request == ptrace_getregs)
1537      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
1538    else if (request == ptrace_getfpregs)
1539      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1540    else if (request == ptrace_getfpxregs)
1541      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1542    else if (request == ptrace_getsiginfo)
1543      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
1544    else if (request == ptrace_getregset) {
1545      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1546      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
1547    }
1548  }
1549  return res;
1550}
1551
1552#define INIT_PTRACE           \
1553  INTERCEPT_FUNCTION(ptrace);
1554#else
1555#define INIT_PTRACE
1556#endif
1557
1558#if SANITIZER_INTERCEPT_SETLOCALE
1559INTERCEPTOR(char *, setlocale, int category, char *locale) {
1560  void *ctx;
1561  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
1562  if (locale)
1563    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
1564  char *res = REAL(setlocale)(category, locale);
1565  if (res)
1566    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1567  return res;
1568}
1569
1570#define INIT_SETLOCALE           \
1571  INTERCEPT_FUNCTION(setlocale);
1572#else
1573#define INIT_SETLOCALE
1574#endif
1575
1576#if SANITIZER_INTERCEPT_GETCWD
1577INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
1578  void *ctx;
1579  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
1580  char *res = REAL(getcwd)(buf, size);
1581  if (res)
1582    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1583  return res;
1584}
1585#define INIT_GETCWD           \
1586  INTERCEPT_FUNCTION(getcwd);
1587#else
1588#define INIT_GETCWD
1589#endif
1590
1591#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
1592INTERCEPTOR(char *, get_current_dir_name, int fake) {
1593  void *ctx;
1594  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
1595  char *res = REAL(get_current_dir_name)(fake);
1596  if (res)
1597    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1598  return res;
1599}
1600
1601#define INIT_GET_CURRENT_DIR_NAME           \
1602  INTERCEPT_FUNCTION(get_current_dir_name);
1603#else
1604#define INIT_GET_CURRENT_DIR_NAME
1605#endif
1606
1607#if SANITIZER_INTERCEPT_STRTOIMAX
1608INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
1609  void *ctx;
1610  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
1611  INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
1612  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1613  return res;
1614}
1615
1616INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
1617  void *ctx;
1618  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
1619  INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
1620  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1621  return res;
1622}
1623
1624#define INIT_STRTOIMAX           \
1625  INTERCEPT_FUNCTION(strtoimax); \
1626  INTERCEPT_FUNCTION(strtoumax);
1627#else
1628#define INIT_STRTOIMAX
1629#endif
1630
1631#if SANITIZER_INTERCEPT_MBSTOWCS
1632INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
1633  void *ctx;
1634  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
1635  SIZE_T res = REAL(mbstowcs)(dest, src, len);
1636  if (res != (SIZE_T) - 1 && dest) {
1637    SIZE_T write_cnt = res + (res < len);
1638    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1639  }
1640  return res;
1641}
1642
1643INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
1644            void *ps) {
1645  void *ctx;
1646  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
1647  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1648  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1649  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
1650  if (res != (SIZE_T)(-1) && dest && src) {
1651    // This function, and several others, may or may not write the terminating
1652    // \0 character. They write it iff they clear *src.
1653    SIZE_T write_cnt = res + !*src;
1654    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1655  }
1656  return res;
1657}
1658
1659#define INIT_MBSTOWCS           \
1660  INTERCEPT_FUNCTION(mbstowcs); \
1661  INTERCEPT_FUNCTION(mbsrtowcs);
1662#else
1663#define INIT_MBSTOWCS
1664#endif
1665
1666#if SANITIZER_INTERCEPT_MBSNRTOWCS
1667INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
1668            SIZE_T len, void *ps) {
1669  void *ctx;
1670  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
1671  if (src) {
1672    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1673    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1674  }
1675  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1676  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
1677  if (res != (SIZE_T)(-1) && dest && src) {
1678    SIZE_T write_cnt = res + !*src;
1679    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1680  }
1681  return res;
1682}
1683
1684#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs);
1685#else
1686#define INIT_MBSNRTOWCS
1687#endif
1688
1689#if SANITIZER_INTERCEPT_WCSTOMBS
1690INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
1691  void *ctx;
1692  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
1693  SIZE_T res = REAL(wcstombs)(dest, src, len);
1694  if (res != (SIZE_T) - 1 && dest) {
1695    SIZE_T write_cnt = res + (res < len);
1696    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1697  }
1698  return res;
1699}
1700
1701INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
1702            void *ps) {
1703  void *ctx;
1704  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
1705  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1706  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1707  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
1708  if (res != (SIZE_T) - 1 && dest && src) {
1709    SIZE_T write_cnt = res + !*src;
1710    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1711  }
1712  return res;
1713}
1714
1715#define INIT_WCSTOMBS           \
1716  INTERCEPT_FUNCTION(wcstombs); \
1717  INTERCEPT_FUNCTION(wcsrtombs);
1718#else
1719#define INIT_WCSTOMBS
1720#endif
1721
1722#if SANITIZER_INTERCEPT_WCSNRTOMBS
1723INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
1724            SIZE_T len, void *ps) {
1725  void *ctx;
1726  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
1727  if (src) {
1728    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1729    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1730  }
1731  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1732  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
1733  if (res != (SIZE_T) - 1 && dest && src) {
1734    SIZE_T write_cnt = res + !*src;
1735    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1736  }
1737  return res;
1738}
1739
1740#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs);
1741#else
1742#define INIT_WCSNRTOMBS
1743#endif
1744
1745
1746#if SANITIZER_INTERCEPT_TCGETATTR
1747INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
1748  void *ctx;
1749  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
1750  int res = REAL(tcgetattr)(fd, termios_p);
1751  if (!res && termios_p)
1752    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
1753  return res;
1754}
1755
1756#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr);
1757#else
1758#define INIT_TCGETATTR
1759#endif
1760
1761
1762#if SANITIZER_INTERCEPT_REALPATH
1763INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
1764  void *ctx;
1765  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
1766  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1767
1768  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
1769  // version of a versioned symbol. For realpath(), this gives us something
1770  // (called __old_realpath) that does not handle NULL in the second argument.
1771  // Handle it as part of the interceptor.
1772  char *allocated_path = 0;
1773  if (!resolved_path)
1774    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
1775
1776  char *res = REAL(realpath)(path, resolved_path);
1777  if (allocated_path && !res)
1778    WRAP(free)(allocated_path);
1779  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1780  return res;
1781}
1782#define INIT_REALPATH INTERCEPT_FUNCTION(realpath);
1783#else
1784#define INIT_REALPATH
1785#endif
1786
1787#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
1788INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
1789  void *ctx;
1790  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
1791  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1792  char *res = REAL(canonicalize_file_name)(path);
1793  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1794  return res;
1795}
1796#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name);
1797#else
1798#define INIT_CANONICALIZE_FILE_NAME
1799#endif
1800
1801#if SANITIZER_INTERCEPT_CONFSTR
1802INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
1803  void *ctx;
1804  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
1805  SIZE_T res = REAL(confstr)(name, buf, len);
1806  if (buf && res)
1807    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
1808  return res;
1809}
1810#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr);
1811#else
1812#define INIT_CONFSTR
1813#endif
1814
1815#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
1816INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
1817  void *ctx;
1818  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
1819  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
1820  if (mask && !res)
1821    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
1822  return res;
1823}
1824#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity);
1825#else
1826#define INIT_SCHED_GETAFFINITY
1827#endif
1828
1829#if SANITIZER_INTERCEPT_STRERROR
1830INTERCEPTOR(char *, strerror, int errnum) {
1831  void *ctx;
1832  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
1833  char *res = REAL(strerror)(errnum);
1834  if (res)
1835    COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1836  return res;
1837}
1838#define INIT_STRERROR INTERCEPT_FUNCTION(strerror);
1839#else
1840#define INIT_STRERROR
1841#endif
1842
1843#if SANITIZER_INTERCEPT_STRERROR_R
1844INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
1845  void *ctx;
1846  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
1847  char *res = REAL(strerror_r)(errnum, buf, buflen);
1848  // There are 2 versions of strerror_r:
1849  //  * POSIX version returns 0 on success, negative error code on failure,
1850  //    writes message to buf.
1851  //  * GNU version returns message pointer, which points to either buf or some
1852  //    static storage.
1853  SIZE_T posix_res = (SIZE_T)res;
1854  if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
1855    // POSIX version. Spec is not clear on whether buf is NULL-terminated.
1856    // At least on OSX, buf contents are valid even when the call fails.
1857    SIZE_T sz = internal_strnlen(buf, buflen);
1858    if (sz < buflen) ++sz;
1859    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
1860  } else {
1861    // GNU version.
1862    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1863  }
1864  return res;
1865}
1866#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r);
1867#else
1868#define INIT_STRERROR_R
1869#endif
1870
1871#if SANITIZER_INTERCEPT_SCANDIR
1872typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
1873typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
1874                                const struct __sanitizer_dirent **);
1875
1876static THREADLOCAL void *scandir_ctx;
1877static THREADLOCAL scandir_filter_f scandir_filter;
1878static THREADLOCAL scandir_compar_f scandir_compar;
1879
1880static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
1881  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1);
1882  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen);
1883  return scandir_filter(dir);
1884}
1885
1886static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
1887                                  const struct __sanitizer_dirent **b) {
1888  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2);
1889  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a));
1890  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen);
1891  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b));
1892  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen);
1893  return scandir_compar(a, b);
1894}
1895
1896INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
1897            scandir_filter_f filter, scandir_compar_f compar) {
1898  void *ctx;
1899  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
1900  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
1901  CHECK_EQ(0, scandir_ctx);
1902  scandir_ctx = ctx;
1903  scandir_filter = filter;
1904  scandir_compar = compar;
1905  int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0,
1906                          compar ? wrapped_scandir_compar : 0);
1907  scandir_ctx = 0;
1908  scandir_filter = 0;
1909  scandir_compar = 0;
1910  if (namelist && res > 0) {
1911    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
1912    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
1913    for (int i = 0; i < res; ++i)
1914      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
1915                                     (*namelist)[i]->d_reclen);
1916  }
1917  return res;
1918}
1919#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir);
1920#else
1921#define INIT_SCANDIR
1922#endif
1923
1924#if SANITIZER_INTERCEPT_SCANDIR64
1925typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
1926typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
1927                                  const struct __sanitizer_dirent64 **);
1928
1929static THREADLOCAL void *scandir64_ctx;
1930static THREADLOCAL scandir64_filter_f scandir64_filter;
1931static THREADLOCAL scandir64_compar_f scandir64_compar;
1932
1933static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
1934  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1);
1935  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen);
1936  return scandir64_filter(dir);
1937}
1938
1939static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
1940                                    const struct __sanitizer_dirent64 **b) {
1941  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2);
1942  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a));
1943  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen);
1944  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b));
1945  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen);
1946  return scandir64_compar(a, b);
1947}
1948
1949INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
1950            scandir64_filter_f filter, scandir64_compar_f compar) {
1951  void *ctx;
1952  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
1953  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
1954  CHECK_EQ(0, scandir64_ctx);
1955  scandir64_ctx = ctx;
1956  scandir64_filter = filter;
1957  scandir64_compar = compar;
1958  int res =
1959      REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0,
1960                      compar ? wrapped_scandir64_compar : 0);
1961  scandir64_ctx = 0;
1962  scandir64_filter = 0;
1963  scandir64_compar = 0;
1964  if (namelist && res > 0) {
1965    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
1966    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
1967    for (int i = 0; i < res; ++i)
1968      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
1969                                     (*namelist)[i]->d_reclen);
1970  }
1971  return res;
1972}
1973#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64);
1974#else
1975#define INIT_SCANDIR64
1976#endif
1977
1978#if SANITIZER_INTERCEPT_GETGROUPS
1979INTERCEPTOR(int, getgroups, int size, u32 *lst) {
1980  void *ctx;
1981  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
1982  int res = REAL(getgroups)(size, lst);
1983  if (res && lst)
1984    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
1985  return res;
1986}
1987#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups);
1988#else
1989#define INIT_GETGROUPS
1990#endif
1991
1992#if SANITIZER_INTERCEPT_POLL
1993static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
1994                        __sanitizer_nfds_t nfds) {
1995  for (unsigned i = 0; i < nfds; ++i) {
1996    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
1997    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
1998  }
1999}
2000
2001static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
2002                         __sanitizer_nfds_t nfds) {
2003  for (unsigned i = 0; i < nfds; ++i)
2004    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
2005                                   sizeof(fds[i].revents));
2006}
2007
2008INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2009            int timeout) {
2010  void *ctx;
2011  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
2012  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2013  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
2014  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2015  return res;
2016}
2017#define INIT_POLL INTERCEPT_FUNCTION(poll);
2018#else
2019#define INIT_POLL
2020#endif
2021
2022#if SANITIZER_INTERCEPT_PPOLL
2023INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2024            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
2025  void *ctx;
2026  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
2027  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2028  if (timeout_ts)
2029    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
2030  // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
2031  int res =
2032      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
2033  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2034  return res;
2035}
2036#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll);
2037#else
2038#define INIT_PPOLL
2039#endif
2040
2041#if SANITIZER_INTERCEPT_WORDEXP
2042INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
2043  void *ctx;
2044  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
2045  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
2046  int res = REAL(wordexp)(s, p, flags);
2047  if (!res && p) {
2048    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2049    if (p->we_wordc)
2050      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
2051                                     sizeof(*p->we_wordv) * p->we_wordc);
2052    for (uptr i = 0; i < p->we_wordc; ++i) {
2053      char *w = p->we_wordv[i];
2054      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
2055    }
2056  }
2057  return res;
2058}
2059#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp);
2060#else
2061#define INIT_WORDEXP
2062#endif
2063
2064#if SANITIZER_INTERCEPT_SIGWAIT
2065INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
2066  void *ctx;
2067  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
2068  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2069  int res = REAL(sigwait)(set, sig);
2070  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
2071  return res;
2072}
2073#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait);
2074#else
2075#define INIT_SIGWAIT
2076#endif
2077
2078#if SANITIZER_INTERCEPT_SIGWAITINFO
2079INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
2080  void *ctx;
2081  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
2082  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2083  int res = REAL(sigwaitinfo)(set, info);
2084  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2085  return res;
2086}
2087#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo);
2088#else
2089#define INIT_SIGWAITINFO
2090#endif
2091
2092#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
2093INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
2094            void *timeout) {
2095  void *ctx;
2096  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
2097  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
2098  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2099  int res = REAL(sigtimedwait)(set, info, timeout);
2100  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2101  return res;
2102}
2103#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait);
2104#else
2105#define INIT_SIGTIMEDWAIT
2106#endif
2107
2108#if SANITIZER_INTERCEPT_SIGSETOPS
2109INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
2110  void *ctx;
2111  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
2112  int res = REAL(sigemptyset)(set);
2113  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2114  return res;
2115}
2116
2117INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
2118  void *ctx;
2119  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
2120  int res = REAL(sigfillset)(set);
2121  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2122  return res;
2123}
2124#define INIT_SIGSETOPS             \
2125  INTERCEPT_FUNCTION(sigemptyset); \
2126  INTERCEPT_FUNCTION(sigfillset);
2127#else
2128#define INIT_SIGSETOPS
2129#endif
2130
2131#if SANITIZER_INTERCEPT_SIGPENDING
2132INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
2133  void *ctx;
2134  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
2135  int res = REAL(sigpending)(set);
2136  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2137  return res;
2138}
2139#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending);
2140#else
2141#define INIT_SIGPENDING
2142#endif
2143
2144#if SANITIZER_INTERCEPT_SIGPROCMASK
2145INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
2146            __sanitizer_sigset_t *oldset) {
2147  void *ctx;
2148  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
2149  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2150  int res = REAL(sigprocmask)(how, set, oldset);
2151  if (!res && oldset)
2152    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
2153  return res;
2154}
2155#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask);
2156#else
2157#define INIT_SIGPROCMASK
2158#endif
2159
2160#if SANITIZER_INTERCEPT_BACKTRACE
2161INTERCEPTOR(int, backtrace, void **buffer, int size) {
2162  void *ctx;
2163  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
2164  int res = REAL(backtrace)(buffer, size);
2165  if (res && buffer)
2166    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
2167  return res;
2168}
2169
2170INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
2171  void *ctx;
2172  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
2173  if (buffer && size)
2174    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
2175  char ** res = REAL(backtrace_symbols)(buffer, size);
2176  if (res && size) {
2177    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
2178    for (int i = 0; i < size; ++i)
2179      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
2180  }
2181  return res;
2182}
2183#define INIT_BACKTRACE           \
2184  INTERCEPT_FUNCTION(backtrace); \
2185  INTERCEPT_FUNCTION(backtrace_symbols);
2186#else
2187#define INIT_BACKTRACE
2188#endif
2189
2190#if SANITIZER_INTERCEPT__EXIT
2191INTERCEPTOR(void, _exit, int status) {
2192  void *ctx;
2193  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
2194  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
2195  if (status == 0)
2196    status = status1;
2197  REAL(_exit)(status);
2198}
2199#define INIT__EXIT INTERCEPT_FUNCTION(_exit);
2200#else
2201#define INIT__EXIT
2202#endif
2203
2204#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
2205INTERCEPTOR(int, pthread_mutex_lock, void *m) {
2206  void *ctx;
2207  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
2208  int res = REAL(pthread_mutex_lock)(m);
2209  if (res == 0)
2210    COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2211  return res;
2212}
2213
2214INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
2215  void *ctx;
2216  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
2217  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2218  return REAL(pthread_mutex_unlock)(m);
2219}
2220
2221#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock)
2222#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock)
2223#else
2224#define INIT_PTHREAD_MUTEX_LOCK
2225#define INIT_PTHREAD_MUTEX_UNLOCK
2226#endif
2227
2228#if SANITIZER_INTERCEPT_PTHREAD_COND
2229INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {
2230  void *ctx;
2231  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m);
2232  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2233  COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2234  int res = REAL(pthread_cond_wait)(c, m);
2235  COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2236  return res;
2237}
2238
2239INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
2240  void *ctx;
2241  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a);
2242  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz);
2243  return REAL(pthread_cond_init)(c, a);
2244}
2245
2246INTERCEPTOR(int, pthread_cond_signal, void *c) {
2247  void *ctx;
2248  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c);
2249  COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2250  return REAL(pthread_cond_signal)(c);
2251}
2252
2253INTERCEPTOR(int, pthread_cond_broadcast, void *c) {
2254  void *ctx;
2255  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c);
2256  COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2257  return REAL(pthread_cond_broadcast)(c);
2258}
2259
2260#define INIT_PTHREAD_COND_WAIT \
2261  INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2)
2262#define INIT_PTHREAD_COND_INIT \
2263  INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2)
2264#define INIT_PTHREAD_COND_SIGNAL \
2265  INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2)
2266#define INIT_PTHREAD_COND_BROADCAST \
2267  INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2)
2268#else
2269#define INIT_PTHREAD_COND_WAIT
2270#define INIT_PTHREAD_COND_INIT
2271#define INIT_PTHREAD_COND_SIGNAL
2272#define INIT_PTHREAD_COND_BROADCAST
2273#endif
2274
2275#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
2276static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
2277  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
2278  if (mnt->mnt_fsname)
2279    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
2280                                   REAL(strlen)(mnt->mnt_fsname) + 1);
2281  if (mnt->mnt_dir)
2282    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
2283                                   REAL(strlen)(mnt->mnt_dir) + 1);
2284  if (mnt->mnt_type)
2285    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
2286                                   REAL(strlen)(mnt->mnt_type) + 1);
2287  if (mnt->mnt_opts)
2288    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
2289                                   REAL(strlen)(mnt->mnt_opts) + 1);
2290}
2291#endif
2292
2293#if SANITIZER_INTERCEPT_GETMNTENT
2294INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
2295  void *ctx;
2296  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
2297  __sanitizer_mntent *res = REAL(getmntent)(fp);
2298  if (res) write_mntent(ctx, res);
2299  return res;
2300}
2301#define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent);
2302#else
2303#define INIT_GETMNTENT
2304#endif
2305
2306#if SANITIZER_INTERCEPT_GETMNTENT_R
2307INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
2308            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
2309  void *ctx;
2310  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
2311  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
2312  if (res) write_mntent(ctx, res);
2313  return res;
2314}
2315#define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r);
2316#else
2317#define INIT_GETMNTENT_R
2318#endif
2319
2320#if SANITIZER_INTERCEPT_STATFS
2321INTERCEPTOR(int, statfs, char *path, void *buf) {
2322  void *ctx;
2323  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
2324  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2325  int res = REAL(statfs)(path, buf);
2326  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
2327  return res;
2328}
2329INTERCEPTOR(int, fstatfs, int fd, void *buf) {
2330  void *ctx;
2331  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
2332  int res = REAL(fstatfs)(fd, buf);
2333  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
2334  return res;
2335}
2336#define INIT_STATFS           \
2337  INTERCEPT_FUNCTION(statfs); \
2338  INTERCEPT_FUNCTION(fstatfs);
2339#else
2340#define INIT_STATFS
2341#endif
2342
2343#if SANITIZER_INTERCEPT_STATFS64
2344INTERCEPTOR(int, statfs64, char *path, void *buf) {
2345  void *ctx;
2346  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
2347  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2348  int res = REAL(statfs64)(path, buf);
2349  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
2350  return res;
2351}
2352INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
2353  void *ctx;
2354  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
2355  int res = REAL(fstatfs64)(fd, buf);
2356  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
2357  return res;
2358}
2359#define INIT_STATFS64           \
2360  INTERCEPT_FUNCTION(statfs64); \
2361  INTERCEPT_FUNCTION(fstatfs64);
2362#else
2363#define INIT_STATFS64
2364#endif
2365
2366#if SANITIZER_INTERCEPT_STATVFS
2367INTERCEPTOR(int, statvfs, char *path, void *buf) {
2368  void *ctx;
2369  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
2370  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2371  int res = REAL(statvfs)(path, buf);
2372  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
2373  return res;
2374}
2375INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
2376  void *ctx;
2377  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
2378  int res = REAL(fstatvfs)(fd, buf);
2379  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
2380  return res;
2381}
2382#define INIT_STATVFS           \
2383  INTERCEPT_FUNCTION(statvfs); \
2384  INTERCEPT_FUNCTION(fstatvfs);
2385#else
2386#define INIT_STATVFS
2387#endif
2388
2389#if SANITIZER_INTERCEPT_STATVFS64
2390INTERCEPTOR(int, statvfs64, char *path, void *buf) {
2391  void *ctx;
2392  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
2393  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2394  int res = REAL(statvfs64)(path, buf);
2395  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
2396  return res;
2397}
2398INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
2399  void *ctx;
2400  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
2401  int res = REAL(fstatvfs64)(fd, buf);
2402  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
2403  return res;
2404}
2405#define INIT_STATVFS64           \
2406  INTERCEPT_FUNCTION(statvfs64); \
2407  INTERCEPT_FUNCTION(fstatvfs64);
2408#else
2409#define INIT_STATVFS64
2410#endif
2411
2412#if SANITIZER_INTERCEPT_INITGROUPS
2413INTERCEPTOR(int, initgroups, char *user, u32 group) {
2414  void *ctx;
2415  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
2416  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
2417  int res = REAL(initgroups)(user, group);
2418  return res;
2419}
2420#define INIT_INITGROUPS INTERCEPT_FUNCTION(initgroups);
2421#else
2422#define INIT_INITGROUPS
2423#endif
2424
2425#if SANITIZER_INTERCEPT_ETHER
2426INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
2427  void *ctx;
2428  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
2429  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2430  char *res = REAL(ether_ntoa)(addr);
2431  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2432  return res;
2433}
2434INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
2435  void *ctx;
2436  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
2437  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2438  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
2439  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res));
2440  return res;
2441}
2442INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
2443  void *ctx;
2444  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
2445  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2446  int res = REAL(ether_ntohost)(hostname, addr);
2447  if (!res && hostname)
2448    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2449  return res;
2450}
2451INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
2452  void *ctx;
2453  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
2454  if (hostname)
2455    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2456  int res = REAL(ether_hostton)(hostname, addr);
2457  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2458  return res;
2459}
2460INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
2461            char *hostname) {
2462  void *ctx;
2463  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
2464  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
2465  int res = REAL(ether_line)(line, addr, hostname);
2466  if (!res) {
2467    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2468    if (hostname)
2469      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2470  }
2471  return res;
2472}
2473#define INIT_ETHER                   \
2474  INTERCEPT_FUNCTION(ether_ntoa);    \
2475  INTERCEPT_FUNCTION(ether_aton);    \
2476  INTERCEPT_FUNCTION(ether_ntohost); \
2477  INTERCEPT_FUNCTION(ether_hostton); \
2478  INTERCEPT_FUNCTION(ether_line);
2479#else
2480#define INIT_ETHER
2481#endif
2482
2483#if SANITIZER_INTERCEPT_ETHER_R
2484INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
2485  void *ctx;
2486  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
2487  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2488  char *res = REAL(ether_ntoa_r)(addr, buf);
2489  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2490  return res;
2491}
2492INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
2493            __sanitizer_ether_addr *addr) {
2494  void *ctx;
2495  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
2496  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2497  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
2498  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
2499  return res;
2500}
2501#define INIT_ETHER_R                 \
2502  INTERCEPT_FUNCTION(ether_ntoa_r);  \
2503  INTERCEPT_FUNCTION(ether_aton_r);
2504#else
2505#define INIT_ETHER_R
2506#endif
2507
2508#if SANITIZER_INTERCEPT_SHMCTL
2509INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
2510  void *ctx;
2511  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
2512  int res = REAL(shmctl)(shmid, cmd, buf);
2513  if (res >= 0) {
2514    unsigned sz = 0;
2515    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
2516      sz = sizeof(__sanitizer_shmid_ds);
2517    else if (cmd == shmctl_ipc_info)
2518      sz = struct_shminfo_sz;
2519    else if (cmd == shmctl_shm_info)
2520      sz = struct_shm_info_sz;
2521    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2522  }
2523  return res;
2524}
2525#define INIT_SHMCTL INTERCEPT_FUNCTION(shmctl);
2526#else
2527#define INIT_SHMCTL
2528#endif
2529
2530#if SANITIZER_INTERCEPT_RANDOM_R
2531INTERCEPTOR(int, random_r, void *buf, u32 *result) {
2532  void *ctx;
2533  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
2534  int res = REAL(random_r)(buf, result);
2535  if (!res && result)
2536    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2537  return res;
2538}
2539#define INIT_RANDOM_R INTERCEPT_FUNCTION(random_r);
2540#else
2541#define INIT_RANDOM_R
2542#endif
2543
2544#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \
2545    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED
2546#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz)                      \
2547  INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) {   \
2548    void *ctx;                                                      \
2549    COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \
2550    int res = REAL(pthread_attr_get##what)(attr, r);                \
2551    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz);      \
2552    return res;                                                     \
2553  }
2554#endif
2555
2556#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
2557INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
2558INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
2559INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
2560INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
2561INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
2562INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
2563INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
2564  void *ctx;
2565  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
2566  int res = REAL(pthread_attr_getstack)(attr, addr, size);
2567  if (!res) {
2568    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2569    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
2570  }
2571  return res;
2572}
2573
2574#define INIT_PTHREAD_ATTR_GET                       \
2575  INTERCEPT_FUNCTION(pthread_attr_getdetachstate);  \
2576  INTERCEPT_FUNCTION(pthread_attr_getguardsize);    \
2577  INTERCEPT_FUNCTION(pthread_attr_getschedparam);   \
2578  INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);  \
2579  INTERCEPT_FUNCTION(pthread_attr_getscope);        \
2580  INTERCEPT_FUNCTION(pthread_attr_getstacksize);    \
2581  INTERCEPT_FUNCTION(pthread_attr_getstack);
2582#else
2583#define INIT_PTHREAD_ATTR_GET
2584#endif
2585
2586#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
2587INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
2588
2589#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
2590  INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
2591#else
2592#define INIT_PTHREAD_ATTR_GETINHERITSCHED
2593#endif
2594
2595#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
2596INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
2597            void *cpuset) {
2598  void *ctx;
2599  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
2600                           cpuset);
2601  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
2602  if (!res && cpusetsize && cpuset)
2603    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
2604  return res;
2605}
2606
2607#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
2608  INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
2609#else
2610#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
2611#endif
2612
2613#if SANITIZER_INTERCEPT_TMPNAM
2614INTERCEPTOR(char *, tmpnam, char *s) {
2615  void *ctx;
2616  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
2617  char *res = REAL(tmpnam)(s);
2618  if (res) {
2619    if (s)
2620      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
2621    else
2622      COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2623  }
2624  return res;
2625}
2626#define INIT_TMPNAM INTERCEPT_FUNCTION(tmpnam);
2627#else
2628#define INIT_TMPNAM
2629#endif
2630
2631#if SANITIZER_INTERCEPT_TMPNAM_R
2632INTERCEPTOR(char *, tmpnam_r, char *s) {
2633  void *ctx;
2634  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
2635  char *res = REAL(tmpnam_r)(s);
2636  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
2637  return res;
2638}
2639#define INIT_TMPNAM_R INTERCEPT_FUNCTION(tmpnam_r);
2640#else
2641#define INIT_TMPNAM_R
2642#endif
2643
2644#if SANITIZER_INTERCEPT_TEMPNAM
2645INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
2646  void *ctx;
2647  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
2648  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
2649  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
2650  char *res = REAL(tempnam)(dir, pfx);
2651  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2652  return res;
2653}
2654#define INIT_TEMPNAM INTERCEPT_FUNCTION(tempnam);
2655#else
2656#define INIT_TEMPNAM
2657#endif
2658
2659#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
2660INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
2661  void *ctx;
2662  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
2663  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
2664  return REAL(pthread_setname_np)(thread, name);
2665}
2666#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np);
2667#else
2668#define INIT_PTHREAD_SETNAME_NP
2669#endif
2670
2671#if SANITIZER_INTERCEPT_SINCOS
2672INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
2673  void *ctx;
2674  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
2675  REAL(sincos)(x, sin, cos);
2676  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
2677  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
2678}
2679INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
2680  void *ctx;
2681  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
2682  REAL(sincosf)(x, sin, cos);
2683  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
2684  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
2685}
2686INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
2687  void *ctx;
2688  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
2689  REAL(sincosl)(x, sin, cos);
2690  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
2691  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
2692}
2693#define INIT_SINCOS            \
2694  INTERCEPT_FUNCTION(sincos);  \
2695  INTERCEPT_FUNCTION(sincosf); \
2696  INTERCEPT_FUNCTION(sincosl);
2697#else
2698#define INIT_SINCOS
2699#endif
2700
2701#if SANITIZER_INTERCEPT_REMQUO
2702INTERCEPTOR(double, remquo, double x, double y, int *quo) {
2703  void *ctx;
2704  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
2705  double res = REAL(remquo)(x, y, quo);
2706  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
2707  return res;
2708}
2709INTERCEPTOR(float, remquof, float x, float y, int *quo) {
2710  void *ctx;
2711  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
2712  float res = REAL(remquof)(x, y, quo);
2713  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
2714  return res;
2715}
2716INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
2717  void *ctx;
2718  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
2719  long double res = REAL(remquol)(x, y, quo);
2720  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
2721  return res;
2722}
2723#define INIT_REMQUO            \
2724  INTERCEPT_FUNCTION(remquo);  \
2725  INTERCEPT_FUNCTION(remquof); \
2726  INTERCEPT_FUNCTION(remquol);
2727#else
2728#define INIT_REMQUO
2729#endif
2730
2731#if SANITIZER_INTERCEPT_LGAMMA
2732extern int signgam;
2733INTERCEPTOR(double, lgamma, double x) {
2734  void *ctx;
2735  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
2736  double res = REAL(lgamma)(x);
2737  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
2738  return res;
2739}
2740INTERCEPTOR(float, lgammaf, float x) {
2741  void *ctx;
2742  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
2743  float res = REAL(lgammaf)(x);
2744  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
2745  return res;
2746}
2747INTERCEPTOR(long double, lgammal, long double x) {
2748  void *ctx;
2749  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
2750  long double res = REAL(lgammal)(x);
2751  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
2752  return res;
2753}
2754#define INIT_LGAMMA            \
2755  INTERCEPT_FUNCTION(lgamma);  \
2756  INTERCEPT_FUNCTION(lgammaf); \
2757  INTERCEPT_FUNCTION(lgammal);
2758#else
2759#define INIT_LGAMMA
2760#endif
2761
2762#if SANITIZER_INTERCEPT_LGAMMA_R
2763INTERCEPTOR(double, lgamma_r, double x, int *signp) {
2764  void *ctx;
2765  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
2766  double res = REAL(lgamma_r)(x, signp);
2767  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
2768  return res;
2769}
2770INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
2771  void *ctx;
2772  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
2773  float res = REAL(lgammaf_r)(x, signp);
2774  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
2775  return res;
2776}
2777INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
2778  void *ctx;
2779  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
2780  long double res = REAL(lgammal_r)(x, signp);
2781  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
2782  return res;
2783}
2784#define INIT_LGAMMA_R            \
2785  INTERCEPT_FUNCTION(lgamma_r);  \
2786  INTERCEPT_FUNCTION(lgammaf_r); \
2787  INTERCEPT_FUNCTION(lgammal_r);
2788#else
2789#define INIT_LGAMMA_R
2790#endif
2791
2792#if SANITIZER_INTERCEPT_DRAND48_R
2793INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
2794  void *ctx;
2795  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
2796  int res = REAL(drand48_r)(buffer, result);
2797  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2798  return res;
2799}
2800INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
2801  void *ctx;
2802  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
2803  int res = REAL(lrand48_r)(buffer, result);
2804  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2805  return res;
2806}
2807#define INIT_DRAND48_R            \
2808  INTERCEPT_FUNCTION(drand48_r);  \
2809  INTERCEPT_FUNCTION(lrand48_r);
2810#else
2811#define INIT_DRAND48_R
2812#endif
2813
2814#define SANITIZER_COMMON_INTERCEPTORS_INIT \
2815  INIT_STRCMP;                             \
2816  INIT_STRNCMP;                            \
2817  INIT_STRCASECMP;                         \
2818  INIT_STRNCASECMP;                        \
2819  INIT_READ;                               \
2820  INIT_PREAD;                              \
2821  INIT_PREAD64;                            \
2822  INIT_READV;                              \
2823  INIT_PREADV;                             \
2824  INIT_PREADV64;                           \
2825  INIT_WRITE;                              \
2826  INIT_PWRITE;                             \
2827  INIT_PWRITE64;                           \
2828  INIT_WRITEV;                             \
2829  INIT_PWRITEV;                            \
2830  INIT_PWRITEV64;                          \
2831  INIT_PRCTL;                              \
2832  INIT_LOCALTIME_AND_FRIENDS;              \
2833  INIT_SCANF;                              \
2834  INIT_ISOC99_SCANF;                       \
2835  INIT_FREXP;                              \
2836  INIT_FREXPF_FREXPL;                      \
2837  INIT_GETPWNAM_AND_FRIENDS;               \
2838  INIT_GETPWNAM_R_AND_FRIENDS;             \
2839  INIT_CLOCK_GETTIME;                      \
2840  INIT_GETITIMER;                          \
2841  INIT_TIME;                               \
2842  INIT_GLOB;                               \
2843  INIT_WAIT;                               \
2844  INIT_INET;                               \
2845  INIT_PTHREAD_GETSCHEDPARAM;              \
2846  INIT_GETADDRINFO;                        \
2847  INIT_GETNAMEINFO;                        \
2848  INIT_GETSOCKNAME;                        \
2849  INIT_GETHOSTBYNAME;                      \
2850  INIT_GETHOSTBYNAME_R;                    \
2851  INIT_GETSOCKOPT;                         \
2852  INIT_ACCEPT;                             \
2853  INIT_ACCEPT4;                            \
2854  INIT_MODF;                               \
2855  INIT_RECVMSG;                            \
2856  INIT_GETPEERNAME;                        \
2857  INIT_IOCTL;                              \
2858  INIT_INET_ATON;                          \
2859  INIT_SYSINFO;                            \
2860  INIT_READDIR;                            \
2861  INIT_READDIR64;                          \
2862  INIT_PTRACE;                             \
2863  INIT_SETLOCALE;                          \
2864  INIT_GETCWD;                             \
2865  INIT_GET_CURRENT_DIR_NAME;               \
2866  INIT_STRTOIMAX;                          \
2867  INIT_MBSTOWCS;                           \
2868  INIT_MBSNRTOWCS;                         \
2869  INIT_WCSTOMBS;                           \
2870  INIT_WCSNRTOMBS;                         \
2871  INIT_TCGETATTR;                          \
2872  INIT_REALPATH;                           \
2873  INIT_CANONICALIZE_FILE_NAME;             \
2874  INIT_CONFSTR;                            \
2875  INIT_SCHED_GETAFFINITY;                  \
2876  INIT_STRERROR;                           \
2877  INIT_STRERROR_R;                         \
2878  INIT_SCANDIR;                            \
2879  INIT_SCANDIR64;                          \
2880  INIT_GETGROUPS;                          \
2881  INIT_POLL;                               \
2882  INIT_PPOLL;                              \
2883  INIT_WORDEXP;                            \
2884  INIT_SIGWAIT;                            \
2885  INIT_SIGWAITINFO;                        \
2886  INIT_SIGTIMEDWAIT;                       \
2887  INIT_SIGSETOPS;                          \
2888  INIT_SIGPENDING;                         \
2889  INIT_SIGPROCMASK;                        \
2890  INIT_BACKTRACE;                          \
2891  INIT__EXIT;                              \
2892  INIT_PTHREAD_MUTEX_LOCK;                 \
2893  INIT_PTHREAD_MUTEX_UNLOCK;               \
2894  INIT_PTHREAD_COND_WAIT;                  \
2895  INIT_PTHREAD_COND_INIT;                  \
2896  INIT_PTHREAD_COND_SIGNAL;                \
2897  INIT_PTHREAD_COND_BROADCAST;             \
2898  INIT_GETMNTENT;                          \
2899  INIT_GETMNTENT_R;                        \
2900  INIT_STATFS;                             \
2901  INIT_STATFS64;                           \
2902  INIT_STATVFS;                            \
2903  INIT_STATVFS64;                          \
2904  INIT_INITGROUPS;                         \
2905  INIT_ETHER;                              \
2906  INIT_ETHER_R;                            \
2907  INIT_SHMCTL;                             \
2908  INIT_RANDOM_R;                           \
2909  INIT_PTHREAD_ATTR_GET;                   \
2910  INIT_PTHREAD_ATTR_GETINHERITSCHED;       \
2911  INIT_PTHREAD_ATTR_GETAFFINITY_NP;        \
2912  INIT_TMPNAM;                             \
2913  INIT_TMPNAM_R;                           \
2914  INIT_TEMPNAM;                            \
2915  INIT_PTHREAD_SETNAME_NP;                 \
2916  INIT_SINCOS;                             \
2917  INIT_REMQUO;                             \
2918  INIT_LGAMMA;                             \
2919  INIT_LGAMMA_R;                           \
2920  INIT_DRAND48_R;                          \
2921/**/
2922