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
165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines//   COMMON_INTERCEPTOR_ENTER_NOIGNORE
178530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_READ_RANGE
188530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_WRITE_RANGE
190586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
20c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_ACQUIRE
21c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_RELEASE
2267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov//   COMMON_INTERCEPTOR_FD_ACCESS
23c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany//   COMMON_INTERCEPTOR_SET_THREAD_NAME
2414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov//   COMMON_INTERCEPTOR_ON_EXIT
255e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov//   COMMON_INTERCEPTOR_MUTEX_LOCK
265e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov//   COMMON_INTERCEPTOR_MUTEX_UNLOCK
2711f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov//   COMMON_INTERCEPTOR_MUTEX_REPAIR
285cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//   COMMON_INTERCEPTOR_HANDLE_RECVMSG
308530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//===----------------------------------------------------------------------===//
316afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany#include "interception/interception.h"
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_addrhashmap.h"
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_placement_new.h"
3474737d595c4e3638b980bd88b0492247ae4318faAlexey Samsonov#include "sanitizer_platform_interceptors.h"
352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_tls_get_addr.h"
36b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany
37996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include <stdarg.h>
38996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_WINDOWS && !defined(va_copy)
40348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#define va_copy(dst, src) ((dst) = (src))
41348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#endif // _WIN32
42348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov
430586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
490586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov#endif
500586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov
5167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov#ifndef COMMON_INTERCEPTOR_FD_ACCESS
525cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
535e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#endif
545e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
555e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
565cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
575e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#endif
585e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
595e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
605cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
6167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov#endif
6267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov
6311f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
6411f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
6511f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov#endif
6611f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov
672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_FILE_OPEN
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_FILE_CLOSE
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) {}
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct FileMetadata {
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // For open_memstream().
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char **addr;
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T *size;
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct CommonInterceptorMetadata {
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  enum {
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CIMT_INVALID = 0,
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CIMT_FILE
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } type;
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  union {
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FileMetadata file;
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  };
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic MetadataHashMap *interceptor_metadata_map;
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SI_NOT_WINDOWS
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          const FileMetadata &file) {
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK(h.created());
1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  h->type = CommonInterceptorMetadata::CIMT_FILE;
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  h->file = file;
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static const FileMetadata *GetInterceptorMetadata(
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __sanitizer_FILE *addr) {
1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            /* remove */ false,
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            /* create */ false);
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h.exists()) {
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CHECK(!h.created());
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return &h->file;
1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } else {
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return 0;
1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static void DeleteInterceptorMetadata(void *addr) {
1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK(h.exists());
1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SI_NOT_WINDOWS
1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TEXTDOMAIN
1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(char*, textdomain, const char *domainname) {
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char* domain = REAL(textdomain)(domainname);
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (domain) {
1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return domain;
1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TEXTDOMAIN
1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
15667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#if SANITIZER_INTERCEPT_STRCMP
15767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovstatic inline int CharCmpX(unsigned char c1, unsigned char c2) {
15867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
15967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
16067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
16167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey SamsonovINTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
16267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  void *ctx;
16367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
16467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  unsigned char c1, c2;
16567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  uptr i;
166a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  for (i = 0;; i++) {
16767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c1 = (unsigned char)s1[i];
16867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c2 = (unsigned char)s2[i];
16967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    if (c1 != c2 || c1 == '\0') break;
17067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  }
17167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
17267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
17367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  return CharCmpX(c1, c2);
17467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
17567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
17667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey SamsonovINTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
17767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  void *ctx;
17867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
17967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  unsigned char c1 = 0, c2 = 0;
18067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  uptr i;
18167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  for (i = 0; i < size; i++) {
18267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c1 = (unsigned char)s1[i];
18367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c2 = (unsigned char)s2[i];
18467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    if (c1 != c2 || c1 == '\0') break;
18567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  }
18667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
18767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
18867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  return CharCmpX(c1, c2);
18967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
19067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
191a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
192a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
19367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#else
19467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#define INIT_STRCMP
19567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#define INIT_STRNCMP
19667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#endif
19767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
198be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#if SANITIZER_INTERCEPT_STRCASECMP
199be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
200be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c1_low = ToLower(c1);
201be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c2_low = ToLower(c2);
202be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return c1_low - c2_low;
203be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
204be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
205be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
206be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
207be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
208be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
209be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
210a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  for (i = 0;; i++) {
211be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
212be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
213a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
214be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
215be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
216be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
217be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
218be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
219be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
220be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
221be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
222be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
223be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
224be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
225be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  for (i = 0; i < n; i++) {
226be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
227be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
228a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
229be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
230be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
231be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
232be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
233be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
234be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
235a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
236a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
237be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#else
238be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRCASECMP
239be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRNCASECMP
240be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#endif
241be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_MEMCHR
2432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
2462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(memchr)(s, c, n);
2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr len = res ? (char*)res - (char*)s + 1 : n;
2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMCHR
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_MEMRCHR
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(memrchr)(s, c, n);
2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMRCHR
2682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2707cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#if SANITIZER_INTERCEPT_FREXP
2717cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(double, frexp, double x, int *exp) {
2727cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
2737cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
2745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // Assuming frexp() always writes to |exp|.
2757cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
2765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  double res = REAL(frexp)(x, exp);
2777cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
2787cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
2797cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
280a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
281ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#else
282ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXP
283a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_FREXP
284ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov
285ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#if SANITIZER_INTERCEPT_FREXPF_FREXPL
2867cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(float, frexpf, float x, int *exp) {
2877cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
2887cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
2895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
2905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
2915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2927cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  float res = REAL(frexpf)(x, exp);
2937cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
2947cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
2957cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
2967cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
2977cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(long double, frexpl, long double x, int *exp) {
2987cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
2997cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
3005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
3015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
3025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3037cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  long double res = REAL(frexpl)(x, exp);
3047cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
3057cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
3067cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
3077cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
308a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_FREXPF_FREXPL           \
309a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(frexpf); \
310a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(frexpl)
3117cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#else
312ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXPF_FREXPL
313a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
3147cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
315b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SI_NOT_WINDOWS
316b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
317b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        SIZE_T iovlen, SIZE_T maxlen) {
318b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
319b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
320b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
321b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    maxlen -= sz;
322b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  }
323b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
324b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
325b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
326b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                       SIZE_T iovlen, SIZE_T maxlen) {
327b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
328b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
329b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
330b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
331b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    maxlen -= sz;
332b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  }
333b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
334b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
335b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
3368ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#if SANITIZER_INTERCEPT_READ
3376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
33844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
339996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
34067f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
3425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
3435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3446afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(read)(fd, ptr, count);
345a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
346a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3478530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
3488530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
349a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
350c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
35144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ
3528ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#endif
3538530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
354c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#if SANITIZER_INTERCEPT_PREAD
3556afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
35644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
357996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
35867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
3605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
3615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3626afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
363a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
364a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3658530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
3668530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
367a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
368c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
36944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD
370c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#endif
3718530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
372b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany#if SANITIZER_INTERCEPT_PREAD64
3736afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
37444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
375996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
37667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
3785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
3795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3806afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
381a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
382a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3838530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
3848530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
385a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
386c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
38744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64
3881f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko#endif
3898530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
390b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_READV
391b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
392b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        int iovcnt) {
393b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
394b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
39567f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
396b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
397b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
398b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
399b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
400b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
401a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
402b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
403b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_READV
404b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
405b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
406b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PREADV
407b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
408b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF_T offset) {
409b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
410b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
41167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
412b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
413b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
414b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
415b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
416b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
417a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
418b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
419b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV
420b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
421b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
422b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PREADV64
423b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
424b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF64_T offset) {
425b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
426b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
42767f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
428b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
429b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
430b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
431b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
432b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
433a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
434b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
435b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV64
436b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
437b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
438c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_WRITE
439c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya SerebryanyINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
44044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
441996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
44267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
443a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
444c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  SSIZE_T res = REAL(write)(fd, ptr, count);
445b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  // FIXME: this check should be _before_ the call to REAL(write), not after
446a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
447c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
448c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
449a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
450153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
45144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE
452153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
453153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
454c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE
455f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
45644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
457f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
45867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
459a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
460f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
461a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
462c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
463c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
464a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
465153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
46644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE
467153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
468153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
469c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE64
470f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
471f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov            OFF64_T offset) {
47244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
473f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
47467f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
475a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
476f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
477a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
478c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
479c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
480a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
481153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
48244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64
483153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
484153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
485b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_WRITEV
486b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
487b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        int iovcnt) {
488b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
489b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
49067f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
491b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
492b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
493b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
494b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
495b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
496a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
497b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
498b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_WRITEV
499b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
500b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
501b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PWRITEV
502b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
503b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF_T offset) {
504b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
505b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
50667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
507b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
508b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
509b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
510b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
511b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
512a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
513b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
514b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV
515b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
516b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
517b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PWRITEV64
518b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
519b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF64_T offset) {
520b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
521b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
52267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
523b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
524b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
525b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
526b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
527b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
528a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
529b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
530b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV64
531b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
532b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
533c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PRCTL
534a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy StepanovINTERCEPTOR(int, prctl, int option, unsigned long arg2,
535a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov            unsigned long arg3,                        // NOLINT
536a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov            unsigned long arg4, unsigned long arg5) {  // NOLINT
53744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
538996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
539c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  static const int PR_SET_NAME = 15;
540c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
541c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (option == PR_SET_NAME) {
542c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    char buff[16];
54344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov    internal_strncpy(buff, (char *)arg2, 15);
544c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    buff[15] = 0;
545996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
546c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  }
547c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
548c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
549a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
550c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
55144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL
552a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_PRCTL
553fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
554fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#if SANITIZER_INTERCEPT_TIME
555fef660506e9e5703fedfee01d614abd4b741c738Evgeniy StepanovINTERCEPTOR(unsigned long, time, unsigned long *t) {
556fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  void *ctx;
557fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
5585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  unsigned long local_t;
5595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  unsigned long res = REAL(time)(&local_t);
56015832c2afc4f04fa558160441d1b01fb3f0ec08bAlexander Potapenko  if (t && res != (unsigned long)-1) {
561fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
5625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    *t = local_t;
563fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  }
564fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  return res;
565fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov}
566a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
567fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#else
568fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#define INIT_TIME
569a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_TIME
570fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
5719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
572cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanovstatic void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
573cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
5740586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov  if (tm->tm_zone) {
5750586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
5760586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov    // can point to shared memory and tsan would report a data race.
5772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
5780586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov                                        REAL(strlen(tm->tm_zone)) + 1);
5790586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov  }
580cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov}
581cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
5829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
5839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
584cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(localtime)(timep);
5859358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
5869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
587cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
5889358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
5899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
5909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
591cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
5929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
5939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
594cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
5959358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
5969358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
597cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
5989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
5999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
601cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
6029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
6039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
604cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(gmtime)(timep);
6059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
6069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
607cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
6089358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
6099358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
611cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
6129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
6139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
614cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
6159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
6169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
617cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
6189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
6199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
6219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime, unsigned long *timep) {
6229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
6239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
6245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
6255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
6265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
6279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime)(timep);
6289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
6299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
6309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
6319358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
6329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
6349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
6359358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
6369358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
6375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
6385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
6395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
6409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime_r)(timep, result);
6419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
6429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
6439358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
6449358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
6459358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6469358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
647cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
6489358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
6499358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
6505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
6515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
6525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
6539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime)(tm);
6549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
655cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
6569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
6579358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
6589358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6599358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
660cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
6619358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
6629358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
6635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
6645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
6655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
6669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime_r)(tm, result);
6679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
668cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
6699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
6709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
6719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
6729358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
6732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
6742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
6752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
6762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
6772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
6782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
6792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
6802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
6812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
6822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
6832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  long res = REAL(mktime)(tm);
6842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != -1) unpoison_tm(ctx, tm);
6852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
6862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
687a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS        \
688a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(localtime);   \
689a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(localtime_r); \
690a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gmtime);      \
691a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
692a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ctime);       \
693a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ctime_r);     \
694a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(asctime);     \
6952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(asctime_r);   \
6962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(mktime);
6979358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#else
6989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS
699a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
7009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
701e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#if SANITIZER_INTERCEPT_STRPTIME
702e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy StepanovINTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
703e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  void *ctx;
704e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
705e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  if (format)
706e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
7075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
7085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
7095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
710e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  char *res = REAL(strptime)(s, format, tm);
711e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  if (res) {
712e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, res - s);
713e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    // Do not call unpoison_tm here, because strptime does not, in fact,
714e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    // initialize the entire struct tm. For example, tm_zone pointer is left
715e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    // uninitialized.
716a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (tm) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
717e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  }
718e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  return res;
719e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov}
720a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
721e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#else
722e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#define INIT_STRPTIME
723e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#endif
724e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov
7252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
7262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common_interceptors_format.inc"
727996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
7292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
7302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void *ctx;                                                                 \
7312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    va_list ap;                                                                \
7322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    va_start(ap, format);                                                      \
7332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
7342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
7352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    va_end(ap);                                                                \
7362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
7372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
7382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
7392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
7402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
7412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_SCANF
742996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
743c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
7444ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
7454ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
7464ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
7474ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list aq;                                                                \
7484ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_copy(aq, ap);                                                           \
7494ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = REAL(vname)(__VA_ARGS__);                                        \
7504ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    if (res > 0)                                                               \
751c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
7524ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(aq);                                                                \
7534ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
7544ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
755996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7564ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vscanf, const char *format, va_list ap)
757c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
758996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7594ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
760c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
761996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7624ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
763c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
764996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7659eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
7664ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
767c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
768996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
7694ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
7704ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov            va_list ap)
771c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
7724ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7734ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
774c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
7759eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
7764ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7774ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, scanf, const char *format, ...)
7782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
7794ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7804ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
7812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
7824ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7834ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
7842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
7854ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7869eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
7874ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
7882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
7894ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7904ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
7912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
7924ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
7934ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
7942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
7959eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif
796996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
797ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#endif
798996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
799ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#if SANITIZER_INTERCEPT_SCANF
800a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCANF                    \
801a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(scanf);   \
802a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sscanf);  \
803a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fscanf);  \
804a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(vscanf);  \
805a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(vsscanf); \
806a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(vfscanf);
807996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#else
808996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define INIT_SCANF
809996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#endif
810996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
811ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#if SANITIZER_INTERCEPT_ISOC99_SCANF
812a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ISOC99_SCANF                      \
813a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
814a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
815a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
816a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
817a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
818a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
819ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#else
820ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#define INIT_ISOC99_SCANF
821ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#endif
822745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
8232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_PRINTF
8242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
8262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;                                                                   \
8272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
8282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_list aq;                                                                  \
8292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_copy(aq, ap);
8302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VPRINTF_INTERCEPTOR_RETURN()                                           \
8322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_end(aq);
8332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
8352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
8362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
8372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf)                                          \
8382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
8392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(__VA_ARGS__);                                        \
8402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
8412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
8422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
8432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and
8455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// corrupt its metadata. See
8465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
8472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
8482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
8492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
8502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf) {                                        \
8512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
8522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
8532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(str, __VA_ARGS__);                                   \
8542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res >= 0) {                                                            \
8552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
8562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
8572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
8582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
8592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
8602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and
8625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// corrupt its metadata. See
8635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
8642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
8652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
8662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
8672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf) {                                        \
8682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
8692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
8702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(str, size, __VA_ARGS__);                             \
8712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res >= 0) {                                                            \
8722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
8732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
8742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
8752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
8762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
8772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and
8795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// corrupt its metadata. See
8805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
8812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
8822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
8832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
8842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
8852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf) {                                        \
8862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
8872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
8882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(strp, __VA_ARGS__);                                  \
8892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res >= 0) {                                                            \
8902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
8912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
8922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
8932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
8942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
8952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vprintf, const char *format, va_list ap)
8972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
8982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
8992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
9002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
9012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
9022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
9042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
9052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
9062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
9082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
9092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
9112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
9122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ISOC99_PRINTF
9142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
9152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
9162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
9182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            const char *format, va_list ap)
9192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
9202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
9222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
9232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
9242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
9262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
9272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
9282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                          ap)
9292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
9312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, printf, const char *format, ...)
9332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
9342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
9362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
9372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
9392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
9402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
9422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
9432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
9452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
9462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ISOC99_PRINTF
9482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_printf, const char *format, ...)
9492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
9502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
9522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            ...)
9532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
9542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
9562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
9572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
9592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            const char *format, ...)
9602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
9612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                        format)
9622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
9642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_PRINTF
9662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_PRINTF
9682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_PRINTF                     \
9692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(printf);    \
9702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(sprintf);   \
9712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(snprintf);  \
9722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(asprintf);  \
9732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fprintf);   \
9742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vprintf);   \
9752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vsprintf);  \
9762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vsnprintf); \
9772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vasprintf); \
9782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vfprintf);
9792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
9802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_PRINTF
9812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
9822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ISOC99_PRINTF
9842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ISOC99_PRINTF                       \
9852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
9862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
9872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
9882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
9892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
9902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
9912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
9922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
9932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
9942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ISOC99_PRINTF
9952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
9962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
9974e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#if SANITIZER_INTERCEPT_IOCTL
998745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov#include "sanitizer_common_interceptors_ioctl.inc"
9994e95e949c335dd92b193ff270754e31d144e53bfEvgeniy StepanovINTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
10004e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  void *ctx;
10014e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
10024e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
10034e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  CHECK(ioctl_initialized);
10044e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
10054e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // Note: TSan does not use common flags, and they are zero-initialized.
10064e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // This effectively disables ioctl handling in TSan.
1007a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
10084e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
10094e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  const ioctl_desc *desc = ioctl_lookup(request);
10102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ioctl_desc decoded_desc;
10112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!desc) {
10122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
10132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (!ioctl_decode(request, &decoded_desc))
10142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
10152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    else
10162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      desc = &decoded_desc;
10172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
10184e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
1019a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
10204e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  int res = REAL(ioctl)(d, request, arg);
10214e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // FIXME: some ioctls have different return values for success and failure.
1022a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
10234e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  return res;
10244e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov}
10254ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov#define INIT_IOCTL \
10264ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov  ioctl_init();    \
1027a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ioctl);
10284e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#else
10294e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#define INIT_IOCTL
10304e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#endif
1031745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
10322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
10332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT
10342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
10352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwd) {
10362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
10372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_name)
10382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
10392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_name) + 1);
10402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_passwd)
10412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
10422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_passwd) + 1);
10432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !SANITIZER_ANDROID
10442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_gecos)
10452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
10462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_gecos) + 1);
10472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
10482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_MAC
10492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_class)
10502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
10512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_class) + 1);
10522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
10532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_dir)
10542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
10552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_dir) + 1);
10562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_shell)
10572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
10582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_shell) + 1);
10592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
10602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
10612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
10622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void unpoison_group(void *ctx, __sanitizer_group *grp) {
10632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (grp) {
10642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
10652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (grp->gr_name)
10662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
10672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(grp->gr_name) + 1);
10682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (grp->gr_passwd)
10692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
10702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(grp->gr_passwd) + 1);
10712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    char **p = grp->gr_mem;
10722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (; *p; ++p) {
10732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
10742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
10752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
10762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        (p - grp->gr_mem + 1) * sizeof(*p));
10772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
10782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
10792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
10802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT
10812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1082103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
10832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1084e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1085e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1086e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
10872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(getpwnam)(name);
10882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_passwd(ctx, res);
1089e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1090e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
10912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1092e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1093e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
10942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(getpwuid)(uid);
10952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_passwd(ctx, res);
1096e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1097e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
10982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1099103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1100103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1101103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
11022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(getgrnam)(name);
11032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_group(ctx, res);
1104103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1105103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
11062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1107103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1108103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
11092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(getgrgid)(gid);
11102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_group(ctx, res);
1111103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1112103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
1113a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS      \
1114a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwnam); \
1115a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwuid); \
1116a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrnam); \
1117a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrgid);
1118e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1119103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS
1120e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1121e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1122103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
11232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
11242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1125e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1126e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1127e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
11285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
11295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
11305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1131e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1132e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
11332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_passwd(ctx, *result);
1134e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1135e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
11362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1137e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1138e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
11392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
11402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_passwd **result) {
1141e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1142e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
11435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
11445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
11455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1146e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1147e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
11482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_passwd(ctx, *result);
1149e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1150e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
11512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1152e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1153e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
11542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
11552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            char *buf, SIZE_T buflen, __sanitizer_group **result) {
1156103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1157103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1158103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
11595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
11605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
11615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1162103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1163103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
11642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_group(ctx, *result);
1165103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1166103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
11672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1168103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1169103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
11702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
11712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_group **result) {
1172103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1173103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
11745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
11755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
11765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1177103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1178103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
11792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_group(ctx, *result);
1180103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1181103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
11822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1183103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1184103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
1185a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS      \
1186a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1187a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
1188a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
1189a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrgid_r);
1190e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1191103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS
1192e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1193e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
11942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETPWENT
11952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
11962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
11972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
11982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(getpwent)(dummy);
11992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_passwd(ctx, res);
12002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
12032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
12052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(getgrent)(dummy);
12062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_group(ctx, res);;
12072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT                  \
12102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getpwent); \
12112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getgrent);
12122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
12132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT
12142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
12152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FGETPWENT
12172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
12182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
12202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(fgetpwent)(fp);
12212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_passwd(ctx, res);
12222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
12252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
12272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(fgetgrent)(fp);
12282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != 0) unpoison_group(ctx, res);
12292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FGETPWENT                  \
12322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetpwent); \
12332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetgrent);
12342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
12352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FGETPWENT
12362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
12372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETPWENT_R
12392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
12402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
12412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
12435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
12445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
12455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
12462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
12472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
12482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
12492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
12502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
12522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
12552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
12562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
12585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
12595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
12605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
12612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
12622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
12632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
12642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
12652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
12672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
12702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_group **pwbufp) {
12712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
12735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
12745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
12755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
12762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
12772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
12782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
12792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
12802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
12822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
12852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_group **pwbufp) {
12862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
12872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
12885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
12895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
12905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
12912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
12922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
12932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
12942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
12952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
12972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
12982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
12992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT_R                   \
13002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
13012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
13022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getgrent_r);  \
13032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
13042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
13052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT_R
13062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
13072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_SETPWENT
13092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The only thing these interceptors do is disable any nested interceptors.
13102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// These functions may open nss modules and call uninstrumented functions from
13112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// them, and we don't want things like strlen() to trigger.
13122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, setpwent, int dummy) {
13132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
13142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
13152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(setpwent)(dummy);
13162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, endpwent, int dummy) {
13182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
13192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
13202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(endpwent)(dummy);
13212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, setgrent, int dummy) {
13232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
13242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
13252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(setgrent)(dummy);
13262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, endgrent, int dummy) {
13282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
13292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
13302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(endgrent)(dummy);
13312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
13322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_SETPWENT                  \
13332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(setpwent); \
13342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(endpwent); \
13352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(setgrent); \
13362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(endgrent);
13372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
13382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_SETPWENT
13392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
13402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1341e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_CLOCK_GETTIME
1342e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
1343e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1344e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
13455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
13465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
13475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1348e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_getres)(clk_id, tp);
13497cdae1683c9c2fcd4473a5862c90c64be3a8c5fdEvgeniy Stepanov  if (!res && tp) {
1350e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1351e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1352e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1353e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1354e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
1355e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1356e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
13575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
13585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
13595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1360e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_gettime)(clk_id, tp);
1361e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
1362e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1363e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1364e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1365e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1366e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
1367e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1368e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
1369e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
1370e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return REAL(clock_settime)(clk_id, tp);
1371e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1372a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_CLOCK_GETTIME                  \
1373a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(clock_getres);  \
1374a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(clock_gettime); \
1375a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(clock_settime);
1376e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1377e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_CLOCK_GETTIME
1378e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1379e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1380e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETITIMER
1381e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getitimer, int which, void *curr_value) {
1382e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1383e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
13845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
13855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
13865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1387e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getitimer)(which, curr_value);
138839d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov  if (!res && curr_value) {
1389e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
1390e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1391e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1392e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1393e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
1394e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1395e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
139639d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov  if (new_value)
139739d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
13985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
13995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
14005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1401e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(setitimer)(which, new_value, old_value);
1402e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res && old_value) {
1403e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
1404e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1405e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1406e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1407a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETITIMER                  \
1408a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getitimer); \
1409a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(setitimer);
1410e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1411e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_GETITIMER
1412e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1413e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1414a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#if SANITIZER_INTERCEPT_GLOB
1415906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanovstatic void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
1416a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
1417a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  // +1 for NULL pointer at the end.
1418906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if (pglob->gl_pathv)
1419906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(
1420906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
1421a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
1422a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    char *p = pglob->gl_pathv[i];
1423a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
1424a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  }
1425a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
1426a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1427a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanovstatic THREADLOCAL __sanitizer_glob_t *pglob_copy;
14283fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14293fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void wrapped_gl_closedir(void *dir) {
14302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
14312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  IndirectExternCall(pglob_copy->gl_closedir)(dir);
14323fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
14333fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14343fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void *wrapped_gl_readdir(void *dir) {
14352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
14362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(pglob_copy->gl_readdir)(dir);
14373fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
14383fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14393fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void *wrapped_gl_opendir(const char *s) {
14402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
14412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
14422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(pglob_copy->gl_opendir)(s);
14433fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
14443fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14453fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic int wrapped_gl_lstat(const char *s, void *st) {
14462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
14472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
14482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(pglob_copy->gl_lstat)(s, st);
14493fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
14503fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
14513fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic int wrapped_gl_stat(const char *s, void *st) {
14522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
14532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
14542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(pglob_copy->gl_stat)(s, st);
14553fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
14563fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
1457a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob, const char *pattern, int flags,
1458a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
1459906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov            __sanitizer_glob_t *pglob) {
1460a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
1461a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
1462a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  __sanitizer_glob_t glob_copy = {
1463a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      0,                  0,                   0,
1464a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1465a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
14663fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  if (flags & glob_altdirfunc) {
14673fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
14683fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
14693fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
14703fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
14713fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
14723fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    pglob_copy = &glob_copy;
14733fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  }
1474a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob)(pattern, flags, errfunc, pglob);
14753fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  if (flags & glob_altdirfunc) {
14763fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
14773fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
14783fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
14793fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
14803fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
14813fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  }
14823fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  pglob_copy = 0;
1483906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1484a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
1485a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
1486a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1487a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob64, const char *pattern, int flags,
1488a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
1489906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov            __sanitizer_glob_t *pglob) {
1490a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
1491a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
1492a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  __sanitizer_glob_t glob_copy = {
1493a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      0,                  0,                   0,
1494a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1495a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
149657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  if (flags & glob_altdirfunc) {
149757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
149857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
149957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
150057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
150157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
150257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    pglob_copy = &glob_copy;
150357876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  }
1504a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
150557876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  if (flags & glob_altdirfunc) {
150657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
150757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
150857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
150957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
151057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
151157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  }
151257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  pglob_copy = 0;
1513906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1514a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
1515a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
1516a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GLOB                  \
1517a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(glob); \
1518a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(glob64);
1519906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#else  // SANITIZER_INTERCEPT_GLOB
1520a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#define INIT_GLOB
1521906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#endif  // SANITIZER_INTERCEPT_GLOB
1522a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1523897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#if SANITIZER_INTERCEPT_WAIT
15246a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
15256a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
15266a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// details.
15276a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
1528897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1529897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
15305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
15325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1533897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait)(status);
1534f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
1535897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1536897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1537897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
153830e970f769ccf11e61e472c6f8b22f8e866c592fKostya SerebryanyINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
1539a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov                        int options) {
1540897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1541897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
15425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
15445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1545897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitid)(idtype, id, infop, options);
1546f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && infop)
1547897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
1548897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1549897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
15506a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
1551897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1552897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
15535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
15555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1556897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitpid)(pid, status, options);
1557f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
1558897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1559897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1560897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
1561897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
1562897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1563897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
15645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
15665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1567897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait3)(status, options, rusage);
1568897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
1569a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1570a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1571897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
1572897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1573897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
15742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_ANDROID
15752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
15762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
15772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
15785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
15805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
15812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__wait4)(pid, status, options, rusage);
15822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != -1) {
15832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
15842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
15852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
15862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
15872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
15882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
15892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
1590897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
1591897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1592897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
15935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
15955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1596897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait4)(pid, status, options, rusage);
1597897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
1598a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1599a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1600897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
1601897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1602897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
16032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
16042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_ANDROID
1605a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WAIT                     \
1606a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(wait);    \
1607a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(waitid);  \
1608a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(waitpid); \
16092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(wait3);
1610897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#else
1611897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#define INIT_WAIT
16122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_WAIT4
1613897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#endif
1614897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
16159530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#if SANITIZER_INTERCEPT_INET
16169530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
16179530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
16189530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
16199530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  uptr sz = __sanitizer_in_addr_sz(af);
16209530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
16219530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
16225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
16245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
16259530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  char *res = REAL(inet_ntop)(af, src, dst, size);
1626a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
16279530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
16289530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
16299530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
16309530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
16319530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
16329530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
16335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
16355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
16369530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  int res = REAL(inet_pton)(af, src, dst);
16379530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (res == 1) {
16389530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af);
16399530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
16409530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  }
16419530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
16429530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
1643a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_INET                       \
1644a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(inet_ntop); \
1645a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(inet_pton);
16469530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#else
16479530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#define INIT_INET
16489530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#endif
16499530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
16509d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#if SANITIZER_INTERCEPT_INET
16519d60087654f89e3452841350d9eca97644edca9dEvgeniy StepanovINTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
16529d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  void *ctx;
16539d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
16549d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
16555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
16575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
16589d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  int res = REAL(inet_aton)(cp, dst);
16599d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  if (res != 0) {
16609d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af_inet);
16619d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
16629d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  }
16639d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  return res;
16649d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov}
1665a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
16669d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#else
16679d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#define INIT_INET_ATON
16689d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#endif
16699d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov
167056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
167156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy StepanovINTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
167256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  void *ctx;
167356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
16745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
16765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
167756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  int res = REAL(pthread_getschedparam)(thread, policy, param);
167856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  if (res == 0) {
167956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
168056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
168156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  }
168256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  return res;
168356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov}
1684a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM \
1685a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
168656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#else
168756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM
168856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#endif
1689897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
1690447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETADDRINFO
1691447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy StepanovINTERCEPTOR(int, getaddrinfo, char *node, char *service,
1692447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo *hints,
1693447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo **out) {
1694447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  void *ctx;
1695447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1696447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1697447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (service)
1698447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1699447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (hints)
1700447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
17015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
17025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
17035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1704447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  int res = REAL(getaddrinfo)(node, service, hints, out);
17053538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov  if (res == 0 && out) {
17063538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
1707447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    struct __sanitizer_addrinfo *p = *out;
1708447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    while (p) {
17093538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
1710447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_addr)
1711512c616cacf70ca029a2bf719a482b902f3687cdEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
1712447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_canonname)
1713447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1714447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov                                       REAL(strlen)(p->ai_canonname) + 1);
1715447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      p = p->ai_next;
1716447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    }
1717447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  }
1718447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  return res;
1719447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
1720a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
1721447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#else
1722447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define INIT_GETADDRINFO
1723447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#endif
1724447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
17259eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETNAMEINFO
17269eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy StepanovINTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
17279eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov            unsigned hostlen, char *serv, unsigned servlen, int flags) {
17289eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  void *ctx;
17299eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
17309eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov                           serv, servlen, flags);
17319eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  // FIXME: consider adding READ_RANGE(sockaddr, salen)
17329eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  // There is padding in in_addr that may make this too noisy
17335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
17345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
17355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
17369eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  int res =
17379eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
17389eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  if (res == 0) {
17399eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov    if (host && hostlen)
17409eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
17419eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov    if (serv && servlen)
17429eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
17439eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  }
17449eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  return res;
17459eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov}
1746a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
17479eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#else
17489eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#define INIT_GETNAMEINFO
17499eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#endif
17509eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov
17519f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKNAME
17529f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy StepanovINTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
17539f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  void *ctx;
17549f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
17559f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
17569f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int addrlen_in = *addrlen;
17575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
17585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
17595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
17609f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int res = REAL(getsockname)(sock_fd, addr, addrlen);
17619f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  if (res == 0) {
17629f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
17639f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  }
17649f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  return res;
17659f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov}
1766a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
17679f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#else
17689f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#define INIT_GETSOCKNAME
17699f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#endif
1770447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
177133b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
17720a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanovstatic void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
17730a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
17740a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (h->h_name)
17750a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
17760a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  char **p = h->h_aliases;
17770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
17780a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
17790a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
17800a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
17810a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
17820a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
17830a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  p = h->h_addr_list;
17840a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
17850a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
17860a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
17870a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
17880a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
17890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
17900a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
179133b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#endif
17920a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
17930a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME
17940a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
17950a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
17960a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
17970a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
17980a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
17990a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
18000a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
18010a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
18020a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
18030a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            int type) {
18040a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
18050a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
18060a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
18070a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
18080a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
18090a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
18100a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
18110a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
18121d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry VyukovINTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
18130a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
18141d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
18151d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
18160a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
18170a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
18180a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
18190a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
18200a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
18210a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
18220a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
18230a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
18240a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
18250a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
18260a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
1827a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETHOSTBYNAME                  \
1828a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostent);    \
1829a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
1830a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyname); \
1831a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyname2);
18320a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
18330a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME
18340a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
18350a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
18360a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
18375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
18385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
18395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines            int *h_errnop) {
18405d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  void *ctx;
18415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
18425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines                           h_errnop);
18435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
18445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
18455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
18465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
18475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (result) {
18485d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
18495d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
18505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  }
18515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (h_errnop)
18525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
18535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return res;
18545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
18555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
18565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
18575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTBYNAME_R
18585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
18595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
18605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_GETHOSTENT_R
18610a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
18620a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
18630a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
18640a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
18650a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           h_errnop);
18665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
18675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
18685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
18690a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
18702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) {
18712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
18722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
18730a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
18742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h_errnop)
18752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
18760a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
18770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
18785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTENT_R                  \
18795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(gethostent_r);
18805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
18815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTENT_R
18825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
18830a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
18845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
18850a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
18860a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
18870a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
18880a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
18890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
18900a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           buflen, result, h_errnop);
18910a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
18925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
18935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
18945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
18950a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
18960a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                                  h_errnop);
18972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) {
18982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
18992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
19000a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
19012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h_errnop)
19022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
19030a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
19040a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
19055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTBYADDR_R                  \
19065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
19075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
19085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTBYADDR_R
19095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
19100a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
19115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
19120a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyname2_r, char *name, int af,
19130a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
19140a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
19150a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
19160a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
19170a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           result, h_errnop);
19185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
19205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
19210a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res =
19220a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
19232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) {
19242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
19252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
19260a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
19272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h_errnop)
19282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
19290a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
19300a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
19315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTBYNAME2_R                  \
1932a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
19330a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
19345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETHOSTBYNAME2_R
19350a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
19360a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
1937f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKOPT
1938f32be42523a199674ea665a499db131591e64e08Evgeniy StepanovINTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1939f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov            int *optlen) {
1940f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  void *ctx;
1941f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1942f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov                           optlen);
1943f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
19445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
19465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1947f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1948f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (res == 0)
1949f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1950f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  return res;
1951f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov}
1952a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
1953f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#else
1954f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#define INIT_GETSOCKOPT
1955f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#endif
1956f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov
19579d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT
19589d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
19599d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
19609d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
19615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  unsigned addrlen0 = 0;
19629d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
19639d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
19649d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
19659d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
19669d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept)(fd, addr, addrlen);
19679d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
1968a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
19699d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
19709d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
19719d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
19729d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
19739d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
1974a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
19759d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
19769d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT
19779d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
19789d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
19799d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT4
19809d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
19819d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
19829d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
19835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  unsigned addrlen0 = 0;
19849d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
19859d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
19869d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
19879d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
19885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
19905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
19919d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
19929d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
1993a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
19949d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
19959d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
19969d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
19979d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
19989d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
1999a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
20009d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
20019d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT4
20029d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
20039d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
2004c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#if SANITIZER_INTERCEPT_MODF
2005c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(double, modf, double x, double *iptr) {
2006c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
2007c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
20085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
20105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2011c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  double res = REAL(modf)(x, iptr);
2012c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
2013c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2014c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
2015c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
2016c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
2017c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(float, modff, float x, float *iptr) {
2018c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
2019c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
20205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
20225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2023c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  float res = REAL(modff)(x, iptr);
2024c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
2025c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2026c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
2027c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
2028c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
2029c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2030c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
2031c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
20325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
20345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2035c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  long double res = REAL(modfl)(x, iptr);
2036c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
2037c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2038c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
2039c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
2040c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
2041a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_MODF                   \
2042a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(modf);  \
2043a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(modff); \
2044a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(modfl);
2045c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#else
2046c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#define INIT_MODF
2047c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#endif
2048c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov
20499666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#if SANITIZER_INTERCEPT_RECVMSG
2050eb7c24bb2e6fd20410d34006759caf76852d0600Evgeniy Stepanovstatic void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2051eb7c24bb2e6fd20410d34006759caf76852d0600Evgeniy Stepanov                         SSIZE_T maxlen) {
20529666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2053ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov  if (msg->msg_name && msg->msg_namelen)
2054ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2055ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov  if (msg->msg_iov && msg->msg_iovlen)
2056b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2057b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
2058b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2059ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov  if (msg->msg_control && msg->msg_controllen)
20609666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
20619666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
20629666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
20639666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy StepanovINTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
20649666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov            int flags) {
20659666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  void *ctx;
20669666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
20675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
20695d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
20709666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
20719666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (res >= 0) {
20729666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
20732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (msg) {
20742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      write_msghdr(ctx, msg, res);
20752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
20762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
20779666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  }
20789666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  return res;
20799666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
2080a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
20819666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#else
20829666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#define INIT_RECVMSG
20839666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#endif
20849666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
2085bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPEERNAME
2086bc33e138d82759074f8333239f96506027731e20Evgeniy StepanovINTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
2087bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  void *ctx;
2088bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
2089bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  unsigned addr_sz;
2090bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (addrlen) addr_sz = *addrlen;
20915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
20935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2094bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  int res = REAL(getpeername)(sockfd, addr, addrlen);
2095bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (!res && addr && addrlen)
2096bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2097bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  return res;
2098bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov}
2099a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
2100bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#else
2101bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#define INIT_GETPEERNAME
2102bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#endif
2103bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov
2104359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#if SANITIZER_INTERCEPT_SYSINFO
2105359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy StepanovINTERCEPTOR(int, sysinfo, void *info) {
2106359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  void *ctx;
21075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
21095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2110359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
2111359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  int res = REAL(sysinfo)(info);
2112359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  if (!res && info)
2113359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
2114359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  return res;
2115359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov}
2116a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
2117359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#else
2118359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#define INIT_SYSINFO
2119359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#endif
2120359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov
2121b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#if SANITIZER_INTERCEPT_READDIR
2122a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy StepanovINTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
2123b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2124b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
21255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
21275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2128a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov  __sanitizer_dirent *res = REAL(readdir)(dirp);
2129a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2130b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2131b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2132b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
213352d08d8412bfa4ccfa38384d781b51e8774807a7Alexey SamsonovINTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
213452d08d8412bfa4ccfa38384d781b51e8774807a7Alexey Samsonov            __sanitizer_dirent **result) {
2135b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2136b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
21375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
21395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2140b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  int res = REAL(readdir_r)(dirp, entry, result);
2141b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (!res) {
21425a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
21435a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    if (*result)
21445a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2145b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  }
2146b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2147b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2148b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2149a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READDIR                  \
2150a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir); \
2151a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir_r);
2152b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#else
2153b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR
2154b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#endif
2155b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2156b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#if SANITIZER_INTERCEPT_READDIR64
2157a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy StepanovINTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
2158b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2159b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
21605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
21625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2163a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
2164a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2165b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2166b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2167b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
216852d08d8412bfa4ccfa38384d781b51e8774807a7Alexey SamsonovINTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
216952d08d8412bfa4ccfa38384d781b51e8774807a7Alexey Samsonov            __sanitizer_dirent64 **result) {
2170b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2171b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
21725d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
21745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2175b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  int res = REAL(readdir64_r)(dirp, entry, result);
2176b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (!res) {
21775a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
21785a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    if (*result)
21795a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2180b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  }
2181b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2182b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2183a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READDIR64                  \
2184a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir64); \
2185a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir64_r);
2186b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#else
2187b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR64
2188b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#endif
2189b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2190341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTRACE
2191341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy StepanovINTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
2192341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  void *ctx;
2193341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
2194341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
2195341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (data) {
2196341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (request == ptrace_setregs)
2197341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
2198341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setfpregs)
2199341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2200341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setfpxregs)
2201341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2202341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setsiginfo)
2203341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
2204341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setregset) {
2205341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
2206341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
2207341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    }
2208341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
2209341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
22105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
22115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
22125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2213341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  uptr res = REAL(ptrace)(request, pid, addr, data);
2214341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
2215341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (!res && data) {
22165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    // Note that PEEK* requests assign different meaning to the return value.
2217341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    // This function does not handle them (nor does it need to).
2218341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (request == ptrace_getregs)
2219341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
2220341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getfpregs)
2221341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2222341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getfpxregs)
2223341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2224341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getsiginfo)
2225341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
22265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    else if (request == ptrace_geteventmsg)
22275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
2228341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getregset) {
2229341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
2230341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
2231341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    }
2232341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
2233341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  return res;
2234341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov}
2235341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
2236a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
2237341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#else
2238341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define INIT_PTRACE
2239341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#endif
2240341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
22413cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#if SANITIZER_INTERCEPT_SETLOCALE
22423cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy StepanovINTERCEPTOR(char *, setlocale, int category, char *locale) {
22433cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  void *ctx;
22443cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
22453cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  if (locale)
22463cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
2247801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(setlocale)(category, locale);
2248a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
22493cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  return res;
22503cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov}
22513cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov
2252a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
22533cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#else
22543cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#define INIT_SETLOCALE
22553cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#endif
22563cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov
2257801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETCWD
2258801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
2259801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  void *ctx;
2260801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
22615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
22625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
22635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2264801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(getcwd)(buf, size);
2265a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2266801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
2267801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
2268a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
2269801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#else
2270801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GETCWD
2271801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#endif
2272801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
2273801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
22741d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry VyukovINTERCEPTOR(char *, get_current_dir_name, int fake) {
2275801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  void *ctx;
22761d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
22775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
22785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
22795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
22801d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  char *res = REAL(get_current_dir_name)(fake);
2281a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2282801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
2283801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
2284801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
2285a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GET_CURRENT_DIR_NAME \
2286a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
2287801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#else
2288801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GET_CURRENT_DIR_NAME
2289801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#endif
2290b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2291ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_STRTOIMAX
2292ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
2293ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2294ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
22955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
22965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
22975d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2298ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
2299ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2300ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2301ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2302ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2303ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
2304ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2305ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
23065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
23085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2309ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
2310ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2311ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2312ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2313ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2314a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRTOIMAX                  \
2315a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(strtoimax); \
2316a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(strtoumax);
2317ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2318ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_STRTOIMAX
2319ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2320ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2321ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_MBSTOWCS
2322ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
2323ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2324ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
23255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
23275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2328ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(mbstowcs)(dest, src, len);
2329098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest) {
2330e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + (res < len);
2331e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2332e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2333ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2334ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2335ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2336ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
2337ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            void *ps) {
2338ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2339ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
2340098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2341098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
23425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
23445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
23455a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
2346098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T)(-1) && dest && src) {
2347098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    // This function, and several others, may or may not write the terminating
2348098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    // \0 character. They write it iff they clear *src.
2349098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2350e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2351e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2352ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2353ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2354ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2355a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_MBSTOWCS                  \
2356a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(mbstowcs); \
2357a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
2358ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2359ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSTOWCS
2360ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2361ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2362ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_MBSNRTOWCS
2363ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
2364ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            SIZE_T len, void *ps) {
2365ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2366ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
2367098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) {
2368ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2369098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2370ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  }
2371098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
23725d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
23745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2375ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
2376098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T)(-1) && dest && src) {
2377098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2378e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2379e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2380ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2381ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2382ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2383a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
2384ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2385ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSNRTOWCS
2386ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2387ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2388ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_WCSTOMBS
2389ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
2390ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2391ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
23925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
23945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2395ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(wcstombs)(dest, src, len);
2396098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest) {
2397e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + (res < len);
2398e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2399e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2400ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2401ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2402ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2403ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
2404ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            void *ps) {
2405ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2406ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
2407098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2408098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
24095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
24115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
24125a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
2413098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest && src) {
2414098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2415e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2416e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2417ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2418ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2419ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2420a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WCSTOMBS                  \
2421a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(wcstombs); \
2422a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(wcsrtombs);
2423ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2424ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSTOMBS
2425ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2426ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2427ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_WCSNRTOMBS
2428ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
2429ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            SIZE_T len, void *ps) {
2430ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2431ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
2432098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) {
2433ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2434098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2435ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  }
2436098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
24375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
24395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2440ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
2441098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest && src) {
2442098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2443e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2444e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2445ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2446ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2447ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2448a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
2449ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2450ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSNRTOMBS
2451ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2452ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2453ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#if SANITIZER_INTERCEPT_TCGETATTR
2454ea72768894e32f367607c2142a7dfab603310da0Evgeniy StepanovINTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
2455ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  void *ctx;
2456ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
24575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
24595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2460ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  int res = REAL(tcgetattr)(fd, termios_p);
2461ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  if (!res && termios_p)
2462ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
2463ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  return res;
2464ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov}
2465ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
2466a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
2467ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#else
2468ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#define INIT_TCGETATTR
2469ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#endif
2470ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
247112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#if SANITIZER_INTERCEPT_REALPATH
247212eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovINTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
247312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  void *ctx;
247412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
247512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
247612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
247712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
247812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // version of a versioned symbol. For realpath(), this gives us something
247912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // (called __old_realpath) that does not handle NULL in the second argument.
248012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // Handle it as part of the interceptor.
248112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *allocated_path = 0;
248212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (!resolved_path)
248312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
248412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
248512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *res = REAL(realpath)(path, resolved_path);
2486a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (allocated_path && !res) WRAP(free)(allocated_path);
248712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
248812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  return res;
248912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov}
2490a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
249112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#else
249212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_REALPATH
249312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#endif
249412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
249512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
249612eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovINTERCEPTOR(char *, canonicalize_file_name, const char *path) {
249712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  void *ctx;
249812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
249912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
250012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *res = REAL(canonicalize_file_name)(path);
250112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
250212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  return res;
250312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov}
2504a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_CANONICALIZE_FILE_NAME \
2505a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
250612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#else
250712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_CANONICALIZE_FILE_NAME
250812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#endif
250912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
25105ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#if SANITIZER_INTERCEPT_CONFSTR
25115ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy StepanovINTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
25125ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  void *ctx;
25135ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
25145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
25155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
25165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
25175ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  SIZE_T res = REAL(confstr)(name, buf, len);
25185ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  if (buf && res)
25195ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
25205ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  return res;
25215ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov}
2522a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
25235ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#else
25245ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#define INIT_CONFSTR
25255ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#endif
25265ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov
252784ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
252884ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy StepanovINTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
252984ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  void *ctx;
253084ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
25315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
25325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
25335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
253484ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
2535a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
253684ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  return res;
253784ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov}
2538a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
253984ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#else
254084ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#define INIT_SCHED_GETAFFINITY
254184ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#endif
254284ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov
25431204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#if SANITIZER_INTERCEPT_STRERROR
25441204979804868728edb6edfe3ae018465191a85cEvgeniy StepanovINTERCEPTOR(char *, strerror, int errnum) {
25451204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  void *ctx;
25461204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
25471204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  char *res = REAL(strerror)(errnum);
25482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
25491204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  return res;
25501204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov}
2551a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
25521204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#else
25531204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#define INIT_STRERROR
25541204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#endif
25551204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov
25561204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#if SANITIZER_INTERCEPT_STRERROR_R
25571204979804868728edb6edfe3ae018465191a85cEvgeniy StepanovINTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
25581204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  void *ctx;
25591204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
25605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
25615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
25625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
25631204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  char *res = REAL(strerror_r)(errnum, buf, buflen);
25641204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  // There are 2 versions of strerror_r:
25651204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //  * POSIX version returns 0 on success, negative error code on failure,
25661204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //    writes message to buf.
25671204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //  * GNU version returns message pointer, which points to either buf or some
25681204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //    static storage.
2569d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov  SIZE_T posix_res = (SIZE_T)res;
2570d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov  if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
25711204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    // POSIX version. Spec is not clear on whether buf is NULL-terminated.
2572d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov    // At least on OSX, buf contents are valid even when the call fails.
25731204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    SIZE_T sz = internal_strnlen(buf, buflen);
25741204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    if (sz < buflen) ++sz;
25751204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2576d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov  } else {
25771204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    // GNU version.
25781204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
25791204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  }
25801204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  return res;
25811204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov}
2582a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
25831204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#else
25841204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#define INIT_STRERROR_R
25851204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#endif
25861204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov
25872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_XPG_STRERROR_R
25882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
25892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
25902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
25915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
25925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
25935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
25942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
25952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // This version always returns a null-terminated string.
25962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (buf && buflen)
25972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
25982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
25992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
26002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
26012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
26022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XPG_STRERROR_R
26032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
26042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2605224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANDIR
2606224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
2607224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
2608224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                const struct __sanitizer_dirent **);
2609224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2610224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir_filter_f scandir_filter;
2611224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir_compar_f scandir_compar;
2612224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2613224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
26142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
26152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
26162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(scandir_filter)(dir);
2617224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
2618224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2619224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
2620224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                  const struct __sanitizer_dirent **b) {
26212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
26222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
26232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
26242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
26252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
26262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(scandir_compar)(a, b);
2627224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
2628224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2629224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy StepanovINTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
2630224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov            scandir_filter_f filter, scandir_compar_f compar) {
2631224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  void *ctx;
2632224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
2633224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
2634224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir_filter = filter;
2635224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir_compar = compar;
26365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
26375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
26385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2639224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0,
2640224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                          compar ? wrapped_scandir_compar : 0);
2641224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir_filter = 0;
2642224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir_compar = 0;
2643224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (namelist && res > 0) {
2644224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
2645224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
2646224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    for (int i = 0; i < res; ++i)
2647224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
2648224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                     (*namelist)[i]->d_reclen);
2649224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  }
2650224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  return res;
2651224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
2652a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
2653224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#else
2654224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#define INIT_SCANDIR
2655224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#endif
2656224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2657224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANDIR64
2658224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
2659224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
2660224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                  const struct __sanitizer_dirent64 **);
2661224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2662224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir64_filter_f scandir64_filter;
2663224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir64_compar_f scandir64_compar;
2664224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2665224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
26662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
26672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
26682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(scandir64_filter)(dir);
2669224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
2670224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2671224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
2672224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                    const struct __sanitizer_dirent64 **b) {
26732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
26742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
26752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
26762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
26772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
26782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return IndirectExternCall(scandir64_compar)(a, b);
2679224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
2680224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2681224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy StepanovINTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
2682224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov            scandir64_filter_f filter, scandir64_compar_f compar) {
2683224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  void *ctx;
2684224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
2685224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
2686224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir64_filter = filter;
2687224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir64_compar = compar;
26885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
26895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
26905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2691224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  int res =
2692224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov      REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0,
2693224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                      compar ? wrapped_scandir64_compar : 0);
2694224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir64_filter = 0;
2695224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir64_compar = 0;
2696224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (namelist && res > 0) {
2697224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
2698224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
2699224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    for (int i = 0; i < res; ++i)
2700224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
2701224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                     (*namelist)[i]->d_reclen);
2702224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  }
2703224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  return res;
2704224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
2705a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
2706224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#else
2707224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#define INIT_SCANDIR64
2708224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#endif
2709224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
2710edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETGROUPS
2711edff34b5175c6759685da82077c99ee2be017667Evgeniy StepanovINTERCEPTOR(int, getgroups, int size, u32 *lst) {
2712edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  void *ctx;
2713edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
27145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
27155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
27165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2717edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  int res = REAL(getgroups)(size, lst);
2718a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
2719edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  return res;
2720edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov}
2721a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
2722edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#else
2723edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#define INIT_GETGROUPS
2724edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#endif
2725edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov
2726e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#if SANITIZER_INTERCEPT_POLL
2727e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanovstatic void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
2728e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov                        __sanitizer_nfds_t nfds) {
2729e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  for (unsigned i = 0; i < nfds; ++i) {
2730e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
2731e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
2732e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  }
2733e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
2734e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
2735e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanovstatic void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
2736e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov                         __sanitizer_nfds_t nfds) {
2737e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  for (unsigned i = 0; i < nfds; ++i)
27385bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
27395bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonov                                   sizeof(fds[i].revents));
2740e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
2741e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
2742e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy StepanovINTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2743e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov            int timeout) {
2744e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  void *ctx;
2745e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
2746e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2747e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
2748e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2749e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  return res;
2750e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
2751a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
2752e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#else
2753e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define INIT_POLL
2754e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#endif
2755e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
2756e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#if SANITIZER_INTERCEPT_PPOLL
2757e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy StepanovINTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2758b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
2759e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  void *ctx;
2760e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
2761e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2762e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (timeout_ts)
2763e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
2764b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov  // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
2765e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  int res =
2766e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
2767e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2768e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  return res;
2769e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
2770a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
2771e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#else
2772e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define INIT_PPOLL
2773e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#endif
2774e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
2775c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#if SANITIZER_INTERCEPT_WORDEXP
2776c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy StepanovINTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
2777c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  void *ctx;
2778c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
2779c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
27805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
27815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
27825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2783c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  int res = REAL(wordexp)(s, p, flags);
2784c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  if (!res && p) {
2785c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2786c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    if (p->we_wordc)
2787c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
2788c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov                                     sizeof(*p->we_wordv) * p->we_wordc);
2789c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    for (uptr i = 0; i < p->we_wordc; ++i) {
2790c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov      char *w = p->we_wordv[i];
2791c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
2792c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    }
2793c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  }
2794c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  return res;
2795c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov}
2796a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
2797c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#else
2798c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#define INIT_WORDEXP
2799c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#endif
2800c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov
28019a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGWAIT
28029a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
28039a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
28049a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
28059a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
28065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
28085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
28099a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigwait)(set, sig);
28109a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
28119a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
28129a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
2813a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
28149a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
28159a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGWAIT
28169a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
28179a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
28189a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGWAITINFO
28199a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
28209a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
28219a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
28229a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
28235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
28255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
28269a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigwaitinfo)(set, info);
28279a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
28289a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
28299a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
2830a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
28319a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
28329a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGWAITINFO
28339a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
28349a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
28359a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
28369a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
28379a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov            void *timeout) {
28389a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
28399a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
28409a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
28419a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
28425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
28445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
28459a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigtimedwait)(set, info, timeout);
28469a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
28479a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
28489a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
2849a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
28509a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
28519a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGTIMEDWAIT
28529a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
28539a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
28549a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGSETOPS
28559a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
28569a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
28579a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
28585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
28605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
28619a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigemptyset)(set);
28629a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
28639a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
28649a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
28659a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
28669a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
28679a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
28689a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
28695d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28705d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
28715d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
28729a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigfillset)(set);
28739a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
28749a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
28759a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
2876a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGSETOPS                    \
2877a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sigemptyset); \
2878a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sigfillset);
28799a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
28809a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGSETOPS
28819a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
28829a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
28839a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGPENDING
28849a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
28859a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
28869a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
28875d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
28895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
28909a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigpending)(set);
28919a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
28929a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
28939a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
2894a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
28959a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
28969a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGPENDING
28979a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
28989a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
28999a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGPROCMASK
29009a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
29019a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov            __sanitizer_sigset_t *oldset) {
29029a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
29039a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
29049a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
29055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
29075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
29089a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigprocmask)(how, set, oldset);
29099a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && oldset)
29109a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
29119a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
29129a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
2913a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
29149a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
29159a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGPROCMASK
29169a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
29179a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
29181394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#if SANITIZER_INTERCEPT_BACKTRACE
29191394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy StepanovINTERCEPTOR(int, backtrace, void **buffer, int size) {
29201394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  void *ctx;
29211394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
29225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
29245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
29251394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  int res = REAL(backtrace)(buffer, size);
29261394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  if (res && buffer)
29271394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
29281394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  return res;
29291394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov}
29301394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov
29311394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy StepanovINTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
29321394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  void *ctx;
29331394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
29341394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  if (buffer && size)
29351394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
29365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
29385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2939a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  char **res = REAL(backtrace_symbols)(buffer, size);
29401394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  if (res && size) {
29411394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
29421394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    for (int i = 0; i < size; ++i)
29431394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
29441394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  }
29451394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  return res;
29461394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov}
2947a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_BACKTRACE                  \
2948a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(backtrace); \
2949a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
29501394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#else
29511394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#define INIT_BACKTRACE
29521394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#endif
29531394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov
295414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#if SANITIZER_INTERCEPT__EXIT
295514dd980b384ad859099b499e12f320c4791fb674Dmitry VyukovINTERCEPTOR(void, _exit, int status) {
295614dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  void *ctx;
295714dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
295814dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
2959a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (status == 0) status = status1;
296014dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  REAL(_exit)(status);
296114dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov}
2962a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
296314dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#else
296414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#define INIT__EXIT
296514dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#endif
296614dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov
29675e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
29685e2d3776a314629680921abd1d55d89d95a2da90Alexey SamsonovINTERCEPTOR(int, pthread_mutex_lock, void *m) {
29695e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  void *ctx;
29705e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
29715e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  int res = REAL(pthread_mutex_lock)(m);
297211f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov  if (res == errno_EOWNERDEAD)
297311f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov    COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
297411f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov  if (res == 0 || res == errno_EOWNERDEAD)
297511f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov    COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
29765e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  return res;
29775e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov}
29785e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
29795e2d3776a314629680921abd1d55d89d95a2da90Alexey SamsonovINTERCEPTOR(int, pthread_mutex_unlock, void *m) {
29805e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  void *ctx;
29815e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
29825e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
29835e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  return REAL(pthread_mutex_unlock)(m);
29845e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov}
29855e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
2986a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
2987a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_MUTEX_UNLOCK \
2988a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
29895e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#else
29905e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#define INIT_PTHREAD_MUTEX_LOCK
29915e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#define INIT_PTHREAD_MUTEX_UNLOCK
29925e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#endif
29935e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
29944d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
29954d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanovstatic void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
29964d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
29974d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_fsname)
29984d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
29994d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_fsname) + 1);
30004d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_dir)
30014d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
30024d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_dir) + 1);
30034d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_type)
30044d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
30054d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_type) + 1);
30064d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_opts)
30074d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
30084d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_opts) + 1);
30094d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov}
30104d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#endif
30114d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
30124d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETMNTENT
30134d7297daef90ad59446250617b72d184141436fcEvgeniy StepanovINTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
30144d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  void *ctx;
30154d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
30164d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  __sanitizer_mntent *res = REAL(getmntent)(fp);
30174d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (res) write_mntent(ctx, res);
30184d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  return res;
30194d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov}
3020a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
30214d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#else
30224d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#define INIT_GETMNTENT
30234d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#endif
30244d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
30254d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETMNTENT_R
30264d7297daef90ad59446250617b72d184141436fcEvgeniy StepanovINTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
30274d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
30284d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  void *ctx;
30294d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
30304d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
30314d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (res) write_mntent(ctx, res);
30324d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  return res;
30334d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov}
3034a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
30354d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#else
30364d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#define INIT_GETMNTENT_R
30374d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#endif
30384d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
30395cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATFS
30405cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statfs, char *path, void *buf) {
30415cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
30425cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
30435cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
30445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
30465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
30475cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statfs)(path, buf);
30485cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
30495cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
30505cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
30515cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatfs, int fd, void *buf) {
30525cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
30535cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
30545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
30565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
30575cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatfs)(fd, buf);
30585cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
30595cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
30605cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3061a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATFS                  \
3062a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statfs); \
3063a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatfs);
30645cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
30655cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATFS
30665cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
30675cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov
30685cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATFS64
30695cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statfs64, char *path, void *buf) {
30705cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
30715cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
30725cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
30735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
30755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
30765cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statfs64)(path, buf);
30775cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
30785cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
30795cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
30805cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatfs64, int fd, void *buf) {
30815cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
30825cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
30835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
30855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
30865cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatfs64)(fd, buf);
30875cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
30885cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
30895cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3090a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATFS64                  \
3091a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statfs64); \
3092a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatfs64);
30935cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
30945cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATFS64
30955cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
30965cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov
30975cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATVFS
30985cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statvfs, char *path, void *buf) {
30995cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
31005cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
31015cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
31025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
31045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
31055cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statvfs)(path, buf);
31065cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
31075cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
31085cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
31095cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatvfs, int fd, void *buf) {
31105cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
31115cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
31125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
31145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
31155cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatvfs)(fd, buf);
31165cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
31175cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
31185cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3119a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATVFS                  \
3120a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statvfs); \
3121a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatvfs);
31225cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
31235cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATVFS
31245cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
31255cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov
31265cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATVFS64
31275cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statvfs64, char *path, void *buf) {
31285cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
31295cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
31305cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
31315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
31335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
31345cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statvfs64)(path, buf);
31355cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
31365cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
31375cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
31385cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
31395cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
31405cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
31415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
31435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
31445cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatvfs64)(fd, buf);
31455cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
31465cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
31475cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3148a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATVFS64                  \
3149a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statvfs64); \
3150a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatvfs64);
31515cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
31525cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATVFS64
31535cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
31544d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
3155285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#if SANITIZER_INTERCEPT_INITGROUPS
3156285d458935bc2f9d8ec1109de01ed66185062349Evgeniy StepanovINTERCEPTOR(int, initgroups, char *user, u32 group) {
3157285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  void *ctx;
3158285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
3159285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
3160285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  int res = REAL(initgroups)(user, group);
3161285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  return res;
3162285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov}
3163a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
3164285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#else
3165285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#define INIT_INITGROUPS
3166285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#endif
3167285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov
31685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
3169369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
3170369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3171369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
3172369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3173369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  char *res = REAL(ether_ntoa)(addr);
31742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3175369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3176369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
3177369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
3178369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3179369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
3180369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3181369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
31822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
3183369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3184369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
31855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_ETHER_NTOA_ATON             \
31865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
31875d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(ether_aton);
31885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
31895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_ETHER_NTOA_ATON
31905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
31915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
31925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_ETHER_HOST
3193369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
3194369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3195369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
3196369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
31975d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
31995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3200369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  int res = REAL(ether_ntohost)(hostname, addr);
3201369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (!res && hostname)
3202369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3203369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3204369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
3205369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
3206369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3207369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
3208369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (hostname)
3209369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
32105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
32125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3213369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  int res = REAL(ether_hostton)(hostname, addr);
3214369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3215369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3216369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
3217369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
3218369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov            char *hostname) {
3219369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3220369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
3221369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
32225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
32245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3225369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  int res = REAL(ether_line)(line, addr, hostname);
3226369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (!res) {
3227369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3228369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    if (hostname)
3229369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3230369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  }
3231369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3232369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
32335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_ETHER_HOST                     \
3234a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
3235a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_hostton); \
3236a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_line);
3237369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov#else
32385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_ETHER_HOST
3239369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov#endif
3240369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov
3241220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#if SANITIZER_INTERCEPT_ETHER_R
3242220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy StepanovINTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
3243220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  void *ctx;
3244220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
3245220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
32465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
32485d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3249220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  char *res = REAL(ether_ntoa_r)(addr, buf);
3250220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3251220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  return res;
3252220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov}
3253220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy StepanovINTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
3254220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov            __sanitizer_ether_addr *addr) {
3255220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  void *ctx;
3256220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
3257220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
32585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
32605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3261220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
3262220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
3263220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  return res;
3264220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov}
3265a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ETHER_R                       \
3266a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
3267a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_aton_r);
3268220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#else
3269220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#define INIT_ETHER_R
3270220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#endif
3271220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov
327210362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#if SANITIZER_INTERCEPT_SHMCTL
327310362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy StepanovINTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
327410362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  void *ctx;
327510362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
32765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
32785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
327910362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  int res = REAL(shmctl)(shmid, cmd, buf);
328010362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  if (res >= 0) {
328110362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    unsigned sz = 0;
328210362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
3283f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov      sz = sizeof(__sanitizer_shmid_ds);
328410362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    else if (cmd == shmctl_ipc_info)
328510362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov      sz = struct_shminfo_sz;
328610362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    else if (cmd == shmctl_shm_info)
328710362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov      sz = struct_shm_info_sz;
328810362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
328910362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  }
329010362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  return res;
329110362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov}
3292a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
329310362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#else
329410362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#define INIT_SHMCTL
329510362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#endif
329610362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov
3297aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#if SANITIZER_INTERCEPT_RANDOM_R
3298aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy StepanovINTERCEPTOR(int, random_r, void *buf, u32 *result) {
3299aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  void *ctx;
3300aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
33015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
33025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
33035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3304aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  int res = REAL(random_r)(buf, result);
3305aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  if (!res && result)
3306aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3307aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  return res;
3308aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov}
3309a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
3310aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#else
3311aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#define INIT_RANDOM_R
3312aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#endif
3313aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov
33145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and corrupt
33155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// its metadata. See
33165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
33175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
33185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
33195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
33205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
33215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
33225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
33235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
33245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPTOR(int, fn, void *attr, void *r) {                  \
33255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    void *ctx;                                                 \
33265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
33275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    int res = REAL(fn)(attr, r);                               \
33285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
33295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    return res;                                                \
3330e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  }
33315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
33325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
33335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
33345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
33355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
33365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
33375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
33385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
33395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
33405d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
3341e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3342e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3343e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
3344e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
3345e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
3346e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
3347e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
3348e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
3349e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
3350e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
3351e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  void *ctx;
3352e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
33535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
33545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
33555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3356e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  int res = REAL(pthread_attr_getstack)(attr, addr, size);
3357e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  if (!res) {
3358e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3359e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
3360e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  }
3361e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  return res;
3362e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov}
3363e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
33642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// We may need to call the real pthread_attr_getstack from the run-time
33652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// in sanitizer_common, but we don't want to include the interception headers
33662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// there. So, just define this function here.
33672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __sanitizer {
33682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" {
33692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
33702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(pthread_attr_getstack)(attr, addr, size);
33712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
33722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}  // extern "C"
33732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}  // namespace __sanitizer
33742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3375a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GET                             \
3376a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
3377a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
3378a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \
3379a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
3380a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
3381a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
3382a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
3383e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#else
3384e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GET
3385e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3386e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3387e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
3388e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
3389e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3390e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
3391a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
3392e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#else
3393e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETINHERITSCHED
3394e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3395e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3396e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
3397e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
3398e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov            void *cpuset) {
3399e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  void *ctx;
3400e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
3401e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov                           cpuset);
34025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
34045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3405e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
3406e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  if (!res && cpusetsize && cpuset)
3407e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
3408e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  return res;
3409e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov}
3410e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3411e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
3412a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
3413e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#else
3414e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
3415e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3416e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
34175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
34185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
34195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
34205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
34215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPSHARED
34235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
34265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
34275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETTYPE \
34285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
34295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETTYPE
34315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
34345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
34355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
34365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
34375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
34395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34405d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
34425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
34435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
34445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
34455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
34475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34485d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34495d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
34505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
34515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST \
34525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
34535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST
34555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
34585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
34595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
34605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
34615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
34635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
34665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
34675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
34685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
34695d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34705d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
34715d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34725d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
34745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
34755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
34765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
34775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
34795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
34825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
34835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_CONDATTR_GETPSHARED \
34845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
34855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_CONDATTR_GETPSHARED
34875d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34885d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
34905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
34915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_CONDATTR_GETCLOCK \
34925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
34935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
34945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_CONDATTR_GETCLOCK
34955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
34965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
34975d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
34985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
34995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
35005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
35015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
35025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_PTHREAD_BARRIERATTR_GETPSHARED
35035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
35045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
3505eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#if SANITIZER_INTERCEPT_TMPNAM
3506eada1a81188329b3f011311caed12ca4be4f639eEvgeniy StepanovINTERCEPTOR(char *, tmpnam, char *s) {
3507eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  void *ctx;
3508eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
3509eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  char *res = REAL(tmpnam)(s);
3510eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (res) {
3511eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov    if (s)
35125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      // FIXME: under ASan the call below may write to freed memory and corrupt
35135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      // its metadata. See
35145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3515eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3516eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov    else
35172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3518eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  }
3519eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  return res;
3520eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov}
3521a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
3522eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#else
3523eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#define INIT_TMPNAM
3524eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#endif
3525eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
3526eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#if SANITIZER_INTERCEPT_TMPNAM_R
3527eada1a81188329b3f011311caed12ca4be4f639eEvgeniy StepanovINTERCEPTOR(char *, tmpnam_r, char *s) {
3528eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  void *ctx;
3529eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
35305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
35315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
35325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3533eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  char *res = REAL(tmpnam_r)(s);
3534eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3535eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  return res;
3536eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov}
3537a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
3538eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#else
3539eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#define INIT_TMPNAM_R
3540eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#endif
3541eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
3542eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#if SANITIZER_INTERCEPT_TEMPNAM
3543eada1a81188329b3f011311caed12ca4be4f639eEvgeniy StepanovINTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
3544eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  void *ctx;
3545eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
3546eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
3547eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
3548eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  char *res = REAL(tempnam)(dir, pfx);
35492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3550eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  return res;
3551eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov}
3552a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
3553eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#else
3554eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#define INIT_TEMPNAM
3555eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#endif
3556eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
35575cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
35585cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry VyukovINTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
35595cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  void *ctx;
35605cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
35615cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
35625cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  return REAL(pthread_setname_np)(thread, name);
35635cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov}
3564a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
35655cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#else
35665cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define INIT_PTHREAD_SETNAME_NP
35675cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#endif
35685cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov
3569f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_SINCOS
3570f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
3571f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3572f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
35735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
35745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
35755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3576f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  REAL(sincos)(x, sin, cos);
3577f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3578f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3579f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3580f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
3581f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3582f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
35835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
35845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
35855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3586f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  REAL(sincosf)(x, sin, cos);
3587f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3588f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3589f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3590f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
3591f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3592f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
35935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
35945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
35955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3596f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  REAL(sincosl)(x, sin, cos);
3597f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3598f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3599f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3600a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SINCOS                   \
3601a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sincos);  \
3602a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sincosf); \
3603a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sincosl);
3604f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
3605f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#define INIT_SINCOS
3606f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
3607f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
3608f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_REMQUO
3609f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(double, remquo, double x, double y, int *quo) {
3610f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3611f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
36125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
36145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3615f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  double res = REAL(remquo)(x, y, quo);
3616f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3617f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3618f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3619f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(float, remquof, float x, float y, int *quo) {
3620f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3621f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
36225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
36245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3625f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  float res = REAL(remquof)(x, y, quo);
3626f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3627f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3628f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3629f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
3630f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3631f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
36325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
36345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3635f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  long double res = REAL(remquol)(x, y, quo);
3636f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3637f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3638f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3639a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_REMQUO                   \
3640a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(remquo);  \
3641a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(remquof); \
3642a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(remquol);
3643f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
3644f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#define INIT_REMQUO
3645f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
3646f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
3647f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_LGAMMA
3648f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanovextern int signgam;
3649f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(double, lgamma, double x) {
3650f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3651f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
3652f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  double res = REAL(lgamma)(x);
3653f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3654f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3655f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3656f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(float, lgammaf, float x) {
3657f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3658f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
3659f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  float res = REAL(lgammaf)(x);
3660f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3661f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3662f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3663f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(long double, lgammal, long double x) {
3664f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3665f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
3666f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  long double res = REAL(lgammal)(x);
3667f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3668f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3669f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3670a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_LGAMMA                   \
3671a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lgamma);  \
3672a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lgammaf); \
3673a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lgammal);
3674f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
3675f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#define INIT_LGAMMA
3676f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
3677f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
3678f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_LGAMMA_R
3679f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(double, lgamma_r, double x, int *signp) {
3680f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3681f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
36825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
36845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3685f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  double res = REAL(lgamma_r)(x, signp);
3686f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
3687f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3688f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
3689f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(float, lgammaf_r, float x, int *signp) {
3690f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3691f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
36925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
36945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3695f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  float res = REAL(lgammaf_r)(x, signp);
3696f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
3697f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3698f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
36995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_LGAMMA_R                   \
37005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
37015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(lgammaf_r);
37025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else
37035d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_LGAMMA_R
37045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif
37055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
37065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if SANITIZER_INTERCEPT_LGAMMAL_R
3707f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
3708f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
3709f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
37105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
37125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3713f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  long double res = REAL(lgammal_r)(x, signp);
3714f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
3715f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
3716f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
37175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION(lgammal_r);
3718f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
37195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_LGAMMAL_R
3720f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
3721f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
372278d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#if SANITIZER_INTERCEPT_DRAND48_R
372378d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy StepanovINTERCEPTOR(int, drand48_r, void *buffer, double *result) {
372478d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  void *ctx;
372578d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
37265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
37285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
372978d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  int res = REAL(drand48_r)(buffer, result);
373078d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
373178d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  return res;
373278d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov}
373378d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy StepanovINTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
373478d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  void *ctx;
373578d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
37365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
37385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
373978d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  int res = REAL(lrand48_r)(buffer, result);
374078d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
374178d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  return res;
374278d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov}
3743a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_DRAND48_R                  \
3744a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(drand48_r); \
3745a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lrand48_r);
374678d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#else
374778d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#define INIT_DRAND48_R
374878d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#endif
3749eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
37502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_RAND_R
37512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, rand_r, unsigned *seedp) {
37522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
37532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
37542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
37552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(rand_r)(seedp);
37562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
37572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
37582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
37592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_RAND_R
37602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
37612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
376226fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETLINE
376326fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy StepanovINTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
376426fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  void *ctx;
376526fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
37665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
37685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
376926fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  SSIZE_T res = REAL(getline)(lineptr, n, stream);
377026fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  if (res > 0) {
377126fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
377226fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
377326fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
377426fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  }
377526fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  return res;
377626fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov}
37775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
377826fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov            void *stream) {
377926fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  void *ctx;
37805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __getdelim, lineptr, n, delim, stream);
37815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
37835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
37845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  SSIZE_T res = REAL(__getdelim)(lineptr, n, delim, stream);
378526fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  if (res > 0) {
378626fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
378726fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
378826fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
378926fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  }
379026fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  return res;
379126fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov}
37925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesINTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
37935d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines            void *stream) {
37945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __getdelim(lineptr, n, delim, stream);
37955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
37965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define INIT_GETLINE                     \
37975d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(getline);    \
37985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  COMMON_INTERCEPT_FUNCTION(__getdelim); \
3799a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getdelim);
380026fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#else
380126fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#define INIT_GETLINE
380226fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#endif
380326fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov
38042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ICONV
38052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
38062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            char **outbuf, SIZE_T *outbytesleft) {
38072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
38082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
38092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           outbytesleft);
38102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (inbytesleft)
38112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
38122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (inbuf && inbytesleft)
38132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
38142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (outbytesleft)
38152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
38162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *outbuf_orig = outbuf ? *outbuf : 0;
38175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
38195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
38202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
38212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
38222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
38232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
38242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
38252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
38262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
38272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
38282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
38292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ICONV
38302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
38312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
38322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TIMES
38332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
38342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
38352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
38365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
38385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
38392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_clock_t res = REAL(times)(tms);
38402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != (__sanitizer_clock_t)-1 && tms)
38412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
38422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
38432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
38442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
38452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
38462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TIMES
38472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
38482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
38492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TLS_GET_ADDR
38502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
38512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __tls_get_addr, void *arg) {
38522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
38532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
38542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(__tls_get_addr)(arg);
38555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res);
38565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (dtv) {
38575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    // New DTLS block has been allocated.
38585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
38595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  }
38602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
38612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
38622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
38632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TLS_GET_ADDR
38642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
38652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
38662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_LISTXATTR
38672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
38682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
38692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
38702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
38715d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38725d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
38735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
38742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(listxattr)(path, list, size);
38752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Here and below, size == 0 is a special case where nothing is written to the
38762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // buffer, and res contains the desired buffer size.
38772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
38782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
38792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
38802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
38812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
38822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
38832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
38845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
38865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
38872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(llistxattr)(path, list, size);
38882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
38892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
38902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
38912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
38922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
38932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
38945d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
38965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
38972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(flistxattr)(fd, list, size);
38982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
38992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
39002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LISTXATTR                   \
39022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(listxattr);  \
39032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(llistxattr); \
39042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(flistxattr);
39052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
39062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LISTXATTR
39072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
39082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
39092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETXATTR
39102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
39112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T size) {
39122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
39132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
39142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
39152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
39165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
39185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
39192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(getxattr)(path, name, value, size);
39202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
39212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
39222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
39242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T size) {
39252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
39262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
39272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
39282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
39295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
39315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
39322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
39332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
39342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
39352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
39372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T size) {
39382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
39392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
39402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
39415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
39435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
39442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
39452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
39462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
39472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETXATTR                   \
39492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getxattr);  \
39502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(lgetxattr); \
39512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetxattr);
39522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
39532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETXATTR
39542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
39552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
39562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETRESID
39572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
39582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
39592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
39605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
39625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
39632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getresuid)(ruid, euid, suid);
39642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res >= 0) {
39652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
39662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
39672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
39682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
39692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
39702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
39722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
39732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
39745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
39765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
39772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getresgid)(rgid, egid, sgid);
39782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res >= 0) {
39792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
39802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
39812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
39822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
39832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
39842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETRESID                   \
39862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getresuid); \
39872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getresgid);
39882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
39892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETRESID
39902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
39912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
39922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETIFADDRS
39932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
39942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// intercept freeifaddrs(). If that ceases to be the case, we might need to
39952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// intercept it to poison the memory again.
39962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
39972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
39982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
39995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
40005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
40015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
40022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getifaddrs)(ifap);
40032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res == 0 && ifap) {
40042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
40052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __sanitizer_ifaddrs *p = *ifap;
40062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    while (p) {
40072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
40082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_name)
40092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
40102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                       REAL(strlen)(p->ifa_name) + 1);
40112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_addr)
40122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
40132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_netmask)
40142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
40152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      // On Linux this is a union, but the other member also points to a
40162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      // struct sockaddr, so the following is sufficient.
40172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_dstaddr)
40182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
40192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      // FIXME(smatveev): Unpoison p->ifa_data as well.
40202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      p = p->ifa_next;
40212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
40222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
40232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
40242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
40252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETIFADDRS                  \
40262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getifaddrs);
40272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
40282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETIFADDRS
40292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
40302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
40312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_IF_INDEXTONAME
40322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
40332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
40342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
40355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
40365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
40375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
40382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char *res = REAL(if_indextoname)(ifindex, ifname);
40392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res && ifname)
40402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
40412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
40422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
40432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
40442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
40452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
40462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (ifname)
40472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
40482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(if_nametoindex)(ifname);
40492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
40502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_IF_INDEXTONAME                  \
40512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(if_indextoname); \
40522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(if_nametoindex);
40532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
40542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_IF_INDEXTONAME
40552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
40562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
40572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_CAPGET
40582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, capget, void *hdrp, void *datap) {
40592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
40602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
40612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (hdrp)
40622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
40635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
40645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
40655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
40662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(capget)(hdrp, datap);
40672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res == 0 && datap)
40682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
40692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // We can also return -1 and write to hdrp->version if the version passed in
40702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // hdrp->version is unsupported. But that's not a trivial condition to check,
40712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
40722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
40732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
40742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, capset, void *hdrp, const void *datap) {
40752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
40762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
40772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (hdrp)
40782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
40792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (datap)
40802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
40812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(capset)(hdrp, datap);
40822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
40832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_CAPGET                  \
40842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(capget); \
40852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(capset);
40862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
40872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_CAPGET
40882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
40892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
40902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_AEABI_MEM
40912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr);
40922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr);
40932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
40942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
40952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
40962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memmove)(to, from, size);
40972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
40982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
40992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memmove)(to, from, size);
41002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
41022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memmove)(to, from, size);
41032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
41052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memcpy)(to, from, size);
41062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
41082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memcpy)(to, from, size);
41092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
41112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memcpy)(to, from, size);
41122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Note the argument order.
41142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
41152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, c, size);
41162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
41182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, c, size);
41192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
41212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, c, size);
41222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
41242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
41252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
41272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
41282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
41302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
41312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_AEABI_MEM                         \
41332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
41342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
41352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
41362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
41372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
41382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
41392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
41402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
41412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
41422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
41432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
41442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
41452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
41462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_AEABI_MEM
41472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_AEABI_MEM
41482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
41492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT___BZERO
41502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
41512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
41522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __bzero, void *block, uptr size) {
41532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
41542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
41562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
41572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT___BZERO
41582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT___BZERO
41592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
41602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FTIME
41612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
41622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
41632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
41645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
41665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
41672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(ftime)(tp);
41682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (tp)
41692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
41702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
41712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
41732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
41742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FTIME
41752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_FTIME
41762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
41772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_XDR
41782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
41792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            unsigned size, int op) {
41802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
41812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
41825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
41845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
41852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(xdrmem_create)(xdrs, addr, size, op);
41862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
41872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (op == __sanitizer_XDR_ENCODE) {
41882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // It's not obvious how much data individual xdr_ routines write.
41892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // Simply unpoison the entire target buffer in advance.
41902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
41912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
41922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
41932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
41942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
41952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
41962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
41975d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
41995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
42002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(xdrstdio_create)(xdrs, file, op);
42012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
42022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
42032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
42045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// FIXME: under ASan the call below may write to freed memory and corrupt
42055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// its metadata. See
42065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
42072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define XDR_INTERCEPTOR(F, T)                             \
42082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
42092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void *ctx;                                            \
42102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
42112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
42122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
42132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(F)(xdrs, p);                           \
42142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
42152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
42162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                           \
42172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
42182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
42192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_short, short)
42202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_short, unsigned short)
42212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int, int)
42222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_int, unsigned)
42232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_long, long)
42242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_long, unsigned long)
42252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_hyper, long long)
42262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
42272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_longlong_t, long long)
42282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
42292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int8_t, u8)
42302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint8_t, u8)
42312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int16_t, u16)
42322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint16_t, u16)
42332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int32_t, u32)
42342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint32_t, u32)
42352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int64_t, u64)
42362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint64_t, u64)
42372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_quad_t, long long)
42382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
42392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_bool, bool)
42402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_enum, int)
42412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_char, char)
42422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_char, unsigned char)
42432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_float, float)
42442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_double, double)
42452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
42462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
42472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// wrapstring, sizeof
42482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
42492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
42502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            unsigned maxsize) {
42512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
42522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
42532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
42542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
42552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
42562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
42572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
42585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
42605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
42612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
42622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
42632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
42642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
42652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
42662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
42672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
42682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
42692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
42702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
42712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            unsigned maxsize) {
42722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
42732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
42742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
42752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
42762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
42772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
42785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
42805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
42812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(xdr_string)(xdrs, p, maxsize);
42822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
42832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
42842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res && *p)
42852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
42862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
42872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
42882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
42892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
42902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XDR                               \
42912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
42922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
42932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_short);        \
42942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
42952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int);          \
42962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
42972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_long);         \
42982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
42992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
43002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
43012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
43022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
43032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
43042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
43052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
43062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
43072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
43082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
43092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
43102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
43112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
43122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
43132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
43142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
43152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_char);         \
43162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
43172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_float);        \
43182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_double);       \
43192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
43202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_string);
43212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
43222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XDR
43232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_XDR
43242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
43252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TSEARCH
43262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, tsearch, void *key, void **rootp,
43272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            int (*compar)(const void *, const void *)) {
43282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
43305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
43315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
43325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
43332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(tsearch)(key, rootp, compar);
43342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res && *(void **)res == key)
43352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
43362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
43392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
43402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TSEARCH
43412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
43422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
43432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
43442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SANITIZER_INTERCEPT_OPEN_MEMSTREAM
43452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid unpoison_file(__sanitizer_FILE *fp) {
43462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_HAS_STRUCT_FILE
43472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
43482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
43492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
43502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        fp->_IO_read_end - fp->_IO_read_base);
43512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_HAS_STRUCT_FILE
43522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
43542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
43552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_LIBIO_INTERNALS
43562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// These guys are called when a .c source is built with -O2.
43572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
43582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
43602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__uflow)(fp);
43612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
43622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
43652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
43672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__underflow)(fp);
43682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
43692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
43722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
43742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__overflow)(fp, ch);
43752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
43762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
43792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
43812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__wuflow)(fp);
43822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
43832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
43862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
43882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__wunderflow)(fp);
43892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
43902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
43932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
43952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__woverflow)(fp, ch);
43962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
43972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
43982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LIBIO_INTERNALS               \
44002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__uflow);      \
44012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__underflow);  \
44022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__overflow);   \
44032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__wuflow);     \
44042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__wunderflow); \
44052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__woverflow);
44062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
44072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LIBIO_INTERNALS
44082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
44092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
44102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FOPEN
44112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
44122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
44142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
44152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
44162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fopen)(path, mode);
44172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
44182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
44192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
44222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
44242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
44252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
44262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
44272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
44302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_FILE *fp) {
44312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
44332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
44342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
44352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
44362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
44372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
44382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
44392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN                   \
44422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fopen);  \
44432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fdopen); \
44442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(freopen);
44452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
44462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN
44472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
44482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
44492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FOPEN64
44502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
44512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
44532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
44542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
44552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fopen64)(path, mode);
44562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
44572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
44582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
44612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_FILE *fp) {
44622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
44642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
44652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
44662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
44672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
44682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
44692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
44702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN64                  \
44732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fopen64); \
44742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(freopen64);
44752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
44762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN64
44772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
44782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
44792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
44802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
44812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
44835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
44845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
44855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
44862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
44872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) {
44882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
44892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
44902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    unpoison_file(res);
44912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FileMetadata file = {ptr, sizeloc};
44922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SetInterceptorMetadata(res, file);
44932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
44942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
44972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T *sizeloc) {
44982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
45002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
45012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) {
45022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
45032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
45042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    unpoison_file(res);
45052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FileMetadata file = {(char **)ptr, sizeloc};
45062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SetInterceptorMetadata(res, file);
45072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
45082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
45112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            const char *mode) {
45122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
45145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
45155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // its metadata. See
45165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
45172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
45182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
45192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OPEN_MEMSTREAM                   \
45222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(open_memstream);  \
45232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
45242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fmemopen);
45252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
45262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OPEN_MEMSTREAM
45272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
45282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
45292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_OBSTACK
45302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void initialize_obstack(__sanitizer_obstack *obstack) {
45312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
45322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (obstack->chunk)
45332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
45342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        sizeof(*obstack->chunk));
45352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
45372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
45382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            int align, void *(*alloc_fn)(uptr arg, uptr sz),
45392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            void (*free_fn)(uptr arg, void *p)) {
45402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
45422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           free_fn);
45432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
45442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) initialize_obstack(obstack);
45452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
45482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
45492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
45512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           free_fn);
45522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
45532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) initialize_obstack(obstack);
45542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
45572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
45592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(_obstack_newchunk)(obstack, length);
45602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (obstack->chunk)
45612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(
45622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        obstack->chunk, obstack->next_free - (char *)obstack->chunk);
45632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OBSTACK                           \
45652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
45662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
45672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
45682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
45692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OBSTACK
45702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
45712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
45722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FFLUSH
45732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
45742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
45762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(fflush)(fp);
45772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // FIXME: handle fp == NULL
45782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (fp) {
45792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const FileMetadata *m = GetInterceptorMetadata(fp);
45802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
45812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
45822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
45852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
45862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FFLUSH
45872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
45882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
45892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FCLOSE
45902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
45912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
45932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (fp) {
45942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
45952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const FileMetadata *m = GetInterceptorMetadata(fp);
45962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (m) {
45972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
45982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      DeleteInterceptorMetadata(fp);
45992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
46002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
46012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(fclose)(fp);
46022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
46042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
46052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FCLOSE
46062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
46072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
46092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, dlopen, const char *filename, int flag) {
46102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
46122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(dlopen)(filename, flag);
46132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
46142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, dlclose, void *handle) {
46182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
46202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(dlclose)(handle);
46212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
46222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_DLOPEN_DLCLOSE          \
46252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(dlopen); \
46262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(dlclose);
46272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
46282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_DLOPEN_DLCLOSE
46292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
46302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void InitializeCommonInterceptors() {
46322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
46332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
46342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TEXTDOMAIN;
46362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRCMP;
46372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRNCMP;
46382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRCASECMP;
46392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRNCASECMP;
46402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MEMCHR;
46412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MEMRCHR;
46422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READ;
46432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREAD;
46442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREAD64;
46452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READV;
46462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREADV;
46472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREADV64;
46482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WRITE;
46492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITE;
46502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITE64;
46512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WRITEV;
46522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITEV;
46532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITEV64;
46542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PRCTL;
46552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LOCALTIME_AND_FRIENDS;
46562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRPTIME;
46572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCANF;
46582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ISOC99_SCANF;
46592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PRINTF;
46602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ISOC99_PRINTF;
46612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FREXP;
46622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FREXPF_FREXPL;
46632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWNAM_AND_FRIENDS;
46642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWNAM_R_AND_FRIENDS;
46652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWENT;
46662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FGETPWENT;
46672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWENT_R;
46682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SETPWENT;
46692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CLOCK_GETTIME;
46702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETITIMER;
46712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TIME;
46722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GLOB;
46732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WAIT;
46742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WAIT4;
46752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_INET;
46762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_GETSCHEDPARAM;
46772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETADDRINFO;
46782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETNAMEINFO;
46792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETSOCKNAME;
46802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETHOSTBYNAME;
46812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETHOSTBYNAME_R;
46825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_GETHOSTBYNAME2_R;
46835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_GETHOSTBYADDR_R;
46845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_GETHOSTENT_R;
46852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETSOCKOPT;
46862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ACCEPT;
46872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ACCEPT4;
46882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MODF;
46892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_RECVMSG;
46902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPEERNAME;
46912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_IOCTL;
46922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_INET_ATON;
46932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SYSINFO;
46942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READDIR;
46952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READDIR64;
46962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTRACE;
46972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SETLOCALE;
46982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETCWD;
46992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GET_CURRENT_DIR_NAME;
47002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRTOIMAX;
47012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MBSTOWCS;
47022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MBSNRTOWCS;
47032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WCSTOMBS;
47042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WCSNRTOMBS;
47052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TCGETATTR;
47062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_REALPATH;
47072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CANONICALIZE_FILE_NAME;
47082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CONFSTR;
47092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCHED_GETAFFINITY;
47102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRERROR;
47112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRERROR_R;
47122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_XPG_STRERROR_R;
47132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCANDIR;
47142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCANDIR64;
47152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETGROUPS;
47162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_POLL;
47172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PPOLL;
47182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WORDEXP;
47192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGWAIT;
47202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGWAITINFO;
47212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGTIMEDWAIT;
47222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGSETOPS;
47232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGPENDING;
47242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGPROCMASK;
47252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_BACKTRACE;
47262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT__EXIT;
47272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_MUTEX_LOCK;
47282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_MUTEX_UNLOCK;
47292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETMNTENT;
47302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETMNTENT_R;
47312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATFS;
47322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATFS64;
47332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATVFS;
47342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATVFS64;
47352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_INITGROUPS;
47365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_ETHER_NTOA_ATON;
47375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_ETHER_HOST;
47382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ETHER_R;
47392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SHMCTL;
47402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_RANDOM_R;
47412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_ATTR_GET;
47422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_ATTR_GETINHERITSCHED;
47432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_ATTR_GETAFFINITY_NP;
47445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETPSHARED;
47455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETTYPE;
47465d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
47475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
47485d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETROBUST;
47495d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
47505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
47515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
47525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_CONDATTR_GETPSHARED;
47535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_CONDATTR_GETCLOCK;
47545d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_PTHREAD_BARRIERATTR_GETPSHARED;
47552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TMPNAM;
47562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TMPNAM_R;
47572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TEMPNAM;
47582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_SETNAME_NP;
47592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SINCOS;
47602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_REMQUO;
47612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LGAMMA;
47622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LGAMMA_R;
47635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  INIT_LGAMMAL_R;
47642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_DRAND48_R;
47652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_RAND_R;
47662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETLINE;
47672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ICONV;
47682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TIMES;
47692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TLS_GET_ADDR;
47702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LISTXATTR;
47712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETXATTR;
47722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETRESID;
47732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETIFADDRS;
47742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_IF_INDEXTONAME;
47752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CAPGET;
47762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_AEABI_MEM;
47772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT___BZERO;
47782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FTIME;
47792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_XDR;
47802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TSEARCH;
47812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LIBIO_INTERNALS;
47822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FOPEN;
47832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FOPEN64;
47842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_OPEN_MEMSTREAM;
47852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_OBSTACK;
47862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FFLUSH;
47872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FCLOSE;
47882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_DLOPEN_DLCLOSE;
47892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
4790