sanitizer_common_interceptors.inc revision e43d2108ec7622afb34b8281005a12fcdb26d6fa
14f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
28530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
38530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//                     The LLVM Compiler Infrastructure
48530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
58530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// This file is distributed under the University of Illinois Open Source
68530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// License. See LICENSE.TXT for details.
78530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
88530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//===----------------------------------------------------------------------===//
98530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
108530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// Common function interceptors for tools like AddressSanitizer,
118530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// ThreadSanitizer, MemorySanitizer, etc.
128530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// This file should be included into the tool's interceptor file,
148530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// which has to define it's own macros:
158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_ENTER
168530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_READ_RANGE
178530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_WRITE_RANGE
18c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_ACQUIRE
19c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_RELEASE
20c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany//   COMMON_INTERCEPTOR_SET_THREAD_NAME
218530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//===----------------------------------------------------------------------===//
226afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany#include "interception/interception.h"
2374737d595c4e3638b980bd88b0492247ae4318faAlexey Samsonov#include "sanitizer_platform_interceptors.h"
24b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany
25996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include <stdarg.h>
26996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2730e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#if SANITIZER_WINDOWS
28348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#define va_copy(dst, src) ((dst) = (src))
29348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#endif // _WIN32
30348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov
31be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#if SANITIZER_INTERCEPT_STRCASECMP
32be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
33be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c1_low = ToLower(c1);
34be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c2_low = ToLower(c2);
35be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return c1_low - c2_low;
36be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
37be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
38be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
39be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
40be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
41be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
42be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
43be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  for (i = 0; ; i++) {
44be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
45be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
46be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
47be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov      break;
48be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
49be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
50be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
51be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
52be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
53be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
54be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
55be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
56be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
57be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
58be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
59be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  for (i = 0; i < n; i++) {
60be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
61be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
62be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
63be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov      break;
64be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
65be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
66be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
67be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
68be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
69be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
70be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
71be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
72be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#else
73be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRCASECMP
74be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRNCASECMP
75be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#endif
76be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
777cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#if SANITIZER_INTERCEPT_FREXP
787cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(double, frexp, double x, int *exp) {
797cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
807cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
817cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  double res = REAL(frexp)(x, exp);
827cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
837cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
847cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
857cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
86ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
87ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#else
88ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXP
89ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#endif // SANITIZER_INTERCEPT_FREXP
90ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov
91ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#if SANITIZER_INTERCEPT_FREXPF_FREXPL
927cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(float, frexpf, float x, int *exp) {
937cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
947cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
957cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  float res = REAL(frexpf)(x, exp);
967cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
977cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
987cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
997cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
1007cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(long double, frexpl, long double x, int *exp) {
1017cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
1027cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
1037cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  long double res = REAL(frexpl)(x, exp);
1047cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
1057cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
1067cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
1077cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
108ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXPF_FREXPL                       \
1097cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  INTERCEPT_FUNCTION(frexpf);                    \
1107cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  INTERCEPT_FUNCTION(frexpl)
1117cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#else
112ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXPF_FREXPL
113ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
1147cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
115b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SI_NOT_WINDOWS
116b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
117b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        SIZE_T iovlen, SIZE_T maxlen) {
118b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
119b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
120b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
121b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    maxlen -= sz;
122b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  }
123b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
124b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
125b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
126b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                       SIZE_T iovlen, SIZE_T maxlen) {
127b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
128b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
129b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
130b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
131b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    maxlen -= sz;
132b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  }
133b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
134b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
135b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
1368ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#if SANITIZER_INTERCEPT_READ
1376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
13844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
139996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
1406afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(read)(fd, ptr, count);
1418530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
142996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
143c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
144996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1458530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
1468530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
14744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ INTERCEPT_FUNCTION(read)
148c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
14944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ
1508ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#endif
1518530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
152c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#if SANITIZER_INTERCEPT_PREAD
1536afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
15444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
155996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
1566afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
1578530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
158996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
159c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
160996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1618530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
1628530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
16344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD INTERCEPT_FUNCTION(pread)
164c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
16544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD
166c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#endif
1678530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
168b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany#if SANITIZER_INTERCEPT_PREAD64
1696afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
17044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
171996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
1726afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
1738530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
174996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
175c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
176996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1778530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
1788530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
17944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
180c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
18144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64
1821f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko#endif
1838530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
184b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_READV
185b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
186b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        int iovcnt) {
187b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
188b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
189b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
190b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
191b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
192b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
193b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
194b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_READV INTERCEPT_FUNCTION(readv)
195b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
196b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_READV
197b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
198b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
199b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PREADV
200b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
201b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF_T offset) {
202b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
203b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
204b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
205b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
206b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
207b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
208b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
209b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV INTERCEPT_FUNCTION(preadv)
210b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
211b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV
212b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
213b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
214b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PREADV64
215b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
216b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF64_T offset) {
217b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
218b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
219b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
220b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
221b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
222b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
223b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
224b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64)
225b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
226b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV64
227b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
228b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
229c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_WRITE
230c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya SerebryanyINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
23144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
232996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
233c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
234996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
235c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  SSIZE_T res = REAL(write)(fd, ptr, count);
236b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  // FIXME: this check should be _before_ the call to REAL(write), not after
237c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
238996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
239c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
240c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
24144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE INTERCEPT_FUNCTION(write)
242153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
24344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE
244153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
245153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
246c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE
247f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
24844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
249f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
250c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
251996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
252f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
253c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
254996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
255c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
256c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
25744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
258153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
25944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE
260153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
261153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
262c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE64
263f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
264f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov            OFF64_T offset) {
26544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
266f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
267c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
268996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
269f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
270c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
271996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
272c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
273c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
27444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
275153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
27644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64
277153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
278153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
279b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_WRITEV
280b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
281b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        int iovcnt) {
282b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
283b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
284b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
285b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
286b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
287b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
288b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
289b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_WRITEV INTERCEPT_FUNCTION(writev)
290b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
291b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_WRITEV
292b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
293b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
294b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PWRITEV
295b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
296b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF_T offset) {
297b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
298b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
299b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
300b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
301b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
302b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
303b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
304b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev)
305b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
306b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV
307b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
308b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
309b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PWRITEV64
310b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
311b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF64_T offset) {
312b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
313b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
314b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
315b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
316b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
317b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
318b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
319b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64)
320b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
321b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV64
322b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
323b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
324c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PRCTL
32569b109a665247d424874253b412fe9b5253d1702Evgeniy StepanovINTERCEPTOR(int, prctl, int option,
32669b109a665247d424874253b412fe9b5253d1702Evgeniy Stepanov            unsigned long arg2, unsigned long arg3,   // NOLINT
32744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov            unsigned long arg4, unsigned long arg5) { // NOLINT
32844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
329996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
330c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  static const int PR_SET_NAME = 15;
331c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
332c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (option == PR_SET_NAME) {
333c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    char buff[16];
33444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov    internal_strncpy(buff, (char *)arg2, 15);
335c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    buff[15] = 0;
336996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
337c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  }
338c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
339c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
34044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
341c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
34244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL
34344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#endif // SANITIZER_INTERCEPT_PRCTL
344996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
345fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
346fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#if SANITIZER_INTERCEPT_TIME
347fef660506e9e5703fedfee01d614abd4b741c738Evgeniy StepanovINTERCEPTOR(unsigned long, time, unsigned long *t) {
348fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  void *ctx;
349fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
350fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  unsigned long res = REAL(time)(t);
35115832c2afc4f04fa558160441d1b01fb3f0ec08bAlexander Potapenko  if (t && res != (unsigned long)-1) {
352fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
353fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  }
354fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  return res;
355fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov}
356fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#define INIT_TIME                                \
357fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  INTERCEPT_FUNCTION(time);
358fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#else
359fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#define INIT_TIME
360fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#endif // SANITIZER_INTERCEPT_TIME
361fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
362fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
3639358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
3649358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, localtime, unsigned long *timep) {
3659358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
3679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(localtime)(timep);
3689358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
3709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
3719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3729358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3739358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3749358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
3759358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3769358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
3779358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(localtime_r)(timep, result);
3789358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3799358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
3809358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
3819358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3849358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, gmtime, unsigned long *timep) {
3859358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
3879358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(gmtime)(timep);
3889358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
3909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
3919358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3949358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
3959358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3969358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
3979358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(gmtime_r)(timep, result);
3989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
4009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
4019358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
4029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
4039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
4049358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime, unsigned long *timep) {
4059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
4069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
4079358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime)(timep);
4089358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
4099358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
4109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
4119358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
4129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
4139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
4149358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
4159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
4169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
4179358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime_r)(timep, result);
4189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
4199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
4209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
4219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
4229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
4239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
4249358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, asctime, void *tm) {
4259358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
4269358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
4279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime)(tm);
4289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
4299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
4309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
4319358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
4329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
4339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
4349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, asctime_r, void *tm, char *result) {
4359358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
4369358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
4379358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime_r)(tm, result);
4389358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
4399358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
4409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
4419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
4429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
4439358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
4449358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS               \
4459358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(localtime);                 \
4469358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(localtime_r);               \
4479358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(gmtime);                    \
4489358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(gmtime_r);                  \
4499358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(ctime);                     \
4509358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(ctime_r);                   \
4519358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(asctime);                   \
4529358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(asctime_r);
4539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#else
4549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS
4559358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
4569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
457996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANF
458996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
4594f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common_interceptors_scanf.inc"
460996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
461c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
4624ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
4634ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
4644ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
4654ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list aq;                                                                \
4664ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_copy(aq, ap);                                                           \
4674ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = REAL(vname)(__VA_ARGS__);                                        \
4684ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    if (res > 0)                                                               \
469c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
4704ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(aq);                                                                \
4714ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
4724ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
473996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
4744ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vscanf, const char *format, va_list ap)
475c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
476996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
4774ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
478c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
479996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
4804ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
481c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
482996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
4839eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
4844ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
485c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
486996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
4874ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
4884ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov            va_list ap)
489c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
4904ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
4914ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
492c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
4939eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
4944ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
4954ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
4964ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
4974ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
4984ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
4994ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list ap;                                                                \
5004ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_start(ap, format);                                                      \
5014ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = vname(__VA_ARGS__, ap);                                          \
5024ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(ap);                                                                \
5034ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
5044ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
5054ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
5064ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, scanf, const char *format, ...)
5074ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
5084ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
5094ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
5104ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
5114ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
5124ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
5134ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
5144ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
5159eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
5164ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
5174ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
5184ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
5194ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
5204ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
5214ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
5224ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
5234ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
5249eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif
525996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
52644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_SCANF                                                             \
52744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(scanf);                                                   \
5284ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(sscanf);                                                  \
52944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(fscanf);                                                  \
53044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(vscanf);                                                  \
53144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(vsscanf);                                                 \
5324ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(vfscanf);                                                 \
5334ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
5344ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
5354ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
5364ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
5374ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
5384ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vfscanf);
539996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
540996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#else
541996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define INIT_SCANF
542996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#endif
543996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
544745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
5454e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#if SANITIZER_INTERCEPT_IOCTL
546745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov#include "sanitizer_common_interceptors_ioctl.inc"
5474e95e949c335dd92b193ff270754e31d144e53bfEvgeniy StepanovINTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
5484e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  void *ctx;
5494e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
5504e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
5514e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  CHECK(ioctl_initialized);
5524e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
5534e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // Note: TSan does not use common flags, and they are zero-initialized.
5544e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // This effectively disables ioctl handling in TSan.
5554e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (!common_flags()->handle_ioctl)
5564e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    return REAL(ioctl)(d, request, arg);
5574e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
5584e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  const ioctl_desc *desc = ioctl_lookup(request);
5594e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (!desc)
5604e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    Printf("WARNING: unknown ioctl %x\n", request);
5614e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
5624e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (desc)
5634e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    ioctl_common_pre(ctx, desc, d, request, arg);
5644e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  int res = REAL(ioctl)(d, request, arg);
5654e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // FIXME: some ioctls have different return values for success and failure.
5664e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (desc && res != -1)
5674e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    ioctl_common_post(ctx, desc, res, d, request, arg);
5684e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  return res;
5694e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov}
5704ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov#define INIT_IOCTL \
5714ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov  ioctl_init();    \
5724ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov  INTERCEPT_FUNCTION(ioctl);
5734e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#else
5744e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#define INIT_IOCTL
5754e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#endif
576745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
577745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
578103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
579e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(void *, getpwnam, const char *name) {
580e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
581e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
582e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
583e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *res = REAL(getpwnam)(name);
584e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (res != 0)
585e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
586e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
587e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
588e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(void *, getpwuid, u32 uid) {
589e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
590e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
591e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *res = REAL(getpwuid)(uid);
592e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (res != 0)
593e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
594e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
595e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
596103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(void *, getgrnam, const char *name) {
597103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
598103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
599103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
600103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *res = REAL(getgrnam)(name);
601103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (res != 0)
602103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
603103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
604103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
605103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(void *, getgrgid, u32 gid) {
606103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
607103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
608103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *res = REAL(getgrgid)(gid);
609103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (res != 0)
610103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
611103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
612103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
613103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS                  \
614103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwnam);                    \
615103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwuid);                    \
616103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrnam);                    \
617103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrgid);
618e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
619103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS
620e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
621e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
622e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
623103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
624e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
625e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
626e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
627e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
628e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
629e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
630e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
631e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
632e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
633e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
634e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
635e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
636e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
637e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
638e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
639e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
640e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
641e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
642e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
643e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
644e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
645e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
646e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
647103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
648103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
649103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
650103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
651103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
652103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
653103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
654103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
655103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
656103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
657103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
658103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
659103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
660103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
661103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
662103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
663103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
664103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
665103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
666103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
667103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
668103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
669103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
670103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS                \
671103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwnam_r);                  \
672103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwuid_r);                  \
673103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrnam_r);                  \
674103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrgid_r);
675e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
676103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS
677e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
678e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
679e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
680e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_CLOCK_GETTIME
681e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
682e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
683e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
684e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_getres)(clk_id, tp);
6857cdae1683c9c2fcd4473a5862c90c64be3a8c5fdEvgeniy Stepanov  if (!res && tp) {
686e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
687e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
688e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
689e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
690e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
691e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
692e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
693e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_gettime)(clk_id, tp);
694e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
695e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
696e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
697e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
698e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
699e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
700e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
701e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
702e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
703e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return REAL(clock_settime)(clk_id, tp);
704e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
705e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_CLOCK_GETTIME                         \
706e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(clock_getres);                \
707e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(clock_gettime);               \
708e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(clock_settime);
709e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
710e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_CLOCK_GETTIME
711e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
712e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
713e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
714e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETITIMER
715e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getitimer, int which, void *curr_value) {
716e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
717e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
718e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getitimer)(which, curr_value);
719e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
720e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
721e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
722e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
723e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
724e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
725e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
726e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
727e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
728e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(setitimer)(which, new_value, old_value);
729e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res && old_value) {
730e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
731e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
732e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
733e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
734e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_GETITIMER                             \
735e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(getitimer);                   \
736e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(setitimer);
737e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
738e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_GETITIMER
739e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
740e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
741a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#if SANITIZER_INTERCEPT_GLOB
742906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanovstatic void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
743a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
744a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  // +1 for NULL pointer at the end.
745906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if (pglob->gl_pathv)
746906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(
747906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
748a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
749a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    char *p = pglob->gl_pathv[i];
750a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
751a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  }
752a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
753a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
7543fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic THREADLOCAL __sanitizer_glob_t* pglob_copy;
7553fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic THREADLOCAL void* glob_ctx;
7563fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
7573fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void wrapped_gl_closedir(void *dir) {
7583fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
7593fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  pglob_copy->gl_closedir(dir);
7603fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
7613fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
7623fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void *wrapped_gl_readdir(void *dir) {
7633fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
7643fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  return pglob_copy->gl_readdir(dir);
7653fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
7663fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
7673fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void *wrapped_gl_opendir(const char *s) {
7683fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
7693fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
7703fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  return pglob_copy->gl_opendir(s);
7713fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
7723fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
7733fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic int wrapped_gl_lstat(const char *s, void *st) {
7743fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
7753fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
7763fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  return pglob_copy->gl_lstat(s, st);
7773fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
7783fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
7793fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic int wrapped_gl_stat(const char *s, void *st) {
7803fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
7813fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
7823fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  return pglob_copy->gl_stat(s, st);
7833fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
7843fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
785a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob, const char *pattern, int flags,
786a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
787906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov            __sanitizer_glob_t *pglob) {
788a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
789a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
7903fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
7913fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov                                  wrapped_gl_readdir, wrapped_gl_opendir,
7923fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov                                  wrapped_gl_lstat, wrapped_gl_stat};
7933fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  if (flags & glob_altdirfunc) {
7943fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
7953fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
7963fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
7973fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
7983fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
7993fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    pglob_copy = &glob_copy;
8003fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    glob_ctx = ctx;
8013fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  }
802a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob)(pattern, flags, errfunc, pglob);
8033fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  if (flags & glob_altdirfunc) {
8043fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
8053fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
8063fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
8073fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
8083fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
8093fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  }
8103fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  pglob_copy = 0;
8113fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  glob_ctx = 0;
812906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
813a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
814a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
815a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
816a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob64, const char *pattern, int flags,
817a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
818906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov            __sanitizer_glob_t *pglob) {
819a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
820a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
82157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
82257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov                                  wrapped_gl_readdir, wrapped_gl_opendir,
82357876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov                                  wrapped_gl_lstat, wrapped_gl_stat};
82457876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  if (flags & glob_altdirfunc) {
82557876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
82657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
82757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
82857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
82957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
83057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    pglob_copy = &glob_copy;
83157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    glob_ctx = ctx;
83257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  }
833a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
83457876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  if (flags & glob_altdirfunc) {
83557876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
83657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
83757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
83857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
83957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
84057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  }
84157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  pglob_copy = 0;
84257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  glob_ctx = 0;
843906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
844a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
845a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
846906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#define INIT_GLOB           \
847906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  INTERCEPT_FUNCTION(glob); \
848a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  INTERCEPT_FUNCTION(glob64);
849906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#else  // SANITIZER_INTERCEPT_GLOB
850a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#define INIT_GLOB
851906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#endif  // SANITIZER_INTERCEPT_GLOB
852a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
853897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#if SANITIZER_INTERCEPT_WAIT
8546a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
8556a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
8566a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// details.
8576a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
858897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
859897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
860897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait)(status);
861f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
862897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
863897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
864897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
86530e970f769ccf11e61e472c6f8b22f8e866c592fKostya SerebryanyINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
86630e970f769ccf11e61e472c6f8b22f8e866c592fKostya Serebryany  int options) {
867897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
868897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
869897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitid)(idtype, id, infop, options);
870f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && infop)
871897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
872897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
873897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
8746a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
875897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
876897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
877897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitpid)(pid, status, options);
878f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
879897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
880897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
881897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
882897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
883897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
884897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
885897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait3)(status, options, rusage);
886897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
887f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov    if (status)
888f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
889897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    if (rusage)
890897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
891897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
892897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
893897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
894897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
895897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
896897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
897897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait4)(pid, status, options, rusage);
898897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
899f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov    if (status)
900f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
901897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    if (rusage)
902897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
903897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
904897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
905897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
906897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#define INIT_WAIT                                \
907897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(wait);                      \
908897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(waitid);                    \
909897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(waitpid);                   \
910897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(wait3);                     \
911897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(wait4);
912897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#else
913897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#define INIT_WAIT
914897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#endif
915897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
9169530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#if SANITIZER_INTERCEPT_INET
9179530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
9189530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
9199530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
9209530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  uptr sz = __sanitizer_in_addr_sz(af);
9219530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
9229530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
9239530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  char *res = REAL(inet_ntop)(af, src, dst, size);
9249530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (res)
9259530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
9269530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
9279530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
9289530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
9299530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
9309530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
9319530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
9329530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  int res = REAL(inet_pton)(af, src, dst);
9339530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (res == 1) {
9349530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af);
9359530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
9369530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  }
9379530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
9389530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
9399530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#define INIT_INET                                \
9409530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  INTERCEPT_FUNCTION(inet_ntop);                 \
9419530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  INTERCEPT_FUNCTION(inet_pton);
9429530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#else
9439530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#define INIT_INET
9449530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#endif
9459530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
9469d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#if SANITIZER_INTERCEPT_INET
9479d60087654f89e3452841350d9eca97644edca9dEvgeniy StepanovINTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
9489d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  void *ctx;
9499d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
9509d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
9519d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  int res = REAL(inet_aton)(cp, dst);
9529d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  if (res != 0) {
9539d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af_inet);
9549d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
9559d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  }
9569d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  return res;
9579d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov}
9589d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton);
9599d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#else
9609d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#define INIT_INET_ATON
9619d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#endif
9629d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov
96356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
96456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy StepanovINTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
96556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  void *ctx;
96656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
96756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  int res = REAL(pthread_getschedparam)(thread, policy, param);
96856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  if (res == 0) {
96956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
97056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
97156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  }
97256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  return res;
97356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov}
97456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
97556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#else
97656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM
97756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#endif
978897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
979447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETADDRINFO
980447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy StepanovINTERCEPTOR(int, getaddrinfo, char *node, char *service,
981447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo *hints,
982447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo **out) {
983447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  void *ctx;
984447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
985447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
986447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (service)
987447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
988447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (hints)
989447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
990447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  int res = REAL(getaddrinfo)(node, service, hints, out);
9913538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov  if (res == 0 && out) {
9923538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
993447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    struct __sanitizer_addrinfo *p = *out;
994447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    while (p) {
9953538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
996447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_addr)
997512c616cacf70ca029a2bf719a482b902f3687cdEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
998447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_canonname)
999447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1000447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov                                       REAL(strlen)(p->ai_canonname) + 1);
1001447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      p = p->ai_next;
1002447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    }
1003447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  }
1004447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  return res;
1005447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
1006447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
1007447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#else
1008447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define INIT_GETADDRINFO
1009447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#endif
1010447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
10119eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETNAMEINFO
10129eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy StepanovINTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
10139eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov            unsigned hostlen, char *serv, unsigned servlen, int flags) {
10149eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  void *ctx;
10159eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
10169eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov                           serv, servlen, flags);
10179eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  // FIXME: consider adding READ_RANGE(sockaddr, salen)
10189eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  // There is padding in in_addr that may make this too noisy
10199eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  int res =
10209eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
10219eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  if (res == 0) {
10229eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov    if (host && hostlen)
10239eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
10249eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov    if (serv && servlen)
10259eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
10269eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  }
10279eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  return res;
10289eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov}
10299eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo);
10309eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#else
10319eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#define INIT_GETNAMEINFO
10329eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#endif
10339eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov
10349f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKNAME
10359f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy StepanovINTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
10369f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  void *ctx;
10379f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
10389f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
10399f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int addrlen_in = *addrlen;
10409f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int res = REAL(getsockname)(sock_fd, addr, addrlen);
10419f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  if (res == 0) {
10429f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
10439f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  }
10449f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  return res;
10459f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov}
10469f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
10479f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#else
10489f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#define INIT_GETSOCKNAME
10499f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#endif
1050447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
105133b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
10520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanovstatic void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
10530a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
10540a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (h->h_name)
10550a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
10560a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  char **p = h->h_aliases;
10570a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
10580a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
10590a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
10600a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
10610a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
10620a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
10630a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  p = h->h_addr_list;
10640a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
10650a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
10660a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
10670a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
10680a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
10690a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
10700a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
107133b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#endif
10720a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
10730a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME
10740a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
10750a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
10760a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
10770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
10780a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
10790a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
10800a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
10810a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
10820a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
10830a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            int type) {
10840a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
10850a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
10860a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
10870a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
10880a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
10890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
10900a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
10910a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
10920a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostent) {
10930a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
10940a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent);
10950a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostent)();
10960a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
10970a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
10980a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
10990a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
11000a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
11010a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
11020a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
11030a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
11040a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
11050a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
11060a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
11070a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME           \
11080a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostent);    \
11090a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyaddr); \
11100a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname); \
11110a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname2);
11120a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
11130a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME
11140a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
11150a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
11160a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
11170a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
11180a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
11190a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
11200a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
11210a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           h_errnop);
11220a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
11230a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
11240a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
11250a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
11260a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
11270a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
11280a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
11290a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
11300a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
11310a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
11320a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
11330a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
11340a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
11350a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
11360a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
11370a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
11380a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
11390a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           buflen, result, h_errnop);
11400a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
11410a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
11420a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                                  h_errnop);
11430a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
11440a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
11450a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
11460a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
11470a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
11480a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
11490a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
11500a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
11510a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
11520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
11530a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
11540a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
11550a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
11560a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            int *h_errnop) {
11570a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
11580a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
11590a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           h_errnop);
11600a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
11610a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
11620a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
11630a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
11640a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
11650a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
11660a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
11670a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
11680a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
11690a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
11700a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
11710a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
11720a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyname2_r, char *name, int af,
11730a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
11740a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
11750a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
11760a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
11770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           result, h_errnop);
11780a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res =
11790a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
11800a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
11810a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
11820a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
11830a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
11840a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
11850a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
11860a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
11870a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
11880a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
11890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
11900a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME_R           \
11910a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostent_r);    \
11920a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyaddr_r); \
11930a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname_r); \
11940a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname2_r);
11950a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
11960a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME_R
11970a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
11980a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
1199f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKOPT
1200f32be42523a199674ea665a499db131591e64e08Evgeniy StepanovINTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1201f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov            int *optlen) {
1202f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  void *ctx;
1203f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1204f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov                           optlen);
1205f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1206f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1207f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (res == 0)
1208f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1209f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  return res;
1210f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov}
1211f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
1212f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#else
1213f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#define INIT_GETSOCKOPT
1214f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#endif
1215f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov
12169d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT
12179d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
12189d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
12199d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
12209d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  unsigned addrlen0;
12219d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
12229d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
12239d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
12249d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
12259d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept)(fd, addr, addrlen);
12269d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
12279d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (fd >= 0)
12289d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
12299d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
12309d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
12319d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
12329d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
12339d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
12349d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
12359d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
12369d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT
12379d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
12389d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
12399d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT4
12409d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
12419d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
12429d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
12439d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  unsigned addrlen0;
12449d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
12459d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
12469d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
12479d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
12489d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
12499d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
12509d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (fd >= 0)
12519d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
12529d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
12539d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
12549d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
12559d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
12569d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
12579d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
12589d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
12599d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT4
12609d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
12619d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
1262c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#if SANITIZER_INTERCEPT_MODF
1263c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(double, modf, double x, double *iptr) {
1264c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
1265c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1266c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  double res = REAL(modf)(x, iptr);
1267c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
1268c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1269c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
1270c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
1271c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
1272c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(float, modff, float x, float *iptr) {
1273c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
1274c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1275c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  float res = REAL(modff)(x, iptr);
1276c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
1277c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1278c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
1279c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
1280c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
1281c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1282c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
1283c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1284c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  long double res = REAL(modfl)(x, iptr);
1285c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
1286c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1287c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
1288c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
1289c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
1290c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#define INIT_MODF            \
1291c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INTERCEPT_FUNCTION(modf);  \
1292c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INTERCEPT_FUNCTION(modff); \
1293c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INTERCEPT_FUNCTION(modfl);
1294c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#else
1295c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#define INIT_MODF
1296c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#endif
1297c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov
12989666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#if SANITIZER_INTERCEPT_RECVMSG
1299eb7c24bb2e6fd20410d34006759caf76852d0600Evgeniy Stepanovstatic void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
1300eb7c24bb2e6fd20410d34006759caf76852d0600Evgeniy Stepanov                         SSIZE_T maxlen) {
13019666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
13029666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (msg->msg_name)
13039666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name,
13049666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov                                   REAL(strlen)((char *)msg->msg_name) + 1);
13059666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (msg->msg_iov)
1306b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
1307b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
1308b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
13099666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (msg->msg_control)
13109666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
13119666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
13129666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
13139666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy StepanovINTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
13149666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov            int flags) {
13159666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  void *ctx;
13169666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
13179666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
13189666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (res >= 0) {
13199666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1320b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    if (msg) write_msghdr(ctx, msg, res);
13219666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  }
13229666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  return res;
13239666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
13249666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
13259666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#else
13269666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#define INIT_RECVMSG
13279666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#endif
13289666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
1329bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPEERNAME
1330bc33e138d82759074f8333239f96506027731e20Evgeniy StepanovINTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1331bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  void *ctx;
1332bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1333bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  unsigned addr_sz;
1334bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (addrlen) addr_sz = *addrlen;
1335bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  int res = REAL(getpeername)(sockfd, addr, addrlen);
1336bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (!res && addr && addrlen)
1337bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1338bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  return res;
1339bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov}
1340bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1341bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#else
1342bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#define INIT_GETPEERNAME
1343bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#endif
1344bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov
1345359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#if SANITIZER_INTERCEPT_SYSINFO
1346359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy StepanovINTERCEPTOR(int, sysinfo, void *info) {
1347359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  void *ctx;
1348359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
1349359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  int res = REAL(sysinfo)(info);
1350359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  if (!res && info)
1351359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
1352359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  return res;
1353359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov}
1354359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo);
1355359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#else
1356359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#define INIT_SYSINFO
1357359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#endif
1358359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov
1359b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#if SANITIZER_INTERCEPT_READDIR
1360a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy StepanovINTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
1361b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
1362b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
1363a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov  __sanitizer_dirent *res = REAL(readdir)(dirp);
1364b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (res)
1365a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1366b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
1367b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
1368b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
136952d08d8412bfa4ccfa38384d781b51e8774807a7Alexey SamsonovINTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
137052d08d8412bfa4ccfa38384d781b51e8774807a7Alexey Samsonov            __sanitizer_dirent **result) {
1371b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
1372b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
1373b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  int res = REAL(readdir_r)(dirp, entry, result);
1374b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (!res) {
13755a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
13765a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    if (*result)
13775a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
1378b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  }
1379b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
1380b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
1381b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
1382b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR           \
1383b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  INTERCEPT_FUNCTION(readdir); \
1384b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  INTERCEPT_FUNCTION(readdir_r);
1385b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#else
1386b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR
1387b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#endif
1388b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
1389b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#if SANITIZER_INTERCEPT_READDIR64
1390a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy StepanovINTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
1391b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
1392b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
1393a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
1394b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (res)
1395a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1396b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
1397b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
1398b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
139952d08d8412bfa4ccfa38384d781b51e8774807a7Alexey SamsonovINTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
140052d08d8412bfa4ccfa38384d781b51e8774807a7Alexey Samsonov            __sanitizer_dirent64 **result) {
1401b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
1402b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
1403b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  int res = REAL(readdir64_r)(dirp, entry, result);
1404b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (!res) {
14055a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
14065a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    if (*result)
14075a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
1408b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  }
1409b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
1410b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
1411b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR64           \
1412b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  INTERCEPT_FUNCTION(readdir64); \
1413b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  INTERCEPT_FUNCTION(readdir64_r);
1414b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#else
1415b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR64
1416b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#endif
1417b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
1418341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTRACE
1419341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy StepanovINTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
1420341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  void *ctx;
1421341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
1422341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
1423341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (data) {
1424341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (request == ptrace_setregs)
1425341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
1426341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setfpregs)
1427341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1428341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setfpxregs)
1429341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1430341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setsiginfo)
1431341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
1432341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setregset) {
1433341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1434341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
1435341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    }
1436341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
1437341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
1438341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  uptr res = REAL(ptrace)(request, pid, addr, data);
1439341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
1440341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (!res && data) {
1441341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    // Note that PEEK* requests assing different meaning to the return value.
1442341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    // This function does not handle them (nor does it need to).
1443341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (request == ptrace_getregs)
1444341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
1445341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getfpregs)
1446341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1447341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getfpxregs)
1448341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1449341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getsiginfo)
1450341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
1451341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getregset) {
1452341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1453341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
1454341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    }
1455341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
1456341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  return res;
1457341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov}
1458341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
1459341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define INIT_PTRACE           \
1460341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  INTERCEPT_FUNCTION(ptrace);
1461341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#else
1462341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define INIT_PTRACE
1463341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#endif
1464341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
14653cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#if SANITIZER_INTERCEPT_SETLOCALE
14663cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy StepanovINTERCEPTOR(char *, setlocale, int category, char *locale) {
14673cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  void *ctx;
14683cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
14693cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  if (locale)
14703cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
1471801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(setlocale)(category, locale);
14723cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  if (res)
14733cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
14743cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  return res;
14753cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov}
14763cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov
14773cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#define INIT_SETLOCALE           \
14783cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  INTERCEPT_FUNCTION(setlocale);
14793cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#else
14803cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#define INIT_SETLOCALE
14813cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#endif
14823cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov
1483801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETCWD
1484801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
1485801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  void *ctx;
1486801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
1487801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(getcwd)(buf, size);
1488801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  if (res)
1489801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1490801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
1491801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
1492801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GETCWD           \
1493801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INTERCEPT_FUNCTION(getcwd);
1494801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#else
1495801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GETCWD
1496801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#endif
1497801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
1498801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
1499801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(char *, get_current_dir_name) {
1500801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  void *ctx;
1501801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name);
1502801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(get_current_dir_name)();
1503801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  if (res)
1504801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1505801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
1506801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
1507801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
1508801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GET_CURRENT_DIR_NAME           \
1509801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INTERCEPT_FUNCTION(get_current_dir_name);
1510801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#else
1511801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GET_CURRENT_DIR_NAME
1512801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#endif
1513b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
1514ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_STRTOIMAX
1515ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
1516ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1517ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
1518ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
1519ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1520ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1521ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1522ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1523ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
1524ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1525ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
1526ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
1527ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1528ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1529ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1530ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1531ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_STRTOIMAX           \
1532ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(strtoimax); \
1533ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(strtoumax);
1534ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
1535ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_STRTOIMAX
1536ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
1537ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1538ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_MBSTOWCS
1539ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
1540ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1541ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
1542ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(mbstowcs)(dest, src, len);
1543e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (res != (SIZE_T)-1 && dest) {
1544e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + (res < len);
1545e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1546e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
1547ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1548ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1549ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1550ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
1551ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            void *ps) {
1552ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1553ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
1554e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
15555a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
1556e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (res != (SIZE_T)-1 && dest) {
1557e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    // Terminating '\0' is not printed iff *src is cleared.
1558e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + !(*src);
1559e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1560e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
1561ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1562ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1563ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1564ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSTOWCS           \
1565ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(mbstowcs); \
1566ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(mbsrtowcs);
1567ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
1568ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSTOWCS
1569ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
1570ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1571ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_MBSNRTOWCS
1572ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
1573ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            SIZE_T len, void *ps) {
1574ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1575ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
1576e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (nms) {
1577e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1578ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1579ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  }
1580ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
1581e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (res != (SIZE_T)-1 && dest && nms) {
1582e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    // Terminating '\0' is not printed iff *src is cleared.
1583e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + !(*src);
1584e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1585e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
1586ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1587ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1588ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1589ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs);
1590ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
1591ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSNRTOWCS
1592ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
1593ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1594ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_WCSTOMBS
1595ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
1596ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1597ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
1598ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(wcstombs)(dest, src, len);
1599e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (res != (SIZE_T)-1 && dest) {
1600e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + (res < len);
1601e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1602e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
1603ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1604ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1605ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1606ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
1607ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            void *ps) {
1608ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1609ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
1610e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
16115a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
1612e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (res != (SIZE_T)-1 && dest) {
1613e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    // Terminating '\0' is not printed iff *src is cleared.
1614e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + !(*src);
1615e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1616e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
1617ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1618ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1619ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1620ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSTOMBS           \
1621ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(wcstombs); \
1622ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(wcsrtombs);
1623ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
1624ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSTOMBS
1625ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
1626ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1627ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_WCSNRTOMBS
1628ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
1629ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            SIZE_T len, void *ps) {
1630ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
1631ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
1632e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (nms) {
1633ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1634e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1635ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  }
1636ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
1637e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  if (res != (SIZE_T)-1 && dest && nms) {
1638e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    // Terminating '\0' is not printed iff *src is cleared.
1639e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + !(*src);
1640e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1641e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
1642ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
1643ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
1644ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1645ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs);
1646ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
1647ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSNRTOMBS
1648ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
1649ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1650ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
1651ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#if SANITIZER_INTERCEPT_TCGETATTR
1652ea72768894e32f367607c2142a7dfab603310da0Evgeniy StepanovINTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
1653ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  void *ctx;
1654ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
1655ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  int res = REAL(tcgetattr)(fd, termios_p);
1656ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  if (!res && termios_p)
1657ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
1658ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  return res;
1659ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov}
1660ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
1661ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr);
1662ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#else
1663ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#define INIT_TCGETATTR
1664ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#endif
1665ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
166612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
166712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#if SANITIZER_INTERCEPT_REALPATH
166812eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovINTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
166912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  void *ctx;
167012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
167112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
167212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
167312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
167412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // version of a versioned symbol. For realpath(), this gives us something
167512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // (called __old_realpath) that does not handle NULL in the second argument.
167612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // Handle it as part of the interceptor.
167712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *allocated_path = 0;
167812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (!resolved_path)
167912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
168012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
168112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *res = REAL(realpath)(path, resolved_path);
168212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (allocated_path && !res)
168312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov    WRAP(free)(allocated_path);
168412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
168512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  return res;
168612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov}
168712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_REALPATH INTERCEPT_FUNCTION(realpath);
168812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#else
168912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_REALPATH
169012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#endif
169112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
169212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
169312eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovINTERCEPTOR(char *, canonicalize_file_name, const char *path) {
169412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  void *ctx;
169512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
169612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
169712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *res = REAL(canonicalize_file_name)(path);
169812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
169912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  return res;
170012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov}
170112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name);
170212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#else
170312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_CANONICALIZE_FILE_NAME
170412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#endif
170512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
170656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define SANITIZER_COMMON_INTERCEPTORS_INIT \
170756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_STRCASECMP;                         \
170856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_STRNCASECMP;                        \
170956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_READ;                               \
171056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PREAD;                              \
171156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PREAD64;                            \
1712b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_READV;                              \
1713b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_PREADV;                             \
1714b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_PREADV64;                           \
171556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_WRITE;                              \
171656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PWRITE;                             \
171756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PWRITE64;                           \
1718b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_WRITEV;                             \
1719b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_PWRITEV;                            \
1720b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_PWRITEV64;                          \
1721b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  INIT_PRCTL;                              \
172256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_LOCALTIME_AND_FRIENDS;              \
172356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_SCANF;                              \
172456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_FREXP;                              \
172556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_FREXPF_FREXPL;                      \
172656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GETPWNAM_AND_FRIENDS;               \
172756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GETPWNAM_R_AND_FRIENDS;             \
172856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_CLOCK_GETTIME;                      \
172956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GETITIMER;                          \
173056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_TIME;                               \
173156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GLOB;                               \
173256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_WAIT;                               \
173356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_INET;                               \
1734447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  INIT_PTHREAD_GETSCHEDPARAM;              \
17359f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  INIT_GETADDRINFO;                        \
17369eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  INIT_GETNAMEINFO;                        \
17370a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INIT_GETSOCKNAME;                        \
17380a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INIT_GETHOSTBYNAME;                      \
1739f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  INIT_GETHOSTBYNAME_R;                    \
17409d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  INIT_GETSOCKOPT;                         \
17419d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  INIT_ACCEPT;                             \
1742c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INIT_ACCEPT4;                            \
17439666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  INIT_MODF;                               \
1744bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  INIT_RECVMSG;                            \
1745745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov  INIT_GETPEERNAME;                        \
17469d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  INIT_IOCTL;                              \
1747359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  INIT_INET_ATON;                          \
1748b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  INIT_SYSINFO;                            \
1749b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  INIT_READDIR;                            \
1750341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  INIT_READDIR64;                          \
17513cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  INIT_PTRACE;                             \
1752801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INIT_SETLOCALE;                          \
1753801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INIT_GETCWD;                             \
1754ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INIT_GET_CURRENT_DIR_NAME;               \
1755ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INIT_STRTOIMAX;                          \
1756ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INIT_MBSTOWCS;                           \
1757ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INIT_MBSNRTOWCS;                         \
1758ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INIT_WCSTOMBS;                           \
1759ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  INIT_WCSNRTOMBS;                         \
176012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  INIT_TCGETATTR;                          \
176112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  INIT_REALPATH;                           \
176212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  INIT_CANONICALIZE_FILE_NAME;
1763