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,
14c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// which has to define its own macros:
158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_ENTER
166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//   COMMON_INTERCEPTOR_ENTER_NOIGNORE
178530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_READ_RANGE
188530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_WRITE_RANGE
190586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
2086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines//   COMMON_INTERCEPTOR_DIR_ACQUIRE
21c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_ACQUIRE
22c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_RELEASE
2367f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov//   COMMON_INTERCEPTOR_FD_ACCESS
24c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany//   COMMON_INTERCEPTOR_SET_THREAD_NAME
2586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines//   COMMON_INTERCEPTOR_ON_DLOPEN
2614dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov//   COMMON_INTERCEPTOR_ON_EXIT
275e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov//   COMMON_INTERCEPTOR_MUTEX_LOCK
285e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov//   COMMON_INTERCEPTOR_MUTEX_UNLOCK
2911f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov//   COMMON_INTERCEPTOR_MUTEX_REPAIR
305cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//   COMMON_INTERCEPTOR_HANDLE_RECVMSG
326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines//   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
338530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//===----------------------------------------------------------------------===//
34799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
356afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany#include "interception/interception.h"
362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_addrhashmap.h"
372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_placement_new.h"
3874737d595c4e3638b980bd88b0492247ae4318faAlexey Samsonov#include "sanitizer_platform_interceptors.h"
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_tls_get_addr.h"
40b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany
41996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include <stdarg.h>
42996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
43799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPTOR_HOOKS
44799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)                                     \
45799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  do {                                                                         \
46799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    if (f)                                                                     \
47799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      f(__VA_ARGS__);                                                          \
48799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  } while (false);
49799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)                                  \
50799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  extern "C" {                                                                 \
51799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);  \
52799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  } // extern "C"
53799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
54799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
55799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
56799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
57799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif  // SANITIZER_INTERCEPTOR_HOOKS
58799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_WINDOWS && !defined(va_copy)
60348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#define va_copy(dst, src) ((dst) = (src))
61348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#endif // _WIN32
62348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov
636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_FREEBSD
646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define pthread_setname_np pthread_set_name_np
6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define inet_aton __inet_aton
6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define inet_pton __inet_pton
67cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define iconv __bsd_iconv
686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
700586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
760586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov#endif
770586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov
7867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov#ifndef COMMON_INTERCEPTOR_FD_ACCESS
795cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
805e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#endif
815e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
825e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
835cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
845e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#endif
855e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
865e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
875cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
8867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov#endif
8967f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov
9011f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
9111f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
9211f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov#endif
9311f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov
94c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
95c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
96c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
97c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_FILE_OPEN
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_FILE_CLOSE
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
1246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
1256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
1266d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
127259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar#define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n)       \
128259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
129259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar      common_flags()->strict_string_checks ? (len) + 1 : (n) )
130259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
131259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
132259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
133259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
13486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#ifndef COMMON_INTERCEPTOR_ON_DLOPEN
13586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
13686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
13786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
138cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
139cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
140cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#endif
141cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
142799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#ifndef COMMON_INTERCEPTOR_ACQUIRE
143799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
144799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
145799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
146799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#ifndef COMMON_INTERCEPTOR_RELEASE
147799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
148799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
149799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
150c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
151c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
152c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
153c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
154c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
155c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
156c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
157c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
158c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef SANITIZER_NLDBL_VERSION
159c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
160c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
161c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
162c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
163c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPT_FUNCTION(fn)
164c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
165c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct FileMetadata {
1672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // For open_memstream().
1682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char **addr;
1692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T *size;
1702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
1712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct CommonInterceptorMetadata {
1732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  enum {
1742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CIMT_INVALID = 0,
1752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CIMT_FILE
1762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } type;
1772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  union {
1782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FileMetadata file;
1792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  };
1802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
1812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
1832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic MetadataHashMap *interceptor_metadata_map;
1852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SI_NOT_WINDOWS
1872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
1882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          const FileMetadata &file) {
1892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
1902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK(h.created());
1912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  h->type = CommonInterceptorMetadata::CIMT_FILE;
1922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  h->file = file;
1932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static const FileMetadata *GetInterceptorMetadata(
1962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __sanitizer_FILE *addr) {
1972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            /* remove */ false,
1992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            /* create */ false);
2002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h.exists()) {
2012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CHECK(!h.created());
2022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
2032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return &h->file;
2042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } else {
2052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return 0;
2062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static void DeleteInterceptorMetadata(void *addr) {
2102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
2112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK(h.exists());
2122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SI_NOT_WINDOWS
2142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
215c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRLEN
216c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SIZE_T, strlen, const char *s) {
217c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // Sometimes strlen is called prior to InitializeCommonInterceptors,
218c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // in which case the REAL(strlen) typically used in
219c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
220c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // to handle that.
221c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
222c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return internal_strlen(s);
223c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
224c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
225c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SIZE_T result = REAL(strlen)(s);
226c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_strlen)
227c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
228c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return result;
229c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
230c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
231c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
232c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRLEN
233c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
234c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
235c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRNLEN
236c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
237c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
238c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
239c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SIZE_T length = REAL(strnlen)(s, maxlen);
240c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_strlen)
241c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
242c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return length;
243c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
244c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
245c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
246c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRNLEN
247c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
248c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TEXTDOMAIN
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(char*, textdomain, const char *domainname) {
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
253259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
254259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  char *domain = REAL(textdomain)(domainname);
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (domain) {
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return domain;
2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TEXTDOMAIN
2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
26567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#if SANITIZER_INTERCEPT_STRCMP
26667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovstatic inline int CharCmpX(unsigned char c1, unsigned char c2) {
26767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
26867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
26967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
270799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
271c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                              const char *s1, const char *s2, int result)
272799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
27367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey SamsonovINTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
27467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  void *ctx;
27567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
27667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  unsigned char c1, c2;
27767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  uptr i;
278a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  for (i = 0;; i++) {
27967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c1 = (unsigned char)s1[i];
28067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c2 = (unsigned char)s2[i];
28167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    if (c1 != c2 || c1 == '\0') break;
28267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  }
283259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
284259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
285c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int result = CharCmpX(c1, c2);
286c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
287c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                             s2, result);
288c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return result;
28967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
29067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
291799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
292c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                              const char *s1, const char *s2, uptr n,
293c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                              int result)
294799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
29567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey SamsonovINTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
2966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
2976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    return internal_strncmp(s1, s2, size);
29867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  void *ctx;
29967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
30067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  unsigned char c1 = 0, c2 = 0;
30167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  uptr i;
30267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  for (i = 0; i < size; i++) {
30367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c1 = (unsigned char)s1[i];
30467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    c2 = (unsigned char)s2[i];
30567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov    if (c1 != c2 || c1 == '\0') break;
30667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  }
30767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
30867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
309c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int result = CharCmpX(c1, c2);
310c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
311c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                             s2, size, result);
312c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return result;
31367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov}
31467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
315a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
316a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
31767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#else
31867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#define INIT_STRCMP
31967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#define INIT_STRNCMP
32067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov#endif
32167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov
322be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#if SANITIZER_INTERCEPT_STRCASECMP
323be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
324be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c1_low = ToLower(c1);
325be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c2_low = ToLower(c2);
326be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return c1_low - c2_low;
327be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
328be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
329be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
330be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
331be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
332be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
333be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
334a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  for (i = 0;; i++) {
335be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
336be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
337a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
338be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
339259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
340259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
341be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
342be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
343be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
344be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
345be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
346be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
347be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
348be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
349be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  for (i = 0; i < n; i++) {
350be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
351be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
352a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
353be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
354be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
355be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
356be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
357be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
358be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
359a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
360a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
361be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#else
362be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRCASECMP
363be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRNCASECMP
364be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#endif
365be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
366cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
367cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarstatic inline void StrstrCheck(void *ctx, char *r, const char *s1,
368cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar                               const char *s2) {
369cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    uptr len1 = REAL(strlen)(s1);
370cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    uptr len2 = REAL(strlen)(s2);
371cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
372cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar                                          r ? r - s1 + len2 : len1 + 1);
373cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
374cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
375cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#endif
376cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
377cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRSTR
378cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
379cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
380cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    return internal_strstr(s1, s2);
381cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  void *ctx;
382cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
383cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  char *r = REAL(strstr)(s1, s2);
384cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (common_flags()->intercept_strstr)
385cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    StrstrCheck(ctx, r, s1, s2);
386cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  return r;
387cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
388cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
389cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
390cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#else
391cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRSTR
392cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#endif
393cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
394cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRCASESTR
395cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
396cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  void *ctx;
397cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
398cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  char *r = REAL(strcasestr)(s1, s2);
399cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (common_flags()->intercept_strstr)
400cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    StrstrCheck(ctx, r, s1, s2);
401cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  return r;
402cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
403cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
404cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
405cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#else
406cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRCASESTR
407cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#endif
408cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
409c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRCHR
410c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(char*, strchr, const char *s, int c) {
411c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
412c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
413c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return internal_strchr(s, c);
414c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
415c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *result = REAL(strchr)(s, c);
416c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr len = internal_strlen(s);
417c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr n = result ? result - s + 1 : len + 1;
418c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_strchr)
419c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n);
420c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return result;
421c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
422c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
423c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
424c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRCHR
425c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
426c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
427c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRCHRNUL
428c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(char*, strchrnul, const char *s, int c) {
429c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
430c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
431c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *result = REAL(strchrnul)(s, c);
432c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr len = result - s + 1;
433c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_strchr)
434c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
435c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return result;
436c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
437c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
438c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
439c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRCHRNUL
440c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
441c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
442c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRRCHR
443c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(char*, strrchr, const char *s, int c) {
444c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
445c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
446c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return internal_strrchr(s, c);
447c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
448c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr len = internal_strlen(s);
449c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_strchr)
450c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, len + 1);
451c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return REAL(strrchr)(s, c);
452c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
453c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
454c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
455c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STRRCHR
456c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
457c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
458cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRSPN
459cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
460cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  void *ctx;
461cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
462cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  SIZE_T r = REAL(strspn)(s1, s2);
463cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (common_flags()->intercept_strspn) {
464cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
465cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
466cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  }
467cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  return r;
468cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
469cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
470cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
471cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  void *ctx;
472cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
473cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  SIZE_T r = REAL(strcspn)(s1, s2);
474cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (common_flags()->intercept_strspn) {
475cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
476cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
477cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  }
478cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  return r;
479cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
480cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
481cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRSPN \
482cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(strspn); \
483cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(strcspn);
484cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#else
485cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRSPN
486cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#endif
487cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
488cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STRPBRK
489cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
490cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  void *ctx;
491cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
492cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  char *r = REAL(strpbrk)(s1, s2);
493cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (common_flags()->intercept_strpbrk) {
494cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
495cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
496cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar        r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
497cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  }
498cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  return r;
499cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
500cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
501cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
502cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#else
503cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define INIT_STRPBRK
504cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#endif
505cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
506c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_MEMSET
507c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
508c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
509c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return internal_memset(dst, v, size);
510c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
511c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);
512c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_intrin)
513c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
514c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return REAL(memset)(dst, v, size);
515c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
516c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
517c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
518c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
519c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_MEMSET
520c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
521c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
522c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_MEMMOVE
523c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(void*, memmove, void *dst, const void *src, uptr size) {
524c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
525c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return internal_memmove(dst, src, size);
526c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
527c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);
528c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_intrin) {
529c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
530c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
531c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
532c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return REAL(memmove)(dst, src, size);
533c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
534c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
535c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
536c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
537c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_MEMMOVE
538c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
539c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
540c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_MEMCPY
541c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {
542c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
543c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    // On OS X, calling internal_memcpy here will cause memory corruptions,
544c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    // because memcpy and memmove are actually aliases of the same
545c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    // implementation.  We need to use internal_memmove here.
546c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return internal_memmove(dst, src, size);
547c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
548c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
549c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);
550c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_intrin) {
551c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
552c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
553c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
554c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // N.B.: If we switch this to internal_ we'll have to use internal_memmove
555c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // due to memcpy being an alias of memmove on OS X.
556c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return REAL(memcpy)(dst, src, size);
557c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
558c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
559c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_MEMCPY COMMON_INTERCEPT_FUNCTION(memcpy)
560c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
561c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_MEMCPY
562c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
563c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
564799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_MEMCMP
565799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
566799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarDECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
567c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                              const void *s1, const void *s2, uptr n,
568c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                              int result)
569799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
570799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
571799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
572799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    return internal_memcmp(a1, a2, size);
573799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
574799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
575799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (common_flags()->intercept_memcmp) {
576799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    if (common_flags()->strict_memcmp) {
577799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      // Check the entire regions even if the first bytes of the buffers are
578799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      // different.
579799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
580799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
581799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      // Fallthrough to REAL(memcmp) below.
582799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    } else {
583799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      unsigned char c1 = 0, c2 = 0;
584799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      const unsigned char *s1 = (const unsigned char*)a1;
585799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      const unsigned char *s2 = (const unsigned char*)a2;
586799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      uptr i;
587799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      for (i = 0; i < size; i++) {
588799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar        c1 = s1[i];
589799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar        c2 = s2[i];
590799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar        if (c1 != c2) break;
591799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      }
592799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
593799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
594c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      int r = CharCmpX(c1, c2);
595c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
596c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                 a1, a2, size, r);
597c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      return r;
598799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    }
599799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
600c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int result = REAL(memcmp(a1, a2, size));
601c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
602c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                             a2, size, result);
603c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return result;
604799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
605799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
606799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
607799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
608799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_MEMCMP
609799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
610799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
6112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_MEMCHR
6122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
613799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
614799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    return internal_memchr(s, c, n);
6152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
6162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
6172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(memchr)(s, c, n);
6186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  uptr len = res ? (char *)res - (const char *)s + 1 : n;
6192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
6202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
6212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
6222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
6242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
6252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMCHR
6262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
6272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_MEMRCHR
6292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
6302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
6312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
6322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
6332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(memrchr)(s, c, n);
6342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
6352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
6372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
6382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_MEMRCHR
6392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
6402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
6417cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#if SANITIZER_INTERCEPT_FREXP
6427cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(double, frexp, double x, int *exp) {
6437cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
6447cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
6456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // Assuming frexp() always writes to |exp|.
6467cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
6476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  double res = REAL(frexp)(x, exp);
6487cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
6497cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
6507cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
651a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
652ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#else
653ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXP
654a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_FREXP
655ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov
656ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#if SANITIZER_INTERCEPT_FREXPF_FREXPL
6577cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(float, frexpf, float x, int *exp) {
6587cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
6597cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
6606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
6616a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
662799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
6637cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  float res = REAL(frexpf)(x, exp);
6647cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
6657cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
6667cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
6677cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
6687cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(long double, frexpl, long double x, int *exp) {
6697cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
6707cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
6716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
6726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
673799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
6747cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  long double res = REAL(frexpl)(x, exp);
6757cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
6767cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
6777cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
6787cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
679a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_FREXPF_FREXPL           \
680a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(frexpf); \
681c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
6827cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#else
683ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXPF_FREXPL
684a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
6857cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
686b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SI_NOT_WINDOWS
687b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
688b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        SIZE_T iovlen, SIZE_T maxlen) {
689b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
690b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
691b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
692b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    maxlen -= sz;
693b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  }
694b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
695b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
696b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovstatic void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
697b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                       SIZE_T iovlen, SIZE_T maxlen) {
698b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
699b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
700b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
701b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
702b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    maxlen -= sz;
703b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  }
704b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
705b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
706b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
7078ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#if SANITIZER_INTERCEPT_READ
7086afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
70944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
710996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
71167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
7126a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
7136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
714799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
7156afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(read)(fd, ptr, count);
716a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
717a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
7188530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
7198530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
720a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
721c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
72244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ
7238ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#endif
7248530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
725c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#if SANITIZER_INTERCEPT_PREAD
7266afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
72744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
728996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
72967f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
7306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
7316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
732799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
7336afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
734a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
735a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
7368530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
7378530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
738a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
739c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
74044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD
741c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#endif
7428530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
743b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany#if SANITIZER_INTERCEPT_PREAD64
7446afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
74544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
746996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
74767f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
7486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
7496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
750799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
7516afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
752a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
753a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
7548530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
7558530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
756a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
757c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
75844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64
7591f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko#endif
7608530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
761b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_READV
762b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
763b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        int iovcnt) {
764b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
765b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
76667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
767b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
768b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
769b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
770b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
771b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
772a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
773b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
774b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_READV
775b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
776b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
777b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PREADV
778b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
779b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF_T offset) {
780b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
781b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
78267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
783b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
784b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
785b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
786b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
787b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
788a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
789b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
790b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV
791b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
792b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
793b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PREADV64
794b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
795b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF64_T offset) {
796b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
797b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
79867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
799b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
800b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
801b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
802b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
803b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
804a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
805b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
806b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PREADV64
807b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
808b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
809c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_WRITE
810c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya SerebryanyINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
81144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
812996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
81367f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
814a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
815c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  SSIZE_T res = REAL(write)(fd, ptr, count);
816b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  // FIXME: this check should be _before_ the call to REAL(write), not after
817a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
818c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
819c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
820a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
821153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
82244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE
823153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
824153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
825c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE
826f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
82744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
828f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
82967f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
830a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
831f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
832a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
833c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
834c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
835a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
836153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
83744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE
838153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
839153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
840c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE64
841f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
842f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov            OFF64_T offset) {
84344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
844f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
84567f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
846a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
847f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
848a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
849c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
850c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
851a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
852153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
85344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64
854153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
855153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
856b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_WRITEV
857b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
858b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                        int iovcnt) {
859b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
860b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
86167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
862b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
863b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
864b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
865b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
866b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
867a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
868b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
869b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_WRITEV
870b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
871b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
872b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PWRITEV
873b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
874b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF_T offset) {
875b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
876b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
87767f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
878b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
879b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
880b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
881b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
882b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
883a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
884b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
885b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV
886b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
887b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
888b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#if SANITIZER_INTERCEPT_PWRITEV64
889b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy StepanovINTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
890b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov            OFF64_T offset) {
891b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  void *ctx;
892b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
89367f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
894b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
895b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
896b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
897b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  return res;
898b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov}
899a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
900b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#else
901b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#define INIT_PWRITEV64
902b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov#endif
903b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov
904c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PRCTL
905a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy StepanovINTERCEPTOR(int, prctl, int option, unsigned long arg2,
906a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov            unsigned long arg3,                        // NOLINT
907a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov            unsigned long arg4, unsigned long arg5) {  // NOLINT
90844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
909996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
910c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  static const int PR_SET_NAME = 15;
911c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
912c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (option == PR_SET_NAME) {
913c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    char buff[16];
91444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov    internal_strncpy(buff, (char *)arg2, 15);
915c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    buff[15] = 0;
916996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
917c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  }
918c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
919c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
920a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
921c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
92244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL
923a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_PRCTL
924fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
925fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#if SANITIZER_INTERCEPT_TIME
926fef660506e9e5703fedfee01d614abd4b741c738Evgeniy StepanovINTERCEPTOR(unsigned long, time, unsigned long *t) {
927fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  void *ctx;
928fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
9296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  unsigned long local_t;
9306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  unsigned long res = REAL(time)(&local_t);
93115832c2afc4f04fa558160441d1b01fb3f0ec08bAlexander Potapenko  if (t && res != (unsigned long)-1) {
932fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
9336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    *t = local_t;
934fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  }
935fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  return res;
936fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov}
937a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
938fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#else
939fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#define INIT_TIME
940a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_TIME
941fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
9429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
943cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanovstatic void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
944cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
9450586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov  if (tm->tm_zone) {
9460586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
9470586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov    // can point to shared memory and tsan would report a data race.
9482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
9490586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov                                        REAL(strlen(tm->tm_zone)) + 1);
9500586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov  }
951cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov}
952cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
9539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
9549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
955cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(localtime)(timep);
9569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
9579358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
958cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
9599358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
9609358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
9619358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
962cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
9639358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
9649358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
965cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
9669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
9679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
968cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
9699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
9709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
9719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
972cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
9739358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
9749358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
975cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(gmtime)(timep);
9769358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
9779358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
978cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
9799358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
9809358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
9819358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
982cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
9839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
9849358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
985cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
9869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
9879358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
988cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    unpoison_tm(ctx, res);
9899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
9909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
9919358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
9929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime, unsigned long *timep) {
9939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
9949358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
9956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
9966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
997799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
9989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime)(timep);
9999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
10009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
10019358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
10029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
10039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
10049358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
10059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
10069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
10079358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
10086a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
10096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1010799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
10119358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime_r)(timep, result);
10129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
10139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
10149358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
10159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
10169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
10179358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
1018cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
10199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
10209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
10216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
10226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1023799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
10249358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime)(tm);
10259358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1026cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
10279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
10289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
10299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
10309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
1031cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy StepanovINTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
10329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
10339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
10346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
10356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1036799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
10379358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime_r)(tm, result);
10389358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1039cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
10409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
10419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
10429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
10439358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
10442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
10452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
10462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
10472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
10482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
10492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
10502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
10512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
10522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
10532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
10542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  long res = REAL(mktime)(tm);
10552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != -1) unpoison_tm(ctx, tm);
10562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
10572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1058a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS        \
1059a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(localtime);   \
1060a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(localtime_r); \
1061a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gmtime);      \
1062a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
1063a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ctime);       \
1064a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ctime_r);     \
1065a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(asctime);     \
10662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(asctime_r);   \
10672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(mktime);
10689358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#else
10699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS
1070a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
10719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
1072e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#if SANITIZER_INTERCEPT_STRPTIME
1073e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy StepanovINTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
1074e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  void *ctx;
1075e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
1076e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  if (format)
1077e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
10786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
10796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1080799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1081e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  char *res = REAL(strptime)(s, format, tm);
1082259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
1083259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  if (res && tm) {
1084e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    // Do not call unpoison_tm here, because strptime does not, in fact,
1085e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    // initialize the entire struct tm. For example, tm_zone pointer is left
1086e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov    // uninitialized.
1087259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1088e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  }
1089e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov  return res;
1090e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov}
1091a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
1092e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#else
1093e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#define INIT_STRPTIME
1094e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov#endif
1095e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov
10962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
10972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common_interceptors_format.inc"
1098996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
10992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
11002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
11012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void *ctx;                                                                 \
11022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    va_list ap;                                                                \
11032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    va_start(ap, format);                                                      \
11042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
11052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
11062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    va_end(ap);                                                                \
11072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
11082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
11092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
11102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
11112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
11122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_SCANF
1113996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
1114c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
11154ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
11164ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
11174ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
11184ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list aq;                                                                \
11194ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_copy(aq, ap);                                                           \
11204ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = REAL(vname)(__VA_ARGS__);                                        \
11214ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    if (res > 0)                                                               \
1122c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
11234ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(aq);                                                                \
11244ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
11254ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
1126996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
11274ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vscanf, const char *format, va_list ap)
1128c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
1129996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
11304ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
1131c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
1132996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
11334ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
1134c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
1135996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
11369eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
11374ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
1138c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
1139996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
11404ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
11414ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov            va_list ap)
1142c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
11434ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11444ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
1145c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
11469eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
11474ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11484ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, scanf, const char *format, ...)
11492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
11504ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11514ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
11522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
11534ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11544ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
11552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
11564ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11579eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
11584ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
11592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
11604ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11614ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
11622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
11634ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
11644ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
11652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
11669eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif
1167996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
1168ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#endif
1169996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
1170ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#if SANITIZER_INTERCEPT_SCANF
1171a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCANF                    \
1172a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(scanf);   \
1173a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sscanf);  \
1174a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fscanf);  \
1175a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(vscanf);  \
1176a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(vsscanf); \
1177a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(vfscanf);
1178996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#else
1179996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define INIT_SCANF
1180996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#endif
1181996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
1182ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#if SANITIZER_INTERCEPT_ISOC99_SCANF
1183a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ISOC99_SCANF                      \
1184a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
1185a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
1186a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
1187a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
1188a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1189a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1190ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#else
1191ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#define INIT_ISOC99_SCANF
1192ba15077bf83ebf9a32bfefcd0c9c2f35ab36001dEvgeniy Stepanov#endif
1193745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
11942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_PRINTF
11952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
11962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
11972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;                                                                   \
11982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
11992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_list aq;                                                                  \
12002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_copy(aq, ap);
12012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VPRINTF_INTERCEPTOR_RETURN()                                           \
12032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_end(aq);
12042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
12062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
12072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
12082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf)                                          \
12092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
12102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(__VA_ARGS__);                                        \
12112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
12122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
12132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and
12166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// corrupt its metadata. See
1217799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// https://github.com/google/sanitizers/issues/321.
12182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
12192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
12202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
12212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf) {                                        \
12222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
12232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
12242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(str, __VA_ARGS__);                                   \
12252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res >= 0) {                                                            \
12262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
12272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
12282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
12292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
12302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and
12336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// corrupt its metadata. See
1234799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// https://github.com/google/sanitizers/issues/321.
12352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
12362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
12372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
12382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf) {                                        \
12392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
12402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
12412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(str, size, __VA_ARGS__);                             \
12422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res >= 0) {                                                            \
12432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
12442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
12452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
12462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
12472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and
12506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// corrupt its metadata. See
1251799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// https://github.com/google/sanitizers/issues/321.
12522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
12532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  {                                                                            \
12542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
12552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
12562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (common_flags()->check_printf) {                                        \
12572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      printf_common(ctx, format, aq);                                          \
12582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
12592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(vname)(strp, __VA_ARGS__);                                  \
12602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res >= 0) {                                                            \
12612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
12622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
12632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPRINTF_INTERCEPTOR_RETURN();                                              \
12642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                                                \
12652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
12662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vprintf, const char *format, va_list ap)
12682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
12692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
12712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
12722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
12732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
12752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
12762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
12772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
127886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_INTERCEPT_PRINTF_L
127986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
128086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines            const char *format, va_list ap)
128186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesVSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
128286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
128386277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
128486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines            const char *format, ...)
128586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesFORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
128686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif  // SANITIZER_INTERCEPT_PRINTF_L
128786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
12882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
12892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
12902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
12922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
12932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ISOC99_PRINTF
12952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
12962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
12972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
12982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
12992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            const char *format, va_list ap)
13002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
13012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
13032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
13042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
13052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
13072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            va_list ap)
13082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesVSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
13092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                          ap)
13102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
13122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, printf, const char *format, ...)
13142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
13152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
13172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
13182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
13202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
13212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
13232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
13242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
13262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
13272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ISOC99_PRINTF
13292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_printf, const char *format, ...)
13302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
13312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
13332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            ...)
13342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
13352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
13372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
13382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
13402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            const char *format, ...)
13412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesFORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
13422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                        format)
13432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
13452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_PRINTF
13472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_PRINTF
13492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_PRINTF                     \
13502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(printf);    \
13512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(sprintf);   \
13522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(snprintf);  \
13532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(asprintf);  \
13542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fprintf);   \
13552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vprintf);   \
13562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vsprintf);  \
13572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vsnprintf); \
13582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vasprintf); \
13592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(vfprintf);
13602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
13612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_PRINTF
13622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
13632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
136486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_INTERCEPT_PRINTF_L
136586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INIT_PRINTF_L                     \
136686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
136786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
136886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
136986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INIT_PRINTF_L
137086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
137186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
13722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ISOC99_PRINTF
13732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ISOC99_PRINTF                       \
13742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
13752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
13762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
13772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
13782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
13792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
13802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
13812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
13822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
13832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ISOC99_PRINTF
13842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
13852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
13864e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#if SANITIZER_INTERCEPT_IOCTL
1387745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov#include "sanitizer_common_interceptors_ioctl.inc"
138886277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
138986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // We need a frame pointer, because we call into ioctl_common_[pre|post] which
139086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // can trigger a report and we need to be able to unwind through this
139186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // function.  On Mac in debug mode we might not have a frame pointer, because
139286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // ioctl_common_[pre|post] doesn't get inlined here.
139386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ENABLE_FRAME_POINTER;
139486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
139586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  void *ctx;
139686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  va_list ap;
139786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  va_start(ap, request);
139886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  void *arg = va_arg(ap, void *);
139986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  va_end(ap);
14004e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
14014e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
14024e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  CHECK(ioctl_initialized);
14034e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
14044e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // Note: TSan does not use common flags, and they are zero-initialized.
14054e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // This effectively disables ioctl handling in TSan.
1406a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
14074e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
140886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // Although request is unsigned long, the rest of the interceptor uses it
140986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // as just "unsigned" to save space, because we know that all values fit in
141086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // "unsigned" - they are compile-time constants.
141186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
14124e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  const ioctl_desc *desc = ioctl_lookup(request);
14132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ioctl_desc decoded_desc;
14142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!desc) {
14152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
14162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (!ioctl_decode(request, &decoded_desc))
14172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
14182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    else
14192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      desc = &decoded_desc;
14202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
14214e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
1422a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
14234e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  int res = REAL(ioctl)(d, request, arg);
14244e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // FIXME: some ioctls have different return values for success and failure.
1425a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
14264e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  return res;
14274e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov}
14284ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov#define INIT_IOCTL \
14294ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov  ioctl_init();    \
1430a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ioctl);
14314e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#else
14324e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#define INIT_IOCTL
14334e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#endif
1434745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
14352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
14366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
14376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
14382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
14392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwd) {
14402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
14412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_name)
14422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
14432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_name) + 1);
14442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_passwd)
14452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
14462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_passwd) + 1);
14472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !SANITIZER_ANDROID
14482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_gecos)
14492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
14502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_gecos) + 1);
14512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
14522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_MAC
14532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_class)
14542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
14552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_class) + 1);
14562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
14572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_dir)
14582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
14592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_dir) + 1);
14602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwd->pw_shell)
14612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
14622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(pwd->pw_shell) + 1);
14632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
14642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
14652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void unpoison_group(void *ctx, __sanitizer_group *grp) {
14672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (grp) {
14682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
14692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (grp->gr_name)
14702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
14712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(grp->gr_name) + 1);
14722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (grp->gr_passwd)
14732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
14742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                          REAL(strlen)(grp->gr_passwd) + 1);
14752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    char **p = grp->gr_mem;
14762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    for (; *p; ++p) {
14772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
14782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
14792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
14802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        (p - grp->gr_mem + 1) * sizeof(*p));
14812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
14822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
14832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
14846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines        // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
14856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines        // SANITIZER_INTERCEPT_GETPWENT_R ||
14866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines        // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
14872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1488103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
14892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1490e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1491e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1492e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
14932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(getpwnam)(name);
1494799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_passwd(ctx, res);
1495e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1496e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
14972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1498e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1499e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
15002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(getpwuid)(uid);
1501799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_passwd(ctx, res);
1502e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1503e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
15042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1505103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1506103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1507103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
15082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(getgrnam)(name);
1509799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_group(ctx, res);
1510103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1511103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
15122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1513103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1514103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
15152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(getgrgid)(gid);
1516799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_group(ctx, res);
1517103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1518103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
1519a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS      \
1520a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwnam); \
1521a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwuid); \
1522a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrnam); \
1523a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrgid);
1524e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1525103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS
1526e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1527e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1528103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
15292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
15302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1531e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1532e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1533e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
15346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1536799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1537e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1538e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
15392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_passwd(ctx, *result);
1540e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1541e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
15422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1543e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1544e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
15452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
15462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_passwd **result) {
1547e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1548e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
15496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1551799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1552e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1553e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
15542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_passwd(ctx, *result);
1555e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1556e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
15572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1558e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1559e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
15602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
15612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            char *buf, SIZE_T buflen, __sanitizer_group **result) {
1562103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1563103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1564103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
15656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1567799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1568103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1569103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
15702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_group(ctx, *result);
1571103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1572103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
15732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1574103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1575103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
15762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
15772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_group **result) {
1578103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
1579103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
15806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
15816a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1582799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1583103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1584103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
15852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (result && *result) unpoison_group(ctx, *result);
1586103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1587103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
15882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1589103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
1590103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
1591a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS      \
1592a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1593a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
1594a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
1595a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getgrgid_r);
1596e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1597103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS
1598e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1599e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
16002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETPWENT
16012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
16022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
16042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(getpwent)(dummy);
1605799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_passwd(ctx, res);
16062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
16092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
16112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(getgrent)(dummy);
1612799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_group(ctx, res);;
16132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT                  \
16162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getpwent); \
16172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getgrent);
16182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
16192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT
16202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
16212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
16222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FGETPWENT
16232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
16242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
16262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_passwd *res = REAL(fgetpwent)(fp);
1627799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_passwd(ctx, res);
16282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
16312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
16332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_group *res = REAL(fgetgrent)(fp);
1634799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) unpoison_group(ctx, res);
16352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FGETPWENT                  \
16382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetpwent); \
16392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetgrent);
16402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
16412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FGETPWENT
16422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
16432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
16442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETPWENT_R
16452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
16462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
16472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
16496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1651799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
16522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
16532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
16542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
16552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
16562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
16572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
16582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
16612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
16622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
16646a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1666799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
16672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
16682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
16692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
16702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
16712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
16722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
16732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
16762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_group **pwbufp) {
16772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
16796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1681799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
16822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
16832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
16842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
16852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
16862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
16872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
16882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
16892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
16902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
16912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T buflen, __sanitizer_group **pwbufp) {
16922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
16932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
16946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
16956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1696799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
16972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
16982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!res) {
16992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
17002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
17012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
17022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
17032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
17042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
17052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT_R                   \
17062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
17072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
17082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getgrent_r);  \
17092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
17102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
17112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETPWENT_R
17122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
17132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
17142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_SETPWENT
17152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The only thing these interceptors do is disable any nested interceptors.
17162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// These functions may open nss modules and call uninstrumented functions from
17172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// them, and we don't want things like strlen() to trigger.
17182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, setpwent, int dummy) {
17192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
17202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
17212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(setpwent)(dummy);
17222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
17232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, endpwent, int dummy) {
17242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
17252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
17262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(endpwent)(dummy);
17272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
17282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, setgrent, int dummy) {
17292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
17302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
17312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(setgrent)(dummy);
17322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
17332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, endgrent, int dummy) {
17342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
17352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
17362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(endgrent)(dummy);
17372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
17382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_SETPWENT                  \
17392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(setpwent); \
17402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(endpwent); \
17412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(setgrent); \
17422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(endgrent);
17432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
17442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_SETPWENT
17452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
17462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1747e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_CLOCK_GETTIME
1748e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
1749e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1750e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
17516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
17526a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1753799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1754e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_getres)(clk_id, tp);
17557cdae1683c9c2fcd4473a5862c90c64be3a8c5fdEvgeniy Stepanov  if (!res && tp) {
1756e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1757e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1758e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1759e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1760e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
1761e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1762e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
17636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
17646a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1765799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1766e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_gettime)(clk_id, tp);
1767e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
1768e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1769e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1770e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1771e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1772e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
1773e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1774e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
1775e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
1776e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return REAL(clock_settime)(clk_id, tp);
1777e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1778a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_CLOCK_GETTIME                  \
1779a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(clock_getres);  \
1780a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(clock_gettime); \
1781a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(clock_settime);
1782e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1783e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_CLOCK_GETTIME
1784e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1785e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1786e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETITIMER
1787e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getitimer, int which, void *curr_value) {
1788e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1789e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
17906a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
17916a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1792799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1793e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getitimer)(which, curr_value);
179439d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov  if (!res && curr_value) {
1795e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
1796e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1797e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1798e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1799e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
1800e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
1801e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
180239d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov  if (new_value)
180339d68edd461abb5058a4b96fd16f1741ad89bba7Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
18046a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
18056a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1806799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1807e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(setitimer)(which, new_value, old_value);
1808e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res && old_value) {
1809e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
1810e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1811e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1812e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1813a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETITIMER                  \
1814a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getitimer); \
1815a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(setitimer);
1816e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
1817e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_GETITIMER
1818e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
1819e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
1820a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#if SANITIZER_INTERCEPT_GLOB
1821906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanovstatic void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
1822a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
1823a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  // +1 for NULL pointer at the end.
1824906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if (pglob->gl_pathv)
1825906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(
1826906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
1827a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
1828a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    char *p = pglob->gl_pathv[i];
1829a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
1830a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  }
1831a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
1832a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1833a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanovstatic THREADLOCAL __sanitizer_glob_t *pglob_copy;
18343fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
18353fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void wrapped_gl_closedir(void *dir) {
18362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
18376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  pglob_copy->gl_closedir(dir);
18383fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
18393fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
18403fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void *wrapped_gl_readdir(void *dir) {
18412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
18426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return pglob_copy->gl_readdir(dir);
18433fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
18443fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
18453fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic void *wrapped_gl_opendir(const char *s) {
18462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
18472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
18486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return pglob_copy->gl_opendir(s);
18493fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
18503fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
18513fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic int wrapped_gl_lstat(const char *s, void *st) {
18522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
18532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
18546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return pglob_copy->gl_lstat(s, st);
18553fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
18563fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
18573fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanovstatic int wrapped_gl_stat(const char *s, void *st) {
18582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
18592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
18606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return pglob_copy->gl_stat(s, st);
18613fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov}
18623fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov
1863799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic const __sanitizer_glob_t kGlobCopy = {
1864799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      0,                  0,                   0,
1865799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1866799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
1867799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
1868a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob, const char *pattern, int flags,
1869a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
1870906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov            __sanitizer_glob_t *pglob) {
1871a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
1872a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
1873259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1874799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_glob_t glob_copy;
1875799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
18763fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  if (flags & glob_altdirfunc) {
18773fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
18783fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
18793fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
18803fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
18813fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
18823fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    pglob_copy = &glob_copy;
18833fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  }
1884a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob)(pattern, flags, errfunc, pglob);
18853fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  if (flags & glob_altdirfunc) {
18863fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
18873fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
18883fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
18893fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
18903fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
18913fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  }
18923fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  pglob_copy = 0;
1893906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1894a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
1895a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
1896a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1897a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob64, const char *pattern, int flags,
1898a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
1899906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov            __sanitizer_glob_t *pglob) {
1900a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
1901a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
1902259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1903799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_glob_t glob_copy;
1904799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
190557876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  if (flags & glob_altdirfunc) {
190657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
190757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
190857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
190957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
191057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
191157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    pglob_copy = &glob_copy;
191257876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  }
1913a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
191457876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  if (flags & glob_altdirfunc) {
191557876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
191657876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
191757876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
191857876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
191957876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov    Swap(pglob->gl_stat, glob_copy.gl_stat);
192057876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  }
192157876cfc5357e2a04d17c56ee51e69c593a536beEvgeniy Stepanov  pglob_copy = 0;
1922906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1923a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
1924a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
1925a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GLOB                  \
1926a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(glob); \
1927a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(glob64);
1928906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#else  // SANITIZER_INTERCEPT_GLOB
1929a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#define INIT_GLOB
1930906f2c11e854539f316f737b1f661c0f6bc66fabEvgeniy Stepanov#endif  // SANITIZER_INTERCEPT_GLOB
1931a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
1932897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#if SANITIZER_INTERCEPT_WAIT
19336a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
19346a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
19356a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// details.
19366a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
1937897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1938897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
19396a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1941799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1942897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait)(status);
1943f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
1944897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1945897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1946897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
19476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// On FreeBSD id_t is always 64-bit wide.
19486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
19496d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
19506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines                        int options) {
19516d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
195230e970f769ccf11e61e472c6f8b22f8e866c592fKostya SerebryanyINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
1953a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov                        int options) {
19546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
1955897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1956897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
19576a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1959799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1960897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitid)(idtype, id, infop, options);
1961f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && infop)
1962897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
1963897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1964897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
19656a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
1966897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1967897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
19686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1970799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1971897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitpid)(pid, status, options);
1972f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
1973897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1974897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1975897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
1976897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
1977897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
1978897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
19796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1981799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
1982897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait3)(status, options, rusage);
1983897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
1984a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1985a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1986897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
1987897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
1988897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
19892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_ANDROID
19902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
19912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
19922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
19936a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
19946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
1995799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
19962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__wait4)(pid, status, options, rusage);
19972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != -1) {
19982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
19992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
20002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
20012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
20022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
20032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
20042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
2005897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
2006897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
2007897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
20086a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2010799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2011897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait4)(pid, status, options, rusage);
2012897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
2013a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2014a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2015897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
2016897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
2017897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
20182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
20192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_ANDROID
2020a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WAIT                     \
2021a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(wait);    \
2022a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(waitid);  \
2023a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(waitpid); \
20242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(wait3);
2025897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#else
2026897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#define INIT_WAIT
20272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_WAIT4
2028897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#endif
2029897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
20309530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#if SANITIZER_INTERCEPT_INET
20319530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
20329530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
20339530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
20349530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  uptr sz = __sanitizer_in_addr_sz(af);
20359530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
20369530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
20376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20386a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2039799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
20409530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  char *res = REAL(inet_ntop)(af, src, dst, size);
2041a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
20429530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
20439530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
20449530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
20459530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
20469530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
2047259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
20489530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
20496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2051799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
20529530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  int res = REAL(inet_pton)(af, src, dst);
20539530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (res == 1) {
20549530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af);
20559530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
20569530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  }
20579530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
20589530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
2059a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_INET                       \
2060a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(inet_ntop); \
2061a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(inet_pton);
20629530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#else
20639530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#define INIT_INET
20649530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#endif
20659530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
20669d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#if SANITIZER_INTERCEPT_INET
20679d60087654f89e3452841350d9eca97644edca9dEvgeniy StepanovINTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
20689d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  void *ctx;
20699d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
20709d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
20716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2073799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
20749d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  int res = REAL(inet_aton)(cp, dst);
20759d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  if (res != 0) {
20769d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af_inet);
20779d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
20789d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  }
20799d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov  return res;
20809d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov}
2081a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
20829d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#else
20839d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#define INIT_INET_ATON
20849d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov#endif
20859d60087654f89e3452841350d9eca97644edca9dEvgeniy Stepanov
208656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
208756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy StepanovINTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
208856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  void *ctx;
208956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
20906a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
20916a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2092799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
209356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  int res = REAL(pthread_getschedparam)(thread, policy, param);
209456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  if (res == 0) {
209556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
209656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
209756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  }
209856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  return res;
209956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov}
2100a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM \
2101a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
210256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#else
210356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM
210456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#endif
2105897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
2106447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETADDRINFO
2107447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy StepanovINTERCEPTOR(int, getaddrinfo, char *node, char *service,
2108447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo *hints,
2109447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo **out) {
2110447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  void *ctx;
2111447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
2112447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
2113447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (service)
2114447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
2115447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (hints)
2116447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
21176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2119799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2120447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  int res = REAL(getaddrinfo)(node, service, hints, out);
21213538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov  if (res == 0 && out) {
21223538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
2123447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    struct __sanitizer_addrinfo *p = *out;
2124447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    while (p) {
21253538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2126447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_addr)
2127512c616cacf70ca029a2bf719a482b902f3687cdEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
2128447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_canonname)
2129447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
2130447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov                                       REAL(strlen)(p->ai_canonname) + 1);
2131447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      p = p->ai_next;
2132447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    }
2133447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  }
2134447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  return res;
2135447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
2136a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
2137447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#else
2138447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define INIT_GETADDRINFO
2139447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#endif
2140447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
21419eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETNAMEINFO
21429eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy StepanovINTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
21439eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov            unsigned hostlen, char *serv, unsigned servlen, int flags) {
21449eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  void *ctx;
21459eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
21469eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov                           serv, servlen, flags);
21479eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  // FIXME: consider adding READ_RANGE(sockaddr, salen)
21489eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  // There is padding in in_addr that may make this too noisy
21496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2151799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
21529eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  int res =
21539eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
21549eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  if (res == 0) {
21559eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov    if (host && hostlen)
21569eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
21579eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov    if (serv && servlen)
21589eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
21599eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  }
21609eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov  return res;
21619eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov}
2162a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
21639eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#else
21649eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#define INIT_GETNAMEINFO
21659eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov#endif
21669eedf489075c24b2b1ed9f88bf5102066fffdeb1Evgeniy Stepanov
21679f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKNAME
21689f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy StepanovINTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
21699f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  void *ctx;
21709f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
21719f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
21729f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int addrlen_in = *addrlen;
21736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
21746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2175799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
21769f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int res = REAL(getsockname)(sock_fd, addr, addrlen);
21779f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  if (res == 0) {
21789f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
21799f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  }
21809f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  return res;
21819f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov}
2182a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
21839f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#else
21849f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#define INIT_GETSOCKNAME
21859f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#endif
2186447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
218733b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
21880a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanovstatic void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
21890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
21900a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (h->h_name)
21910a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
21920a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  char **p = h->h_aliases;
21930a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
21940a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
21950a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
21960a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
21970a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
21980a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
21990a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  p = h->h_addr_list;
22000a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
22010a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
22020a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
22030a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
22040a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
22050a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
22060a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
220733b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#endif
22080a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
22090a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME
22100a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
22110a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
22120a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
22130a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
22140a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
22150a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
22160a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
22170a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
22180a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
22190a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            int type) {
22200a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
22210a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
22220a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
22230a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
22240a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
22250a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
22260a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
22270a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
22281d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry VyukovINTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
22290a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
22301d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
22311d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
22320a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
22330a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
22340a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
22350a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
22360a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
22370a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
22380a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
22390a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
22400a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
22410a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
22420a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
2243a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETHOSTBYNAME                  \
2244a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostent);    \
2245a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2246a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyname); \
2247a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyname2);
22480a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
22490a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME
22500a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
22510a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
22520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
22536a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
22546a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
22556a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            int *h_errnop) {
22566a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  void *ctx;
22576a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
22586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines                           h_errnop);
22596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
22606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2261799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
22626a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
22636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  if (result) {
22646a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
22656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
22666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  }
22676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  if (h_errnop)
22686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
22696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return res;
22706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
22716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
22726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
22736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTBYNAME_R
22746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
22756a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
22766a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_GETHOSTENT_R
22770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
22780a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
22790a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
22800a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
22810a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           h_errnop);
22826a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
22836a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2284799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
22850a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
22862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) {
22872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
22882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
22890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
22902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h_errnop)
22912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
22920a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
22930a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
22946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTENT_R                  \
22956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(gethostent_r);
22966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
22976a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTENT_R
22986a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
22990a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
23006a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
23010a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
23020a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
23030a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
23040a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
23050a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
23060a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           buflen, result, h_errnop);
23070a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
23086a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2310799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
23110a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
23120a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                                  h_errnop);
23132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) {
23142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
23152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
23160a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
23172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h_errnop)
23182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
23190a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
23200a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
23216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTBYADDR_R                  \
23226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
23236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
23246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTBYADDR_R
23256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
23260a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
23276a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
23280a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyname2_r, char *name, int af,
23290a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
23300a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
23310a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
23320a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
23330a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           result, h_errnop);
23346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2336799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
23370a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res =
23380a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
23392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (result) {
23402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
23412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res == 0 && *result) write_hostent(ctx, *result);
23420a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
23432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (h_errnop)
23442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
23450a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
23460a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
23476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTBYNAME2_R                  \
2348a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
23490a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
23506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETHOSTBYNAME2_R
23510a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
23520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
2353f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKOPT
2354f32be42523a199674ea665a499db131591e64e08Evgeniy StepanovINTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
2355f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov            int *optlen) {
2356f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  void *ctx;
2357f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
2358f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov                           optlen);
2359f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
23606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
23616a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2362799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2363f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
2364f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (res == 0)
2365f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
2366f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  return res;
2367f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov}
2368a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
2369f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#else
2370f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#define INIT_GETSOCKOPT
2371f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#endif
2372f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov
23739d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT
23749d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
23759d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
23769d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
23776a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  unsigned addrlen0 = 0;
23789d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
23799d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
23809d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
23819d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
23829d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept)(fd, addr, addrlen);
23839d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
2384a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
23859d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
23869d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
23879d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
23889d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
23899d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
2390a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
23919d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
23929d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT
23939d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
23949d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
23959d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT4
23969d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
23979d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
23989d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
23996a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  unsigned addrlen0 = 0;
24009d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
24019d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
24029d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
24039d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
24046a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24056a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2406799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
24079d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
24089d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
2409a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
24109d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
24119d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
24129d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
24139d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
24149d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
2415a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
24169d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
24179d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT4
24189d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
24199d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
2420c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#if SANITIZER_INTERCEPT_MODF
2421c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(double, modf, double x, double *iptr) {
2422c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
2423c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
24246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2426799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2427c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  double res = REAL(modf)(x, iptr);
2428c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
2429c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2430c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
2431c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
2432c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
2433c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(float, modff, float x, float *iptr) {
2434c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
2435c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
24366a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2438799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2439c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  float res = REAL(modff)(x, iptr);
2440c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
2441c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2442c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
2443c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
2444c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
2445c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2446c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
2447c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
24486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2450799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2451c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  long double res = REAL(modfl)(x, iptr);
2452c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
2453c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2454c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
2455c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
2456c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
2457a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_MODF                   \
2458a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(modf);  \
2459a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(modff); \
2460c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
2461c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#else
2462c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#define INIT_MODF
2463c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#endif
2464c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov
24659666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#if SANITIZER_INTERCEPT_RECVMSG
2466eb7c24bb2e6fd20410d34006759caf76852d0600Evgeniy Stepanovstatic void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2467eb7c24bb2e6fd20410d34006759caf76852d0600Evgeniy Stepanov                         SSIZE_T maxlen) {
24689666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2469ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov  if (msg->msg_name && msg->msg_namelen)
2470ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2471ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov  if (msg->msg_iov && msg->msg_iovlen)
2472b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2473b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
2474b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2475ab8bf09f11d76af6bf9bf6b573f36cb29aa3e557Evgeniy Stepanov  if (msg->msg_control && msg->msg_controllen)
24769666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
24779666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
24789666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
24799666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy StepanovINTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
24809666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov            int flags) {
24819666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  void *ctx;
24829666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
24836a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
24846a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2485799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
24869666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
24879666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (res >= 0) {
24889666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
24892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (msg) {
24902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      write_msghdr(ctx, msg, res);
24912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
24922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
24939666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  }
24949666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  return res;
24959666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
2496a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
24979666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#else
24989666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#define INIT_RECVMSG
24999666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#endif
25009666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
2501c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_SENDMSG
2502c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void read_msghdr_control(void *ctx, void *control, uptr controllen) {
2503c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  const unsigned kCmsgDataOffset =
2504c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
2505c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2506c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *p = (char *)control;
2507c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *const control_end = p + controllen;
2508c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  while (true) {
2509c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
2510c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
2511c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
2512c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2513c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
2514c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2515c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
2516c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                  sizeof(cmsg->cmsg_level));
2517c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
2518c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                  sizeof(cmsg->cmsg_type));
2519c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2520c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (cmsg->cmsg_len > kCmsgDataOffset) {
2521c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      char *data = p + kCmsgDataOffset;
2522c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
2523c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
2524c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    }
2525c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2526c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
2527c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
2528c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
2529c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2530c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2531c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                        SSIZE_T maxlen) {
2532c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define R(f) \
2533c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
2534c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(name);
2535c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(namelen);
2536c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(iov);
2537c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(iovlen);
2538c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(control);
2539c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(controllen);
2540c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  R(flags);
2541c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#undef R
2542c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (msg->msg_name && msg->msg_namelen)
2543c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2544c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (msg->msg_iov && msg->msg_iovlen)
2545c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
2546c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                  sizeof(*msg->msg_iov) * msg->msg_iovlen);
2547c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2548c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (msg->msg_control && msg->msg_controllen)
2549c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
2550c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
2551c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2552c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
2553c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar            int flags) {
2554c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
2555c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
2556c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (fd >= 0) {
2557c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
2558c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
2559c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
2560c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
2561c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_send && res >= 0 && msg)
2562c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    read_msghdr(ctx, msg, res);
2563c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
2564c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
2565c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
2566c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
2567c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_SENDMSG
2568c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
2569c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
2570bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPEERNAME
2571bc33e138d82759074f8333239f96506027731e20Evgeniy StepanovINTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
2572bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  void *ctx;
2573bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
2574bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  unsigned addr_sz;
2575bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (addrlen) addr_sz = *addrlen;
25766a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
25776a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2578799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2579bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  int res = REAL(getpeername)(sockfd, addr, addrlen);
2580bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (!res && addr && addrlen)
2581bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2582bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  return res;
2583bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov}
2584a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
2585bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#else
2586bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#define INIT_GETPEERNAME
2587bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#endif
2588bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov
2589359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#if SANITIZER_INTERCEPT_SYSINFO
2590359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy StepanovINTERCEPTOR(int, sysinfo, void *info) {
2591359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  void *ctx;
25926a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
25936a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2594799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2595359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
2596359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  int res = REAL(sysinfo)(info);
2597359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  if (!res && info)
2598359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
2599359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov  return res;
2600359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov}
2601a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
2602359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#else
2603359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#define INIT_SYSINFO
2604359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov#endif
2605359d7fc7daf099ab8ef9a860564542d2581544aaEvgeniy Stepanov
2606b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#if SANITIZER_INTERCEPT_READDIR
260786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
260886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  void *ctx;
260986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
261086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
261186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  __sanitizer_dirent *res = REAL(opendir)(path);
2612799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res)
261386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
261486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  return res;
261586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
261686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
2617a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy StepanovINTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
2618b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2619b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
26206a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
26216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2622799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2623a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov  __sanitizer_dirent *res = REAL(readdir)(dirp);
2624a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2625b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2626b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2627b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
262852d08d8412bfa4ccfa38384d781b51e8774807a7Alexey SamsonovINTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
262952d08d8412bfa4ccfa38384d781b51e8774807a7Alexey Samsonov            __sanitizer_dirent **result) {
2630b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2631b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
26326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
26336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2634799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2635b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  int res = REAL(readdir_r)(dirp, entry, result);
2636b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (!res) {
26375a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
26385a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    if (*result)
26395a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2640b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  }
2641b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2642b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2643b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2644a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READDIR                  \
264586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPT_FUNCTION(opendir); \
2646a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir); \
2647a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir_r);
2648b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#else
2649b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR
2650b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#endif
2651b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2652b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#if SANITIZER_INTERCEPT_READDIR64
2653a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy StepanovINTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
2654b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2655b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
26566a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
26576a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2658799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2659a0379b5566f7c04536a313e40c450c6aef4b3ec5Evgeniy Stepanov  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
2660a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2661b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2662b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2663b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
266452d08d8412bfa4ccfa38384d781b51e8774807a7Alexey SamsonovINTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
266552d08d8412bfa4ccfa38384d781b51e8774807a7Alexey Samsonov            __sanitizer_dirent64 **result) {
2666b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  void *ctx;
2667b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
26686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
26696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2670799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2671b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  int res = REAL(readdir64_r)(dirp, entry, result);
2672b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  if (!res) {
26735a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
26745a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth    if (*result)
26755a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2676b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  }
2677b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov  return res;
2678b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov}
2679a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_READDIR64                  \
2680a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir64); \
2681a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(readdir64_r);
2682b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#else
2683b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#define INIT_READDIR64
2684b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov#endif
2685b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2686341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTRACE
2687341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy StepanovINTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
2688341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  void *ctx;
2689341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
2690799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_iovec local_iovec;
2691341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
2692341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (data) {
2693341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (request == ptrace_setregs)
2694341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
2695341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setfpregs)
2696341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2697341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setfpxregs)
2698341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2699799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    else if (request == ptrace_setvfpregs)
2700799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
2701341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_setsiginfo)
2702341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
2703799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    // Some kernel might zero the iovec::iov_base in case of invalid
2704799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    // write access.  In this case copy the invalid address for further
2705799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    // inspection.
2706799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    else if (request == ptrace_setregset || request == ptrace_getregset) {
2707799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2708799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
2709799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      local_iovec = *iovec;
2710799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      if (request == ptrace_setregset)
2711799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar        COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
2712341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    }
2713341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
2714341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
27156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
27166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2717799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2718341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  uptr res = REAL(ptrace)(request, pid, addr, data);
2719341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
2720341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (!res && data) {
27216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    // Note that PEEK* requests assign different meaning to the return value.
2722341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    // This function does not handle them (nor does it need to).
2723341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (request == ptrace_getregs)
2724341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
2725341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getfpregs)
2726341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2727341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getfpxregs)
2728341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2729799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    else if (request == ptrace_getvfpregs)
2730799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
2731341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getsiginfo)
2732341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
27336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    else if (request == ptrace_geteventmsg)
27346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
2735341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    else if (request == ptrace_getregset) {
2736799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2737799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
2738799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
2739799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                                     local_iovec.iov_len);
2740341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    }
2741341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
2742341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  return res;
2743341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov}
2744341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
2745a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
2746341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#else
2747341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define INIT_PTRACE
2748341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#endif
2749341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
27503cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#if SANITIZER_INTERCEPT_SETLOCALE
27513cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy StepanovINTERCEPTOR(char *, setlocale, int category, char *locale) {
27523cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  void *ctx;
27533cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
27543cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  if (locale)
27553cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
2756801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(setlocale)(category, locale);
2757a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
27583cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov  return res;
27593cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov}
27603cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov
2761a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
27623cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#else
27633cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#define INIT_SETLOCALE
27643cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov#endif
27653cae6040ebb4ce14123b8ba000b79b4383dbd48aEvgeniy Stepanov
2766801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETCWD
2767801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
2768801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  void *ctx;
2769801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
27706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
27716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2772799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2773801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  char *res = REAL(getcwd)(buf, size);
2774a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2775801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
2776801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
2777a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
2778801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#else
2779801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GETCWD
2780801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#endif
2781801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
2782801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
27831d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry VyukovINTERCEPTOR(char *, get_current_dir_name, int fake) {
2784801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  void *ctx;
27851d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
27866a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
27876a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2788799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
27891d02bea922d7b47686de5a5ca81a6bcc8905b6f8Dmitry Vyukov  char *res = REAL(get_current_dir_name)(fake);
2790a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2791801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
2792801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
2793801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
2794a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GET_CURRENT_DIR_NAME \
2795a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
2796801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#else
2797801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#define INIT_GET_CURRENT_DIR_NAME
2798801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov#endif
2799b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4Evgeniy Stepanov
2800259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga NainarUNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
2801259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK(endptr);
2802259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  if (nptr == *endptr) {
2803259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    // No digits were found at strtol call, we need to find out the last
2804259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    // symbol accessed by strtoll on our own.
2805259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    // We get this symbol by skipping leading blanks and optional +/- sign.
2806259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    while (IsSpace(*nptr)) nptr++;
2807259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    if (*nptr == '+' || *nptr == '-') nptr++;
2808259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    *endptr = const_cast<char *>(nptr);
2809259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  }
2810259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK(*endptr >= nptr);
2811259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar}
2812259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
2813259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga NainarUNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
2814259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar                             char **endptr, char *real_endptr, int base) {
2815799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (endptr) {
2816259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    *endptr = real_endptr;
2817259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2818259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  }
2819259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  // If base has unsupported value, strtol can exit with EINVAL
2820259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  // without reading any characters. So do additional checks only
2821259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  // if base is valid.
2822259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
2823259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  if (is_valid_base) {
2824259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    FixRealStrtolEndptr(nptr, &real_endptr);
2825259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  }
2826259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
2827259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar                                 (real_endptr - nptr) + 1 : 0);
2828259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar}
2829259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
2830259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
2831ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_STRTOIMAX
2832ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
2833ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2834ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
28356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28366a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2837799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2838259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  char *real_endptr;
2839259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
2840259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2841ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2842ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2843ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2844ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
2845ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2846ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
28476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2849799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2850259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  char *real_endptr;
2851259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
2852259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2853ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2854ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2855ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2856a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRTOIMAX                  \
2857a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(strtoimax); \
2858a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(strtoumax);
2859ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2860ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_STRTOIMAX
2861ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2862ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2863ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_MBSTOWCS
2864ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
2865ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2866ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
28676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2869799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2870ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(mbstowcs)(dest, src, len);
2871098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest) {
2872e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + (res < len);
2873e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2874e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2875ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2876ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2877ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2878ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
2879ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            void *ps) {
2880ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2881ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
2882098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2883098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
28846a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
28856a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2886799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
28875a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
2888098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T)(-1) && dest && src) {
2889098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    // This function, and several others, may or may not write the terminating
2890098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    // \0 character. They write it iff they clear *src.
2891098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2892e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2893e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2894ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2895ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2896ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2897a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_MBSTOWCS                  \
2898a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(mbstowcs); \
2899a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
2900ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2901ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSTOWCS
2902ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2903ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2904ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_MBSNRTOWCS
2905ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
2906ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            SIZE_T len, void *ps) {
2907ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2908ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
2909098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) {
2910ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2911098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2912ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  }
2913098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
29146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2916799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2917ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
2918098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T)(-1) && dest && src) {
2919098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2920e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2921e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2922ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2923ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2924ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2925a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
2926ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2927ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_MBSNRTOWCS
2928ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2929ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2930ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_WCSTOMBS
2931ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
2932ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2933ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
29346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2936799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2937ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(wcstombs)(dest, src, len);
2938098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest) {
2939e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    SIZE_T write_cnt = res + (res < len);
2940e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2941e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2942ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2943ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2944ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2945ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
2946ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            void *ps) {
2947ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2948ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
2949098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2950098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
29516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29526a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2953799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
29545a482cd54a75bf821fb8c61f2fe4e84ae9efb714Chandler Carruth  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
2955098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (res != (SIZE_T) - 1 && dest && src) {
2956098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2957e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2958e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2959ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2960ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2961ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2962a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WCSTOMBS                  \
2963a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(wcstombs); \
2964a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(wcsrtombs);
2965ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2966ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSTOMBS
2967ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2968ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2969ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#if SANITIZER_INTERCEPT_WCSNRTOMBS
2970ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
2971ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov            SIZE_T len, void *ps) {
2972ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  void *ctx;
2973ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
2974098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (src) {
2975ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2976098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2977ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  }
2978098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
29796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
29806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
2981799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
2982ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
2983799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res != ((SIZE_T)-1) && dest && src) {
2984098c58fc48a934dd51df31e92efa236a5e1916e2Alexey Samsonov    SIZE_T write_cnt = res + !*src;
2985e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2986e43d2108ec7622afb34b8281005a12fcdb26d6faAlexey Samsonov  }
2987ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return res;
2988ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
2989ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2990a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
2991ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#else
2992ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#define INIT_WCSNRTOMBS
2993ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov#endif
2994ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
2995799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
2996799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_WCRTOMB
2997799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
2998799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
2999799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
3000799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3001799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // FIXME: under ASan the call below may write to freed memory and corrupt
3002799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // its metadata. See
3003799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3004799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  SIZE_T res = REAL(wcrtomb)(dest, src, ps);
3005799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res != ((SIZE_T)-1) && dest) {
3006799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    SIZE_T write_cnt = res;
3007799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3008799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
3009799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
3010799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
3011799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
3012799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
3013799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
3014799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_WCRTOMB
3015799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
3016799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
3017ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#if SANITIZER_INTERCEPT_TCGETATTR
3018ea72768894e32f367607c2142a7dfab603310da0Evgeniy StepanovINTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
3019ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  void *ctx;
3020ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
30216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3023799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3024ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  int res = REAL(tcgetattr)(fd, termios_p);
3025ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  if (!res && termios_p)
3026ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
3027ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov  return res;
3028ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov}
3029ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
3030a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
3031ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#else
3032ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#define INIT_TCGETATTR
3033ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov#endif
3034ea72768894e32f367607c2142a7dfab603310da0Evgeniy Stepanov
303512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#if SANITIZER_INTERCEPT_REALPATH
303612eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovINTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
303712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  void *ctx;
303812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
303912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
304012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
304112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
304212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // version of a versioned symbol. For realpath(), this gives us something
304312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // (called __old_realpath) that does not handle NULL in the second argument.
304412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  // Handle it as part of the interceptor.
3045799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  char *allocated_path = nullptr;
304612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (!resolved_path)
304712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
304812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
304912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *res = REAL(realpath)(path, resolved_path);
3050a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (allocated_path && !res) WRAP(free)(allocated_path);
305112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
305212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  return res;
305312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov}
3054a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
305512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#else
305612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_REALPATH
305712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#endif
305812eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
305912eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
306012eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovINTERCEPTOR(char *, canonicalize_file_name, const char *path) {
306112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  void *ctx;
306212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
306312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
306412eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  char *res = REAL(canonicalize_file_name)(path);
306512eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
306612eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov  return res;
306712eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov}
3068a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_CANONICALIZE_FILE_NAME \
3069a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
307012eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#else
307112eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#define INIT_CANONICALIZE_FILE_NAME
307212eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov#endif
307312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov
30745ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#if SANITIZER_INTERCEPT_CONFSTR
30755ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy StepanovINTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
30765ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  void *ctx;
30775ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
30786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3080799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
30815ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  SIZE_T res = REAL(confstr)(name, buf, len);
30825ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  if (buf && res)
30835ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
30845ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov  return res;
30855ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov}
3086a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
30875ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#else
30885ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#define INIT_CONFSTR
30895ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov#endif
30905ec19bc74b52fd962f079086c2fa615d6d3f0864Evgeniy Stepanov
309184ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
309284ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy StepanovINTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
309384ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  void *ctx;
309484ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
30956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
30966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3097799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
309884ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
3099a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
310084ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov  return res;
310184ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov}
3102a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
310384ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#else
310484ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#define INIT_SCHED_GETAFFINITY
310584ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov#endif
310684ba74c10ad43c6dff77302f87efae72623d2a1bEvgeniy Stepanov
310786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_INTERCEPT_SCHED_GETPARAM
310886277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, sched_getparam, int pid, void *param) {
310986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  void *ctx;
311086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
311186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  int res = REAL(sched_getparam)(pid, param);
311286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
311386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  return res;
311486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
311586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
311686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
311786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INIT_SCHED_GETPARAM
311886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
311986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
31201204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#if SANITIZER_INTERCEPT_STRERROR
31211204979804868728edb6edfe3ae018465191a85cEvgeniy StepanovINTERCEPTOR(char *, strerror, int errnum) {
31221204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  void *ctx;
31231204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
31241204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  char *res = REAL(strerror)(errnum);
31252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
31261204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  return res;
31271204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov}
3128a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
31291204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#else
31301204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#define INIT_STRERROR
31311204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#endif
31321204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov
31331204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#if SANITIZER_INTERCEPT_STRERROR_R
31341204979804868728edb6edfe3ae018465191a85cEvgeniy StepanovINTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
31351204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  void *ctx;
31361204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
31376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31386a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3139799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
31401204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  char *res = REAL(strerror_r)(errnum, buf, buflen);
31411204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  // There are 2 versions of strerror_r:
31421204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //  * POSIX version returns 0 on success, negative error code on failure,
31431204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //    writes message to buf.
31441204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //  * GNU version returns message pointer, which points to either buf or some
31451204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  //    static storage.
3146d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov  SIZE_T posix_res = (SIZE_T)res;
3147d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov  if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
31481204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    // POSIX version. Spec is not clear on whether buf is NULL-terminated.
3149d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov    // At least on OSX, buf contents are valid even when the call fails.
31501204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    SIZE_T sz = internal_strnlen(buf, buflen);
31511204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    if (sz < buflen) ++sz;
31521204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3153d9a5e243254764ab1024320ef34bc2a87180f4c5Evgeniy Stepanov  } else {
31541204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    // GNU version.
31551204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
31561204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  }
31571204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov  return res;
31581204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov}
3159a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
31601204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#else
31611204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#define INIT_STRERROR_R
31621204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov#endif
31631204979804868728edb6edfe3ae018465191a85cEvgeniy Stepanov
31642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_XPG_STRERROR_R
31652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
31662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
31672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
31686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
31696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3170799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
31712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
31722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // This version always returns a null-terminated string.
31732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (buf && buflen)
31742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
31752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
31762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
31772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
31782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
31792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XPG_STRERROR_R
31802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
31812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3182224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANDIR
3183224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
3184224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
3185224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                const struct __sanitizer_dirent **);
3186224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3187224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir_filter_f scandir_filter;
3188224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir_compar_f scandir_compar;
3189224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3190224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
31912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
31922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
31936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return scandir_filter(dir);
3194224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
3195224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3196224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
3197224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                  const struct __sanitizer_dirent **b) {
31982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
31992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
32002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
32012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
32022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
32036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return scandir_compar(a, b);
3204224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
3205224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3206224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy StepanovINTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
3207224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov            scandir_filter_f filter, scandir_compar_f compar) {
3208224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  void *ctx;
3209224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
3210224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3211224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir_filter = filter;
3212224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir_compar = compar;
32136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3215799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3216799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(scandir)(dirp, namelist,
3217799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                          filter ? wrapped_scandir_filter : nullptr,
3218799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                          compar ? wrapped_scandir_compar : nullptr);
3219799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  scandir_filter = nullptr;
3220799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  scandir_compar = nullptr;
3221224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (namelist && res > 0) {
3222224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3223224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3224224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    for (int i = 0; i < res; ++i)
3225224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3226224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                     (*namelist)[i]->d_reclen);
3227224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  }
3228224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  return res;
3229224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
3230a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
3231224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#else
3232224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#define INIT_SCANDIR
3233224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#endif
3234224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3235224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANDIR64
3236224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
3237224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovtypedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
3238224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                  const struct __sanitizer_dirent64 **);
3239224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3240224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir64_filter_f scandir64_filter;
3241224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic THREADLOCAL scandir64_compar_f scandir64_compar;
3242224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3243224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
32442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
32452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
32466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return scandir64_filter(dir);
3247224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
3248224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3249224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanovstatic int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
3250224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                    const struct __sanitizer_dirent64 **b) {
32512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
32522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
32532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
32542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
32552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
32566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return scandir64_compar(a, b);
3257224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
3258224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3259224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy StepanovINTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
3260224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov            scandir64_filter_f filter, scandir64_compar_f compar) {
3261224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  void *ctx;
3262224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
3263224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3264224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir64_filter = filter;
3265224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  scandir64_compar = compar;
32666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3268799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3269224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  int res =
3270799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      REAL(scandir64)(dirp, namelist,
3271799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                      filter ? wrapped_scandir64_filter : nullptr,
3272799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                      compar ? wrapped_scandir64_compar : nullptr);
3273799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  scandir64_filter = nullptr;
3274799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  scandir64_compar = nullptr;
3275224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  if (namelist && res > 0) {
3276224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3277224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3278224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov    for (int i = 0; i < res; ++i)
3279224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3280224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov                                     (*namelist)[i]->d_reclen);
3281224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  }
3282224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov  return res;
3283224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov}
3284a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
3285224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#else
3286224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#define INIT_SCANDIR64
3287224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov#endif
3288224226c18c1ee1f9d187de86bf1c5023cb153c71Evgeniy Stepanov
3289edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETGROUPS
3290edff34b5175c6759685da82077c99ee2be017667Evgeniy StepanovINTERCEPTOR(int, getgroups, int size, u32 *lst) {
3291edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  void *ctx;
3292edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
32936a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
32946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3295799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3296edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  int res = REAL(getgroups)(size, lst);
3297a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
3298edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov  return res;
3299edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov}
3300a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
3301edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#else
3302edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#define INIT_GETGROUPS
3303edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov#endif
3304edff34b5175c6759685da82077c99ee2be017667Evgeniy Stepanov
3305e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#if SANITIZER_INTERCEPT_POLL
3306e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanovstatic void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
3307e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov                        __sanitizer_nfds_t nfds) {
3308e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  for (unsigned i = 0; i < nfds; ++i) {
3309e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
3310e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
3311e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  }
3312e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
3313e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
3314e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanovstatic void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
3315e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov                         __sanitizer_nfds_t nfds) {
3316e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  for (unsigned i = 0; i < nfds; ++i)
33175bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
33185bd2174c1385ec10b172cc9a32bc33b1967d60b5Alexey Samsonov                                   sizeof(fds[i].revents));
3319e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
3320e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
3321e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy StepanovINTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3322e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov            int timeout) {
3323e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  void *ctx;
3324e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
3325e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) read_pollfd(ctx, fds, nfds);
3326e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
3327e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) write_pollfd(ctx, fds, nfds);
3328e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  return res;
3329e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
3330a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
3331e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#else
3332e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define INIT_POLL
3333e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#endif
3334e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
3335e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#if SANITIZER_INTERCEPT_PPOLL
3336e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy StepanovINTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3337b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
3338e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  void *ctx;
3339e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
3340e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) read_pollfd(ctx, fds, nfds);
3341e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (timeout_ts)
3342e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
3343b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov  // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
3344e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  int res =
3345e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
3346e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  if (fds && nfds) write_pollfd(ctx, fds, nfds);
3347e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov  return res;
3348e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov}
3349a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
3350e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#else
3351e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define INIT_PPOLL
3352e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#endif
3353e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov
3354c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#if SANITIZER_INTERCEPT_WORDEXP
3355c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy StepanovINTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
3356c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  void *ctx;
3357c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
3358c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
33596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
33606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3361799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3362c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  int res = REAL(wordexp)(s, p, flags);
3363c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  if (!res && p) {
3364c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
3365c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    if (p->we_wordc)
3366c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
3367c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov                                     sizeof(*p->we_wordv) * p->we_wordc);
3368c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    for (uptr i = 0; i < p->we_wordc; ++i) {
3369c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov      char *w = p->we_wordv[i];
3370c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
3371c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov    }
3372c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  }
3373c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov  return res;
3374c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov}
3375a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
3376c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#else
3377c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#define INIT_WORDEXP
3378c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov#endif
3379c5a385500057ba60c71abbb1d1cc0ee3773be792Evgeniy Stepanov
33809a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGWAIT
33819a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
33829a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
33839a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
33849a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
33856a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
33866a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3387799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
33889a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigwait)(set, sig);
33899a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
33909a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
33919a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
3392a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
33939a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
33949a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGWAIT
33959a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
33969a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
33979a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGWAITINFO
33989a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
33999a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
34009a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
34019a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
34026a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34036a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3404799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
34059a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigwaitinfo)(set, info);
34069a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
34079a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
34089a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
3409a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
34109a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
34119a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGWAITINFO
34129a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
34139a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
34149a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
34159a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
34169a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov            void *timeout) {
34179a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
34189a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
34199a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
34209a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
34216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3423799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
34249a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigtimedwait)(set, info, timeout);
34259a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
34269a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
34279a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
3428a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
34299a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
34309a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGTIMEDWAIT
34319a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
34329a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
34339a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGSETOPS
34349a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
34359a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
34369a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
34376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34386a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3439799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
34409a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigemptyset)(set);
34419a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
34429a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
34439a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
34449a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
34459a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
34469a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
34479a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
34486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3450799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
34519a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigfillset)(set);
34529a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
34539a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
34549a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
3455a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGSETOPS                    \
3456a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sigemptyset); \
3457a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sigfillset);
34589a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
34599a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGSETOPS
34609a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
34619a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
34629a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGPENDING
34639a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
34649a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
34659a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
34666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3468799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
34699a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigpending)(set);
34709a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
34719a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
34729a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
3473a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
34749a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
34759a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGPENDING
34769a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
34779a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
34789a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#if SANITIZER_INTERCEPT_SIGPROCMASK
34799a949a8909f652b28e9084de785c848743139fd5Evgeniy StepanovINTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
34809a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov            __sanitizer_sigset_t *oldset) {
34819a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  void *ctx;
34829a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
34839a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
34846a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
34856a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3486799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
34879a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  int res = REAL(sigprocmask)(how, set, oldset);
34889a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  if (!res && oldset)
34899a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
34909a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov  return res;
34919a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov}
3492a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
34939a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#else
34949a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#define INIT_SIGPROCMASK
34959a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov#endif
34969a949a8909f652b28e9084de785c848743139fd5Evgeniy Stepanov
34971394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#if SANITIZER_INTERCEPT_BACKTRACE
34981394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy StepanovINTERCEPTOR(int, backtrace, void **buffer, int size) {
34991394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  void *ctx;
35001394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
35016a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
35026a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3503799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
35041394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  int res = REAL(backtrace)(buffer, size);
35051394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  if (res && buffer)
35061394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
35071394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  return res;
35081394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov}
35091394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov
35101394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy StepanovINTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
35111394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  void *ctx;
35121394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
35131394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  if (buffer && size)
35141394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
35156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
35166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3517799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3518a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  char **res = REAL(backtrace_symbols)(buffer, size);
35191394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  if (res && size) {
35201394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
35211394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov    for (int i = 0; i < size; ++i)
35221394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
35231394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  }
35241394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov  return res;
35251394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov}
3526a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_BACKTRACE                  \
3527a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(backtrace); \
3528a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
35291394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#else
35301394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#define INIT_BACKTRACE
35311394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov#endif
35321394be15dfc8a8fc0586d5f5e4302c2c8e917148Evgeniy Stepanov
353314dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#if SANITIZER_INTERCEPT__EXIT
353414dd980b384ad859099b499e12f320c4791fb674Dmitry VyukovINTERCEPTOR(void, _exit, int status) {
353514dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  void *ctx;
353614dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
3537c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_USER_CALLBACK_START();
353814dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
3539c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_USER_CALLBACK_END();
3540a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  if (status == 0) status = status1;
354114dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  REAL(_exit)(status);
354214dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov}
3543a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
354414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#else
354514dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#define INIT__EXIT
354614dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#endif
354714dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov
35485e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
35495e2d3776a314629680921abd1d55d89d95a2da90Alexey SamsonovINTERCEPTOR(int, pthread_mutex_lock, void *m) {
35505e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  void *ctx;
35515e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
35525e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  int res = REAL(pthread_mutex_lock)(m);
355311f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov  if (res == errno_EOWNERDEAD)
355411f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov    COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
355511f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov  if (res == 0 || res == errno_EOWNERDEAD)
355611f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov    COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
3557c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res == errno_EINVAL)
3558c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
35595e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  return res;
35605e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov}
35615e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
35625e2d3776a314629680921abd1d55d89d95a2da90Alexey SamsonovINTERCEPTOR(int, pthread_mutex_unlock, void *m) {
35635e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  void *ctx;
35645e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
35655e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
3566c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(pthread_mutex_unlock)(m);
3567c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res == errno_EINVAL)
3568c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
3569c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
35705e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov}
35715e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
3572a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
3573a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_MUTEX_UNLOCK \
3574a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
35755e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#else
35765e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#define INIT_PTHREAD_MUTEX_LOCK
35775e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#define INIT_PTHREAD_MUTEX_UNLOCK
35785e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov#endif
35795e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov
35804d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
35814d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanovstatic void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
35824d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
35834d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_fsname)
35844d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
35854d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_fsname) + 1);
35864d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_dir)
35874d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
35884d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_dir) + 1);
35894d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_type)
35904d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
35914d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_type) + 1);
35924d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (mnt->mnt_opts)
35934d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
35944d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov                                   REAL(strlen)(mnt->mnt_opts) + 1);
35954d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov}
35964d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#endif
35974d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
35984d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETMNTENT
35994d7297daef90ad59446250617b72d184141436fcEvgeniy StepanovINTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
36004d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  void *ctx;
36014d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
36024d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  __sanitizer_mntent *res = REAL(getmntent)(fp);
36034d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (res) write_mntent(ctx, res);
36044d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  return res;
36054d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov}
3606a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
36074d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#else
36084d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#define INIT_GETMNTENT
36094d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#endif
36104d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
36114d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETMNTENT_R
36124d7297daef90ad59446250617b72d184141436fcEvgeniy StepanovINTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
36134d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
36144d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  void *ctx;
36154d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
36164d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
36174d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  if (res) write_mntent(ctx, res);
36184d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov  return res;
36194d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov}
3620a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
36214d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#else
36224d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#define INIT_GETMNTENT_R
36234d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov#endif
36244d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
36255cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATFS
36265cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statfs, char *path, void *buf) {
36275cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
36285cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
36295cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
36306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3632799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
36335cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statfs)(path, buf);
36345cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
36355cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
36365cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
36375cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatfs, int fd, void *buf) {
36385cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
36395cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
36406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36416a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3642799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
36435cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatfs)(fd, buf);
36445cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
36455cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
36465cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3647a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATFS                  \
3648a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statfs); \
3649a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatfs);
36505cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
36515cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATFS
36525cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
36535cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov
36545cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATFS64
36555cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statfs64, char *path, void *buf) {
36565cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
36575cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
36585cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
36596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3661799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
36625cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statfs64)(path, buf);
36635cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
36645cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
36655cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
36665cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatfs64, int fd, void *buf) {
36675cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
36685cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
36696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3671799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
36725cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatfs64)(fd, buf);
36735cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
36745cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
36755cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3676a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATFS64                  \
3677a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statfs64); \
3678a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatfs64);
36795cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
36805cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATFS64
36815cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
36825cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov
36835cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATVFS
36845cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statvfs, char *path, void *buf) {
36855cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
36865cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
36875cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
36886a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36896a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3690799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
36915cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statvfs)(path, buf);
36925cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
36935cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
36945cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
36955cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatvfs, int fd, void *buf) {
36965cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
36975cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
36986a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
36996a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3700799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
37015cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatvfs)(fd, buf);
37025cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
37035cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
37045cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3705a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATVFS                  \
3706a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statvfs); \
3707a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatvfs);
37085cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
37095cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATVFS
37105cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
37115cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov
37125cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#if SANITIZER_INTERCEPT_STATVFS64
37135cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, statvfs64, char *path, void *buf) {
37145cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
37155cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
37165cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
37176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3719799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
37205cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(statvfs64)(path, buf);
37215cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
37225cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
37235cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
37245cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy StepanovINTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
37255cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  void *ctx;
37265cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
37276a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37286a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3729799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
37305cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  int res = REAL(fstatvfs64)(fd, buf);
37315cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
37325cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov  return res;
37335cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov}
3734a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_STATVFS64                  \
3735a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(statvfs64); \
3736a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(fstatvfs64);
37375cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#else
37385cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#define INIT_STATVFS64
37395cee73e486aaa617a9627bb69a6447d3369b62ccEvgeniy Stepanov#endif
37404d7297daef90ad59446250617b72d184141436fcEvgeniy Stepanov
3741285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#if SANITIZER_INTERCEPT_INITGROUPS
3742285d458935bc2f9d8ec1109de01ed66185062349Evgeniy StepanovINTERCEPTOR(int, initgroups, char *user, u32 group) {
3743285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  void *ctx;
3744285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
3745285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
3746285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  int res = REAL(initgroups)(user, group);
3747285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov  return res;
3748285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov}
3749a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
3750285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#else
3751285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#define INIT_INITGROUPS
3752285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov#endif
3753285d458935bc2f9d8ec1109de01ed66185062349Evgeniy Stepanov
37546a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
3755369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
3756369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3757369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
3758369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3759369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  char *res = REAL(ether_ntoa)(addr);
37602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3761369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3762369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
3763369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
3764369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3765369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
3766369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3767369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
37682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
3769369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3770369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
37716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_ETHER_NTOA_ATON             \
37726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
37736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(ether_aton);
37746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
37756a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_ETHER_NTOA_ATON
37766a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
37776a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
37786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_ETHER_HOST
3779369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
3780369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3781369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
3782369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
37836a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37846a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3785799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3786369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  int res = REAL(ether_ntohost)(hostname, addr);
3787369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (!res && hostname)
3788369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3789369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3790369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
3791369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
3792369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3793369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
3794369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (hostname)
3795369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
37966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
37976a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3798799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3799369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  int res = REAL(ether_hostton)(hostname, addr);
3800369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3801369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3802369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
3803369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy StepanovINTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
3804369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov            char *hostname) {
3805369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  void *ctx;
3806369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
3807369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
38086a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3810799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3811369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  int res = REAL(ether_line)(line, addr, hostname);
3812369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  if (!res) {
3813369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3814369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov    if (hostname)
3815369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3816369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  }
3817369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov  return res;
3818369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov}
38196a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_ETHER_HOST                     \
3820a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
3821a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_hostton); \
3822a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_line);
3823369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov#else
38246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_ETHER_HOST
3825369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov#endif
3826369a9a6d4297af031227db1c6fedd21ee7033dc1Evgeniy Stepanov
3827220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#if SANITIZER_INTERCEPT_ETHER_R
3828220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy StepanovINTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
3829220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  void *ctx;
3830220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
3831220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
38326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3834799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3835220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  char *res = REAL(ether_ntoa_r)(addr, buf);
3836220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3837220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  return res;
3838220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov}
3839220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy StepanovINTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
3840220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov            __sanitizer_ether_addr *addr) {
3841220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  void *ctx;
3842220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
3843220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
38446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3846799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3847220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
3848220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
3849220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov  return res;
3850220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov}
3851a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_ETHER_R                       \
3852a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
3853a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(ether_aton_r);
3854220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#else
3855220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#define INIT_ETHER_R
3856220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov#endif
3857220d1f7c727eab61d1846a7d30b2b551a0378c0bEvgeniy Stepanov
385810362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#if SANITIZER_INTERCEPT_SHMCTL
385910362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy StepanovINTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
386010362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  void *ctx;
386110362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
38626a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3864799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
386510362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  int res = REAL(shmctl)(shmid, cmd, buf);
386610362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  if (res >= 0) {
386710362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    unsigned sz = 0;
386810362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
3869f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov      sz = sizeof(__sanitizer_shmid_ds);
387010362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    else if (cmd == shmctl_ipc_info)
387110362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov      sz = struct_shminfo_sz;
387210362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    else if (cmd == shmctl_shm_info)
387310362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov      sz = struct_shm_info_sz;
387410362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
387510362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  }
387610362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov  return res;
387710362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov}
3878a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
387910362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#else
388010362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#define INIT_SHMCTL
388110362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov#endif
388210362d66fffcd99bd5ced983e4b389dfeba114d0Evgeniy Stepanov
3883aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#if SANITIZER_INTERCEPT_RANDOM_R
3884aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy StepanovINTERCEPTOR(int, random_r, void *buf, u32 *result) {
3885aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  void *ctx;
3886aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
38876a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
38886a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3889799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3890aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  int res = REAL(random_r)(buf, result);
3891aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  if (!res && result)
3892aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3893aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov  return res;
3894aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov}
3895a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
3896aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#else
3897aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#define INIT_RANDOM_R
3898aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov#endif
3899aff25aa02098a510eff6eda1a3ec823e5b1fe1aaEvgeniy Stepanov
39006a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// FIXME: under ASan the REAL() call below may write to freed memory and corrupt
39016a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// its metadata. See
3902799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// https://github.com/google/sanitizers/issues/321.
39036a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
39046a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
39056a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
39066a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
39076a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
39086a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
39096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
39106a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPTOR(int, fn, void *attr, void *r) {                  \
39116a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    void *ctx;                                                 \
39126a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
39136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    int res = REAL(fn)(attr, r);                               \
39146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
39156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    return res;                                                \
3916e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  }
39176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
39186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
39196a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
39206a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
39216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
39226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
39236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
39246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
39256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
39266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
3927e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3928e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3929e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
3930e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
3931e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
3932e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
3933e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
3934e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
3935e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
3936e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
3937e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  void *ctx;
3938e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
39396a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3941799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3942e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  int res = REAL(pthread_attr_getstack)(attr, addr, size);
3943e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  if (!res) {
3944e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3945e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
3946e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  }
3947e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  return res;
3948e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov}
3949e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
39502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// We may need to call the real pthread_attr_getstack from the run-time
39512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// in sanitizer_common, but we don't want to include the interception headers
39522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// there. So, just define this function here.
39532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __sanitizer {
39542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" {
39552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
39562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(pthread_attr_getstack)(attr, addr, size);
39572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
39582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}  // extern "C"
39592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}  // namespace __sanitizer
39602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3961a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GET                             \
3962a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
3963a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
3964a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \
3965a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
3966a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
3967a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
3968a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
3969e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#else
3970e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GET
3971e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3972e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3973e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
3974e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
3975e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3976e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
3977a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
3978e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#else
3979e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETINHERITSCHED
3980e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
3981e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3982e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
3983e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy StepanovINTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
3984e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov            void *cpuset) {
3985e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  void *ctx;
3986e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
3987e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov                           cpuset);
39886a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
39896a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
3990799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
3991e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
3992e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  if (!res && cpusetsize && cpuset)
3993e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
3994e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov  return res;
3995e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov}
3996e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
3997e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
3998a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
3999e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#else
4000e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
4001e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov#endif
4002e236dbb5e558b174609d2d13e80685d488c129d8Evgeniy Stepanov
40036a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
40046a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
40056a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
40066a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
40076a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40086a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPSHARED
40096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40106a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40116a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
40126a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
40136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETTYPE \
40146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
40156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETTYPE
40176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40196a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
40206a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
40216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
40226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
40236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
40256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40276a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
40286a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
40296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
40306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
40316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
40336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
40366a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
40376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST \
40386a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
40396a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST
40416a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40426a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40436a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
40446a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
40456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
40466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
40476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
40496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
40526a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
40536a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
40546a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
40556a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40566a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
40576a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
40606a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
40616a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
40626a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
40636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40646a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
40656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
40686a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
40696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_CONDATTR_GETPSHARED \
40706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
40716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_CONDATTR_GETPSHARED
40736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40756a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
40766a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
40776a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_CONDATTR_GETCLOCK \
40786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
40796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_CONDATTR_GETCLOCK
40816a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40826a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
40836a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
40846a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
40856a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
40866a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
40876a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
40886a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_PTHREAD_BARRIERATTR_GETPSHARED
40896a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
40906a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
4091eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#if SANITIZER_INTERCEPT_TMPNAM
4092eada1a81188329b3f011311caed12ca4be4f639eEvgeniy StepanovINTERCEPTOR(char *, tmpnam, char *s) {
4093eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  void *ctx;
4094eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
4095eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  char *res = REAL(tmpnam)(s);
4096eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (res) {
4097eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov    if (s)
40986a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines      // FIXME: under ASan the call below may write to freed memory and corrupt
40996a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines      // its metadata. See
4100799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      // https://github.com/google/sanitizers/issues/321.
4101eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
4102eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov    else
41032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4104eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  }
4105eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  return res;
4106eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov}
4107a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
4108eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#else
4109eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#define INIT_TMPNAM
4110eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#endif
4111eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
4112eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#if SANITIZER_INTERCEPT_TMPNAM_R
4113eada1a81188329b3f011311caed12ca4be4f639eEvgeniy StepanovINTERCEPTOR(char *, tmpnam_r, char *s) {
4114eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  void *ctx;
4115eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
41166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4118799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4119eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  char *res = REAL(tmpnam_r)(s);
4120eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
4121eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  return res;
4122eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov}
4123a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
4124eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#else
4125eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#define INIT_TMPNAM_R
4126eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#endif
4127eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
4128eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#if SANITIZER_INTERCEPT_TEMPNAM
4129eada1a81188329b3f011311caed12ca4be4f639eEvgeniy StepanovINTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
4130eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  void *ctx;
4131eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
4132eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
4133eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
4134eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  char *res = REAL(tempnam)(dir, pfx);
41352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4136eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov  return res;
4137eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov}
4138a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
4139eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#else
4140eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#define INIT_TEMPNAM
4141eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov#endif
4142eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
41435cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
41445cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry VyukovINTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
41455cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  void *ctx;
41465cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
4147259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
41485cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
41495cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  return REAL(pthread_setname_np)(thread, name);
41505cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov}
4151a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
41525cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#else
41535cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define INIT_PTHREAD_SETNAME_NP
41545cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#endif
41555cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov
4156f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_SINCOS
4157f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
4158f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4159f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
41606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41616a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4162799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4163f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  REAL(sincos)(x, sin, cos);
4164f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4165f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4166f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4167f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
4168f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4169f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
41706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4172799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4173f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  REAL(sincosf)(x, sin, cos);
4174f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4175f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4176f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4177f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
4178f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4179f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
41806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
41816a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4182799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4183f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  REAL(sincosl)(x, sin, cos);
4184f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4185f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4186f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4187a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_SINCOS                   \
4188a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sincos);  \
4189a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(sincosf); \
4190c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
4191f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
4192f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#define INIT_SINCOS
4193f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
4194f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
4195f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_REMQUO
4196f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(double, remquo, double x, double y, int *quo) {
4197f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4198f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
41996a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42006a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4201799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4202f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  double res = REAL(remquo)(x, y, quo);
4203f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4204f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4205f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4206f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(float, remquof, float x, float y, int *quo) {
4207f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4208f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
42096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42106a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4211799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4212f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  float res = REAL(remquof)(x, y, quo);
4213f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4214f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4215f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4216f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
4217f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4218f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
42196a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42206a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4221799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4222f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  long double res = REAL(remquol)(x, y, quo);
4223f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4224f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4225f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4226a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_REMQUO                   \
4227a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(remquo);  \
4228a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(remquof); \
4229c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
4230f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
4231f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#define INIT_REMQUO
4232f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
4233f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
4234f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_LGAMMA
4235f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanovextern int signgam;
4236f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(double, lgamma, double x) {
4237f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4238f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
4239f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  double res = REAL(lgamma)(x);
4240f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4241f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4242f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4243f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(float, lgammaf, float x) {
4244f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4245f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
4246f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  float res = REAL(lgammaf)(x);
4247f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4248f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4249f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4250f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(long double, lgammal, long double x) {
4251f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4252f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
4253f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  long double res = REAL(lgammal)(x);
4254f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4255f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4256f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4257a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_LGAMMA                   \
4258a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lgamma);  \
4259a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lgammaf); \
4260c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
4261f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
4262f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#define INIT_LGAMMA
4263f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
4264f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
4265f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#if SANITIZER_INTERCEPT_LGAMMA_R
4266f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(double, lgamma_r, double x, int *signp) {
4267f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4268f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
42696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4271799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4272f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  double res = REAL(lgamma_r)(x, signp);
4273f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4274f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4275f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4276f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(float, lgammaf_r, float x, int *signp) {
4277f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4278f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
42796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4281799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4282f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  float res = REAL(lgammaf_r)(x, signp);
4283f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4284f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4285f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
42866a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_LGAMMA_R                   \
42876a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
42886a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(lgammaf_r);
42896a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#else
42906a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_LGAMMA_R
42916a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif
42926a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
42936a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_INTERCEPT_LGAMMAL_R
4294f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy StepanovINTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
4295f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  void *ctx;
4296f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
42976a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
42986a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4299799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
4300f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  long double res = REAL(lgammal_r)(x, signp);
4301f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4302f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov  return res;
4303f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov}
4304c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
4305f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#else
43066a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_LGAMMAL_R
4307f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov#endif
4308f814b43ed659512203439bc8c3f6d468155a1d3fEvgeniy Stepanov
430978d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#if SANITIZER_INTERCEPT_DRAND48_R
431078d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy StepanovINTERCEPTOR(int, drand48_r, void *buffer, double *result) {
431178d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  void *ctx;
431278d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
43136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
43146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4315799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
431678d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  int res = REAL(drand48_r)(buffer, result);
431778d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
431878d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  return res;
431978d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov}
432078d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy StepanovINTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
432178d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  void *ctx;
432278d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
43236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
43246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4325799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
432678d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  int res = REAL(lrand48_r)(buffer, result);
432778d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
432878d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov  return res;
432978d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov}
4330a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define INIT_DRAND48_R                  \
4331a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(drand48_r); \
4332a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(lrand48_r);
433378d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#else
433478d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#define INIT_DRAND48_R
433578d77c2638b8e02020737c9b296ce2198e4c58e6Evgeniy Stepanov#endif
4336eada1a81188329b3f011311caed12ca4be4f639eEvgeniy Stepanov
43372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_RAND_R
43382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, rand_r, unsigned *seedp) {
43392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
43402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
43412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
43422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(rand_r)(seedp);
43432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
43442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
43452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
43462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_RAND_R
43472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
43482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
434926fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETLINE
435026fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy StepanovINTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
435126fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  void *ctx;
435226fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
43536a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
43546a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4355799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
435626fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  SSIZE_T res = REAL(getline)(lineptr, n, stream);
435726fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  if (res > 0) {
435826fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
435926fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
436026fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
436126fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  }
436226fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  return res;
436326fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov}
4364cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
4365cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// FIXME: under ASan the call below may write to freed memory and corrupt its
4366cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// metadata. See
4367799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// https://github.com/google/sanitizers/issues/321.
4368cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
4369cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  {                                                                            \
4370cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    void *ctx;                                                                 \
4371cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
4372cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
4373cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    if (res > 0) {                                                             \
4374cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
4375cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
4376cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
4377cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    }                                                                          \
4378cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    return res;                                                                \
437926fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov  }
4380cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
4381cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
4382cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar            void *stream)
4383cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarGETDELIM_INTERCEPTOR_IMPL(__getdelim)
4384cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
4385cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
4386cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// with its own body.
43876a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
4388cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar            void *stream)
4389cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarGETDELIM_INTERCEPTOR_IMPL(getdelim)
4390cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
43916a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define INIT_GETLINE                     \
43926a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(getline);    \
43936a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  COMMON_INTERCEPT_FUNCTION(__getdelim); \
4394a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  COMMON_INTERCEPT_FUNCTION(getdelim);
439526fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#else
439626fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#define INIT_GETLINE
439726fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov#endif
439826fe5d396c5c99ddcd89b3f8722cea1d4940b9e9Evgeniy Stepanov
43992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_ICONV
44002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
44012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            char **outbuf, SIZE_T *outbytesleft) {
44022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
44042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           outbytesleft);
44052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (inbytesleft)
44062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
44072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (inbuf && inbytesleft)
44082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
44092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (outbytesleft)
44102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
4411799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *outbuf_orig = outbuf ? *outbuf : nullptr;
44126a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
44136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4414799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
44152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
44162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
44172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
44182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
44192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
44202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
44232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
44242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_ICONV
44252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
44262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
44272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TIMES
44282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
44292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
44316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
44326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4433799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
44342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_clock_t res = REAL(times)(tms);
44352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res != (__sanitizer_clock_t)-1 && tms)
44362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
44372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
44392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
44402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
44412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TIMES
44422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
44432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
44442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TLS_GET_ADDR
4445c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if !SANITIZER_S390
44462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
444786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// If you see any crashes around this functions, there are 2 known issues with
444886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// it: 1. __tls_get_addr can be called with mis-aligned stack due to:
444986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
445086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// 2. It can be called recursively if sanitizer code uses __tls_get_addr
445186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// to access thread local variables (it should not happen normally,
445286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// because sanitizers use initial-exec tls model).
44532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __tls_get_addr, void *arg) {
44542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
44552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
44562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(__tls_get_addr)(arg);
4457cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  uptr tls_begin, tls_end;
4458cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
4459cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
44606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  if (dtv) {
44616a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    // New DTLS block has been allocated.
44626a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
44636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  }
44642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
44652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
4466c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_PPC
4467c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// On PowerPC, we also need to intercept __tls_get_addr_opt, which has
4468c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// mostly the same semantics as __tls_get_addr, but its presence enables
4469c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// some optimizations in linker (which are safe to ignore here).
4470c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarextern "C" __attribute__((alias("__interceptor___tls_get_addr"),
4471c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                          visibility("default")))
4472c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid *__tls_get_addr_opt(void *arg);
4473c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
4474c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else // SANITIZER_S390
4475c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// On s390, we have to intercept two functions here:
4476c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// - __tls_get_addr_internal, which is a glibc-internal function that is like
4477c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//   the usual __tls_get_addr, but returns a TP-relative offset instead of
4478c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//   a proper pointer.  It is used by dlsym for TLS symbols.
4479c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// - __tls_get_offset, which is like the above, but also takes a GOT-relative
4480c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//   descriptor offset as an argument instead of a pointer.  GOT address
4481c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//   is passed in r12, so it's necessary to write it in assembly.  This is
4482c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar//   the function used by the compiler.
4483c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr_internal)
4484c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
4485c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
4486c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
4487c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr res = REAL(__tls_get_addr_internal)(arg);
4488c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
4489c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ptr = reinterpret_cast<void *>(res + tp);
4490c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  uptr tls_begin, tls_end;
4491c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
4492c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
4493c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (dtv) {
4494c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    // New DTLS block has been allocated.
4495c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
4496c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
4497c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
4498c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
4499c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// We need a protected symbol aliasing the above, so that we can jump
4500c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// directly to it from the assembly below.
4501c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarextern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
4502c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                          visibility("protected")))
4503c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainaruptr __interceptor___tls_get_addr_internal_protected(void *arg);
4504c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Now carefully intercept __tls_get_offset.
4505c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarasm(
4506c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ".text\n"
4507c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ".global __tls_get_offset\n"
4508c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "__tls_get_offset:\n"
4509c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// The __intercept_ version has to exist, so that gen_dynamic_list.py
4510c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// exports our symbol.
4511c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ".global __interceptor___tls_get_offset\n"
4512c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "__interceptor___tls_get_offset:\n"
4513c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef __s390x__
4514c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "la %r2, 0(%r2,%r12)\n"
4515c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "jg __interceptor___tls_get_addr_internal_protected\n"
4516c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
4517c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "basr %r3,0\n"
4518c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "0: la %r2,0(%r2,%r12)\n"
4519c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "l %r4,1f-0b(%r3)\n"
4520c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "b 0(%r4,%r3)\n"
4521c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  "1: .long __interceptor___tls_get_addr_internal_protected - 0b\n"
4522c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
4523c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ".type __tls_get_offset, @function\n"
4524c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ".size __tls_get_offset, .-__tls_get_offset\n"
4525c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar);
4526c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif // SANITIZER_S390
45272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
45282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TLS_GET_ADDR
45292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
45302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
45312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_LISTXATTR
45322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
45332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
45352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
45366a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
45376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4538799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
45392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(listxattr)(path, list, size);
45402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Here and below, size == 0 is a special case where nothing is written to the
45412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // buffer, and res contains the desired buffer size.
45422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
45432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
45462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
45482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
45496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
45506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4551799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
45522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(llistxattr)(path, list, size);
45532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
45542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
45572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
45596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
45606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4561799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
45622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(flistxattr)(fd, list, size);
45632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
45642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LISTXATTR                   \
45672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(listxattr);  \
45682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(llistxattr); \
45692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(flistxattr);
45702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
45712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LISTXATTR
45722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
45732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
45742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETXATTR
45752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
45762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T size) {
45772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
45792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
45802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
45816a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
45826a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4583799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
45842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(getxattr)(path, name, value, size);
45852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
45862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
45872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
45882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
45892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T size) {
45902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
45912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
45922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
45932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
45946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
45956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4596799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
45972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
45982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
45992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
46022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T size) {
46032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
46052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
46066a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
46076a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4608799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
46092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
46102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
46112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETXATTR                   \
46142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getxattr);  \
46152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(lgetxattr); \
46162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fgetxattr);
46172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
46182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETXATTR
46192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
46202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETRESID
46222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
46232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
46256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
46266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4627799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
46282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getresuid)(ruid, euid, suid);
46292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res >= 0) {
46302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
46312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
46322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
46332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
46342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
46372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
46396a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
46406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4641799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
46422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getresgid)(rgid, egid, sgid);
46432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res >= 0) {
46442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
46452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
46462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
46472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
46482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETRESID                   \
46512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getresuid); \
46522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getresgid);
46532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
46542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETRESID
46552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
46562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_GETIFADDRS
46582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
46592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// intercept freeifaddrs(). If that ceases to be the case, we might need to
46602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// intercept it to poison the memory again.
46612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
46622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
46646a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
46656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4666799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
46672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(getifaddrs)(ifap);
46682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res == 0 && ifap) {
46692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
46702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __sanitizer_ifaddrs *p = *ifap;
46712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    while (p) {
46722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
46732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_name)
46742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
46752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                       REAL(strlen)(p->ifa_name) + 1);
46762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_addr)
46772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
46782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_netmask)
46792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
46802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      // On Linux this is a union, but the other member also points to a
46812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      // struct sockaddr, so the following is sufficient.
46822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      if (p->ifa_dstaddr)
46832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
46842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      // FIXME(smatveev): Unpoison p->ifa_data as well.
46852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      p = p->ifa_next;
46862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
46872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
46882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
46892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
46902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETIFADDRS                  \
46912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(getifaddrs);
46922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
46932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_GETIFADDRS
46942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
46952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
46962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_IF_INDEXTONAME
46972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
46982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
46992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
47006a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
47016a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4702799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
47032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char *res = REAL(if_indextoname)(ifindex, ifname);
47042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res && ifname)
47052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
47062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
47072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
47092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
47102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
47112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (ifname)
47122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
47132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(if_nametoindex)(ifname);
47142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_IF_INDEXTONAME                  \
47162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(if_indextoname); \
47172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(if_nametoindex);
47182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
47192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_IF_INDEXTONAME
47202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
47212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
47222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_CAPGET
47232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, capget, void *hdrp, void *datap) {
47242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
47252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
47262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (hdrp)
47272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
47286a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
47296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4730799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
47312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(capget)(hdrp, datap);
47322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res == 0 && datap)
47332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
47342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // We can also return -1 and write to hdrp->version if the version passed in
47352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // hdrp->version is unsupported. But that's not a trivial condition to check,
47362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
47372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
47382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, capset, void *hdrp, const void *datap) {
47402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
47412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
47422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (hdrp)
47432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
47442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (datap)
47452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
47462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return REAL(capset)(hdrp, datap);
47472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_CAPGET                  \
47492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(capget); \
47502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(capset);
47512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
47522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_CAPGET
47532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
47542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
47552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_AEABI_MEM
4756799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarDECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr)
4757799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarDECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr)
4758799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarDECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr)
47592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
47602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
47612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memmove)(to, from, size);
47622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
47642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memmove)(to, from, size);
47652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
47672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memmove)(to, from, size);
47682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
47702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memcpy)(to, from, size);
47712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
47732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memcpy)(to, from, size);
47742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
47762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memcpy)(to, from, size);
47772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Note the argument order.
47792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
47802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, c, size);
47812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
47832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, c, size);
47842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
47862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, c, size);
47872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
47892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
47902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
47922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
47932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
47952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
47962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
47972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_AEABI_MEM                         \
47982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
47992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
48002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
48012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
48022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
48032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
48042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
48052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
48062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
48072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
48082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
48092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
48102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
48112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_AEABI_MEM
48122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_AEABI_MEM
48132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT___BZERO
48152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
48162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, __bzero, void *block, uptr size) {
48182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return WRAP(memset)(block, 0, size);
48192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
48202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
48212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
48222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT___BZERO
48232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT___BZERO
48242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FTIME
48262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
48272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
48282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
48296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
48306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4831799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
48322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(ftime)(tp);
48332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (tp)
48342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
48352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
48362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
48372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
48382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
48392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FTIME
48402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_FTIME
48412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_XDR
48432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
48442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            unsigned size, int op) {
48452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
48462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
48476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
48486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4849799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
48502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(xdrmem_create)(xdrs, addr, size, op);
48512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
48522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (op == __sanitizer_XDR_ENCODE) {
48532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // It's not obvious how much data individual xdr_ routines write.
48542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // Simply unpoison the entire target buffer in advance.
48552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
48562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
48572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
48582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
48602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
48612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
48626a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
48636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4864799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
48652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(xdrstdio_create)(xdrs, file, op);
48662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
48672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
48682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// FIXME: under ASan the call below may write to freed memory and corrupt
48706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// its metadata. See
4871799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// https://github.com/google/sanitizers/issues/321.
48722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define XDR_INTERCEPTOR(F, T)                             \
48732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
48742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void *ctx;                                            \
48752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
48762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
48772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
48782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    int res = REAL(F)(xdrs, p);                           \
48792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
48802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
48812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return res;                                           \
48822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
48832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
48842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_short, short)
48852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_short, unsigned short)
48862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int, int)
48872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_int, unsigned)
48882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_long, long)
48892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_long, unsigned long)
48902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_hyper, long long)
48912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
48922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_longlong_t, long long)
48932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
48942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int8_t, u8)
48952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint8_t, u8)
48962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int16_t, u16)
48972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint16_t, u16)
48982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int32_t, u32)
48992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint32_t, u32)
49002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_int64_t, u64)
49012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_uint64_t, u64)
49022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_quad_t, long long)
49032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
49042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_bool, bool)
49052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_enum, int)
49062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_char, char)
49072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_u_char, unsigned char)
49082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_float, float)
49092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesXDR_INTERCEPTOR(xdr_double, double)
49102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
49112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
49122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// wrapstring, sizeof
49132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
49142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
49152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            unsigned maxsize) {
49162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
49172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
49182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
49192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
49202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
49212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
49222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
49236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
49246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4925799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
49262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
49272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
49282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
49292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
49302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
49312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
49322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
49332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
49342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
49352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
49362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            unsigned maxsize) {
49372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
49382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
49392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
49402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
49412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
49422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
49436a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
49446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4945799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
49462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(xdr_string)(xdrs, p, maxsize);
49472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
49482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
49492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (res && *p)
49502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
49512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
49522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
49532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
49542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
49552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XDR                               \
49562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
49572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
49582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_short);        \
49592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
49602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int);          \
49612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
49622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_long);         \
49632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
49642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
49652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
49662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
49672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
49682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
49692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
49702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
49712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
49722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
49732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
49742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
49752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
49762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
49772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
49782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
49792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
49802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_char);         \
49812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
49822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_float);        \
49832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_double);       \
49842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
49852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(xdr_string);
49862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
49872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_XDR
49882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_INTERCEPT_XDR
49892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
49902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_TSEARCH
49912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void *, tsearch, void *key, void **rootp,
49922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            int (*compar)(const void *, const void *)) {
49932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
49942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
49956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
49966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
4997799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
49982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(tsearch)(key, rootp, compar);
49992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res && *(void **)res == key)
50002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
50012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
50042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
50052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_TSEARCH
50062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
50072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
50082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
50092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SANITIZER_INTERCEPT_OPEN_MEMSTREAM
50102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid unpoison_file(__sanitizer_FILE *fp) {
50112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_HAS_STRUCT_FILE
50122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
50132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
50142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
50152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        fp->_IO_read_end - fp->_IO_read_base);
50162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_HAS_STRUCT_FILE
50172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
50192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
50202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_LIBIO_INTERNALS
50212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// These guys are called when a .c source is built with -O2.
50222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
50232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
50252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__uflow)(fp);
50262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
50272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
50302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
50322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__underflow)(fp);
50332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
50342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
50372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
50392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__overflow)(fp, ch);
50402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
50412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
50442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
50462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__wuflow)(fp);
50472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
50482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
50512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
50532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__wunderflow)(fp);
50542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
50552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
50582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
50602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(__woverflow)(fp, ch);
50612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  unpoison_file(fp);
50622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LIBIO_INTERNALS               \
50652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__uflow);      \
50662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__underflow);  \
50672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__overflow);   \
50682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__wuflow);     \
50692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__wunderflow); \
50702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(__woverflow);
50712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
50722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_LIBIO_INTERNALS
50732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
50742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
50752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FOPEN
50762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
50772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
5079799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
50802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
50812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fopen)(path, mode);
50822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
50832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
50842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
50872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
50892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
50902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
50912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
50922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
50932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
50942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
50952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_FILE *fp) {
50962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
50972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
5098799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
50992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
51002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
51012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
51022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
51032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
51042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
51052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
51062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN                   \
51072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fopen);  \
51082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fdopen); \
51092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(freopen);
51102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
51112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN
51122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
51132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
51142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FOPEN64
51152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
51162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
51172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
51182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
51192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
51202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fopen64)(path, mode);
51212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
51222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
51232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
51242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
51252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
51262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_FILE *fp) {
51272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
51282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
5129799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
51302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
51312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
51322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
51332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
51342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
51352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
51362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
51372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN64                  \
51382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fopen64); \
51392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(freopen64);
51402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
51412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FOPEN64
51422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
51432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
51442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
51452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
51462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
51472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
51486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
51496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
5150799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
51512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
51522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) {
51532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
51542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
51552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    unpoison_file(res);
51562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FileMetadata file = {ptr, sizeloc};
51572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SetInterceptorMetadata(res, file);
51582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
51592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
51602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
51612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
51622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            SIZE_T *sizeloc) {
51632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
51642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
51652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
51662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) {
51672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
51682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
51692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    unpoison_file(res);
51702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FileMetadata file = {(char **)ptr, sizeloc};
51712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    SetInterceptorMetadata(res, file);
51722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
51732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
51742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
51752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
51762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            const char *mode) {
51772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
51782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
51796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // FIXME: under ASan the call below may write to freed memory and corrupt
51806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // its metadata. See
5181799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // https://github.com/google/sanitizers/issues/321.
51822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
51832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) unpoison_file(res);
51842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
51852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
51862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OPEN_MEMSTREAM                   \
51872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(open_memstream);  \
51882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
51892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(fmemopen);
51902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
51912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OPEN_MEMSTREAM
51922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
51932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
51942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_OBSTACK
51952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void initialize_obstack(__sanitizer_obstack *obstack) {
51962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
51972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (obstack->chunk)
51982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
51992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        sizeof(*obstack->chunk));
52002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
52022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
52032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            int align, void *(*alloc_fn)(uptr arg, uptr sz),
52042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            void (*free_fn)(uptr arg, void *p)) {
52052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
52072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           free_fn);
52082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
52092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) initialize_obstack(obstack);
52102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
52112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
52132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
52142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
52162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                           free_fn);
52172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
52182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res) initialize_obstack(obstack);
52192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
52202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
52222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
52242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(_obstack_newchunk)(obstack, length);
52252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (obstack->chunk)
52262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    COMMON_INTERCEPTOR_INITIALIZE_RANGE(
52272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        obstack->chunk, obstack->next_free - (char *)obstack->chunk);
52282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OBSTACK                           \
52302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
52312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
52322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
52332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
52342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_OBSTACK
52352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
52362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
52372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FFLUSH
52382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
52392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
52412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(fflush)(fp);
52422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // FIXME: handle fp == NULL
52432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (fp) {
52442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    const FileMetadata *m = GetInterceptorMetadata(fp);
52452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
52462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
52472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
52482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
52502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
52512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FFLUSH
52522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
52532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
52542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_FCLOSE
52552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
52562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
5258799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
5259799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  const FileMetadata *m = GetInterceptorMetadata(fp);
5260799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(fclose)(fp);
5261799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (m) {
5262799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
5263799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    DeleteInterceptorMetadata(fp);
52642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
5265799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
52662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
52682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
52692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_FCLOSE
52702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
52712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
52722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
52732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, dlopen, const char *filename, int flag) {
52742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
5276259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
527786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
52782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(dlopen)(filename, flag);
52792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
52802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
52812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
52832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, dlclose, void *handle) {
52842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *ctx;
52852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
52862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(dlclose)(handle);
52872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
52882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
52892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
52902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_DLOPEN_DLCLOSE          \
52912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(dlopen); \
52922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPT_FUNCTION(dlclose);
52932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
52942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INIT_DLOPEN_DLCLOSE
52952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
52962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
52976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_INTERCEPT_GETPASS
52986d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(char *, getpass, const char *prompt) {
52996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  void *ctx;
53006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
53016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (prompt)
53026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
53036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  char *res = REAL(getpass)(prompt);
53046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
53056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return res;
53066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
53096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
53106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define INIT_GETPASS
53116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
53126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_INTERCEPT_TIMERFD
53146d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
53156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines            void *old_value) {
53166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  void *ctx;
53176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
53186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines                           old_value);
53196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
53206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
53216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (res != -1 && old_value)
53226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
53236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return res;
53246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53266d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
53276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  void *ctx;
53286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
53296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  int res = REAL(timerfd_gettime)(fd, curr_value);
53306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (res != -1 && curr_value)
53316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
53326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return res;
53336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define INIT_TIMERFD                          \
53356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
53366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
53376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
53386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define INIT_TIMERFD
53396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif
53406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_INTERCEPT_MLOCKX
53426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Linux kernel has a bug that leads to kernel deadlock if a process
53436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// maps TBs of memory and then calls mlock().
53446d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void MlockIsUnsupported() {
53456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  static atomic_uint8_t printed;
53466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (atomic_exchange(&printed, 1, memory_order_relaxed))
53476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    return;
5348799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
53496d1862363c88c183b0ed7740fca876342cf0474bStephen Hines          SanitizerToolName);
53506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53516d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53526d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, mlock, const void *addr, uptr len) {
53536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  MlockIsUnsupported();
53546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return 0;
53556d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53576d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, munlock, const void *addr, uptr len) {
53586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  MlockIsUnsupported();
53596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return 0;
53606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53626d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, mlockall, int flags) {
53636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  MlockIsUnsupported();
53646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return 0;
53656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53676d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, munlockall, void) {
53686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  MlockIsUnsupported();
53696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return 0;
53706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
53716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define INIT_MLOCKX                                                            \
53736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPT_FUNCTION(mlock);                                            \
53746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPT_FUNCTION(munlock);                                          \
53756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
53766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  COMMON_INTERCEPT_FUNCTION(munlockall);
53776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
53786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#else
53796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define INIT_MLOCKX
53806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif  // SANITIZER_INTERCEPT_MLOCKX
53816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
5382799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_FOPENCOOKIE
5383799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstruct WrappedCookie {
5384799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *real_cookie;
5385799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_cookie_io_functions_t real_io_funcs;
5386799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar};
5387799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5388799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic uptr wrapped_read(void *cookie, char *buf, uptr size) {
5389799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5390799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5391799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
5392799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
5393799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5394799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5395799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic uptr wrapped_write(void *cookie, const char *buf, uptr size) {
5396799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5397799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5398799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
5399799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
5400799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5401799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5402799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic int wrapped_seek(void *cookie, u64 *offset, int whence) {
5403799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5404799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
5405799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5406799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
5407799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
5408799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                   : -1;
5409799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5410799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5411799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic int wrapped_close(void *cookie) {
5412799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
5413799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5414799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
5415799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
5416799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  InternalFree(wrapped_cookie);
5417799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5418799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5419799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5420799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
5421799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            __sanitizer_cookie_io_functions_t io_funcs) {
5422799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5423799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
5424799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  WrappedCookie *wrapped_cookie =
5425799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
5426799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  wrapped_cookie->real_cookie = cookie;
5427799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  wrapped_cookie->real_io_funcs = io_funcs;
5428799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  __sanitizer_FILE *res =
5429799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
5430799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                                               wrapped_seek, wrapped_close});
5431799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5432799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5433799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5434799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
5435799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5436799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_FOPENCOOKIE
5437799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
5438799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5439799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_SEM
5440799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
5441799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5442799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
5443799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // Workaround a bug in glibc's "old" semaphore implementation by
5444799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // zero-initializing the sem_t contents. This has to be done here because
5445799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // interceptors bind to the lowest symbols version by default, hitting the
5446799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // buggy code path while the non-sanitized build of the same code works fine.
5447799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  REAL(memset)(s, 0, sizeof(*s));
5448799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(sem_init)(s, pshared, value);
5449799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5450799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5451799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5452799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
5453799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5454799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
5455799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(sem_destroy)(s);
5456799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5457799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5458799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5459799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
5460799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5461799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
5462799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
5463799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0) {
5464799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5465799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5466799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5467799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5468799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5469799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
5470799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5471799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
5472799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
5473799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0) {
5474799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5475799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5476799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5477799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5478799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5479799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
5480799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5481799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
5482799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
5483799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
5484799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0) {
5485799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5486799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5487799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5488799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5489799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5490799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
5491799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5492799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
5493799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
5494799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(sem_post)(s);
5495799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5496799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5497799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5498799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
5499799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5500799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
5501799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(sem_getvalue)(s, sval);
5502799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0) {
5503799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5504799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
5505799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5506799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5507799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5508799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_SEM                                                               \
5509799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_init);                                         \
5510799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \
5511799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \
5512799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \
5513799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \
5514799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_post);                                         \
5515799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sem_getvalue);
5516799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5517799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_SEM
5518799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif // SANITIZER_INTERCEPT_SEM
5519799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5520799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
5521799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
5522799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5523799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
5524799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(pthread_setcancelstate)(state, oldstate);
5525799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0)
5526799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
5527799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5528799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5529799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5530799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
5531799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5532799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
5533799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(pthread_setcanceltype)(type, oldtype);
5534799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0)
5535799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
5536799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5537799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5538799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_PTHREAD_SETCANCEL                                                 \
5539799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
5540799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
5541799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5542799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_PTHREAD_SETCANCEL
5543799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
5544799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5545799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_MINCORE
5546799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
5547799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5548799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
5549799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(mincore)(addr, length, vec);
5550799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res == 0) {
5551799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    uptr page_size = GetPageSizeCached();
5552799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
5553799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
5554799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5555799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5556799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5557799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
5558799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5559799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_MINCORE
5560799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
5561799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5562799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_PROCESS_VM_READV
5563799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
5564799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5565799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            uptr flags) {
5566799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5567799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
5568799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                           remote_iov, riovcnt, flags);
5569799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
5570799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                                       riovcnt, flags);
5571799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res > 0)
5572799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    write_iovec(ctx, local_iov, liovcnt, res);
5573799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5574799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5575799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5576799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
5577799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5578799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            uptr flags) {
5579799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5580799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
5581799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                           remote_iov, riovcnt, flags);
5582799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
5583799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar                                        riovcnt, flags);
5584799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res > 0)
5585799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    read_iovec(ctx, local_iov, liovcnt, res);
5586799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5587799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5588799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_PROCESS_VM_READV                                                  \
5589799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
5590799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(process_vm_writev);
5591799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5592799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_PROCESS_VM_READV
5593799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
5594799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5595799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_CTERMID
5596799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(char *, ctermid, char *s) {
5597799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5598799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
5599799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  char *res = REAL(ctermid)(s);
5600799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) {
5601799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
5602799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5603799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5604799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5605799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
5606799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5607799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_CTERMID
5608799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
5609799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5610799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#if SANITIZER_INTERCEPT_CTERMID_R
5611799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(char *, ctermid_r, char *s) {
5612799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ctx;
5613799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
5614799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  char *res = REAL(ctermid_r)(s);
5615799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res) {
5616799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
5617799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
5618799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
5619799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
5620799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
5621799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#else
5622799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define INIT_CTERMID_R
5623799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
5624799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
5625c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_RECV_RECVFROM
5626c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
5627c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5628c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
5629c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5630c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SSIZE_T res = REAL(recv)(fd, buf, len, flags);
5631c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res > 0) {
5632c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
5633c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
5634c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
5635c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5636c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5637c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5638c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
5639c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar            void *srcaddr, int *addrlen) {
5640c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5641c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
5642c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                           addrlen);
5643c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5644c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SIZE_T srcaddr_sz;
5645c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (srcaddr) srcaddr_sz = *addrlen;
5646c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  (void)srcaddr_sz;  // prevent "set but not used" warning
5647c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
5648c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res > 0) {
5649c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
5650c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (srcaddr)
5651c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
5652c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                          Min((SIZE_T)*addrlen, srcaddr_sz));
5653c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
5654c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5655c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5656c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_RECV_RECVFROM          \
5657c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(recv);  \
5658c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(recvfrom);
5659c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5660c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_RECV_RECVFROM
5661c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5662c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5663c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_SEND_SENDTO
5664c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
5665c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5666c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
5667c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (fd >= 0) {
5668c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5669c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
5670c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
5671c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SSIZE_T res = REAL(send)(fd, buf, len, flags);
5672c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_send && res > 0)
5673c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
5674c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5675c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5676c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5677c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
5678c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar            void *dstaddr, int addrlen) {
5679c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5680c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
5681c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (fd >= 0) {
5682c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5683c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
5684c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
5685c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // Can't check dstaddr as it may have uninitialized padding at the end.
5686c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
5687c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_send && res > 0)
5688c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
5689c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5690c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5691c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_SEND_SENDTO           \
5692c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(send); \
5693c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(sendto);
5694c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5695c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_SEND_SENDTO
5696c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5697c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5698c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
5699c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
5700c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5701c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
5702c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5703c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(eventfd_read)(fd, value);
5704c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res == 0) {
5705c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
5706c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
5707c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
5708c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5709c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5710c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, eventfd_write, int fd, u64 value) {
5711c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5712c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
5713c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (fd >= 0) {
5714c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
5715c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
5716c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
5717c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(eventfd_write)(fd, value);
5718c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5719c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5720c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_EVENTFD_READ_WRITE            \
5721c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(eventfd_read); \
5722c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPT_FUNCTION(eventfd_write)
5723c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5724c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_EVENTFD_READ_WRITE
5725c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5726c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5727c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT_STAT
5728c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, stat, const char *path, void *buf) {
5729c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5730c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
5731c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_stat)
5732c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5733c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(stat)(path, buf);
5734c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res)
5735c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
5736c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5737c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5738c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
5739c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5740c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT_STAT
5741c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5742c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5743c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT___XSTAT
5744c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
5745c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5746c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
5747c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_stat)
5748c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5749c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(__xstat)(version, path, buf);
5750c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res)
5751c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
5752c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5753c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5754c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
5755c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5756c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___XSTAT
5757c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5758c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5759c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT___XSTAT64
5760c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
5761c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5762c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
5763c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_stat)
5764c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5765c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(__xstat64)(version, path, buf);
5766c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res)
5767c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
5768c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5769c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5770c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
5771c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5772c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___XSTAT64
5773c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5774c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5775c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT___LXSTAT
5776c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
5777c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5778c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
5779c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_stat)
5780c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5781c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(__lxstat)(version, path, buf);
5782c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res)
5783c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
5784c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5785c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5786c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
5787c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5788c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___LXSTAT
5789c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5790c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5791c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if SANITIZER_INTERCEPT___LXSTAT64
5792c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
5793c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
5794c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
5795c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (common_flags()->intercept_stat)
5796c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
5797c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(__lxstat64)(version, path, buf);
5798c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res)
5799c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
5800c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
5801c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
5802c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
5803c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
5804c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define INIT___LXSTAT64
5805c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
5806c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
5807c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// FIXME: add other *stat interceptor
5808c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
58092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void InitializeCommonInterceptors() {
58102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
58112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
58122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
58132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TEXTDOMAIN;
5814c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_STRLEN;
5815c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_STRNLEN;
58162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRCMP;
58172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRNCMP;
58182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRCASECMP;
58192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRNCASECMP;
5820cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  INIT_STRSTR;
5821cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  INIT_STRCASESTR;
5822c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_STRCHR;
5823c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_STRCHRNUL;
5824c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_STRRCHR;
5825cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  INIT_STRSPN;
5826cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  INIT_STRPBRK;
5827c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_MEMSET;
5828c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_MEMMOVE;
5829c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_MEMCPY;
58302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MEMCHR;
5831799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_MEMCMP;
58322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MEMRCHR;
58332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READ;
58342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREAD;
58352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREAD64;
58362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READV;
58372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREADV;
58382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PREADV64;
58392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WRITE;
58402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITE;
58412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITE64;
58422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WRITEV;
58432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITEV;
58442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PWRITEV64;
58452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PRCTL;
58462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LOCALTIME_AND_FRIENDS;
58472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRPTIME;
58482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCANF;
58492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ISOC99_SCANF;
58502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PRINTF;
585186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INIT_PRINTF_L;
58522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ISOC99_PRINTF;
58532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FREXP;
58542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FREXPF_FREXPL;
58552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWNAM_AND_FRIENDS;
58562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWNAM_R_AND_FRIENDS;
58572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWENT;
58582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FGETPWENT;
58592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPWENT_R;
58602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SETPWENT;
58612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CLOCK_GETTIME;
58622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETITIMER;
58632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TIME;
58642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GLOB;
58652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WAIT;
58662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WAIT4;
58672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_INET;
58682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_GETSCHEDPARAM;
58692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETADDRINFO;
58702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETNAMEINFO;
58712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETSOCKNAME;
58722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETHOSTBYNAME;
58732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETHOSTBYNAME_R;
58746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_GETHOSTBYNAME2_R;
58756a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_GETHOSTBYADDR_R;
58766a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_GETHOSTENT_R;
58772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETSOCKOPT;
58782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ACCEPT;
58792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ACCEPT4;
58802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MODF;
58812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_RECVMSG;
5882c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_SENDMSG;
58832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETPEERNAME;
58842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_IOCTL;
58852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_INET_ATON;
58862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SYSINFO;
58872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READDIR;
58882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_READDIR64;
58892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTRACE;
58902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SETLOCALE;
58912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETCWD;
58922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GET_CURRENT_DIR_NAME;
58932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRTOIMAX;
58942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MBSTOWCS;
58952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_MBSNRTOWCS;
58962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WCSTOMBS;
58972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WCSNRTOMBS;
5898799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_WCRTOMB;
58992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TCGETATTR;
59002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_REALPATH;
59012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CANONICALIZE_FILE_NAME;
59022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CONFSTR;
59032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCHED_GETAFFINITY;
590486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INIT_SCHED_GETPARAM;
59052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRERROR;
59062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STRERROR_R;
59072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_XPG_STRERROR_R;
59082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCANDIR;
59092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SCANDIR64;
59102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETGROUPS;
59112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_POLL;
59122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PPOLL;
59132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_WORDEXP;
59142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGWAIT;
59152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGWAITINFO;
59162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGTIMEDWAIT;
59172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGSETOPS;
59182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGPENDING;
59192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SIGPROCMASK;
59202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_BACKTRACE;
59212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT__EXIT;
59222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_MUTEX_LOCK;
59232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_MUTEX_UNLOCK;
59242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETMNTENT;
59252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETMNTENT_R;
59262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATFS;
59272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATFS64;
59282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATVFS;
59292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_STATVFS64;
59302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_INITGROUPS;
59316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_ETHER_NTOA_ATON;
59326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_ETHER_HOST;
59332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ETHER_R;
59342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SHMCTL;
59352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_RANDOM_R;
59362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_ATTR_GET;
59372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_ATTR_GETINHERITSCHED;
59382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_ATTR_GETAFFINITY_NP;
59396a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETPSHARED;
59406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETTYPE;
59416a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
59426a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
59436a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETROBUST;
59446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
59456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
59466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
59476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_CONDATTR_GETPSHARED;
59486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_CONDATTR_GETCLOCK;
59496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_PTHREAD_BARRIERATTR_GETPSHARED;
59502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TMPNAM;
59512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TMPNAM_R;
59522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TEMPNAM;
59532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_PTHREAD_SETNAME_NP;
59542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_SINCOS;
59552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_REMQUO;
59562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LGAMMA;
59572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LGAMMA_R;
59586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INIT_LGAMMAL_R;
59592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_DRAND48_R;
59602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_RAND_R;
59612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETLINE;
59622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_ICONV;
59632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TIMES;
59642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TLS_GET_ADDR;
59652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LISTXATTR;
59662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETXATTR;
59672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETRESID;
59682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_GETIFADDRS;
59692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_IF_INDEXTONAME;
59702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_CAPGET;
59712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_AEABI_MEM;
59722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT___BZERO;
59732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FTIME;
59742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_XDR;
59752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_TSEARCH;
59762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_LIBIO_INTERNALS;
59772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FOPEN;
59782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FOPEN64;
59792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_OPEN_MEMSTREAM;
59802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_OBSTACK;
59812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FFLUSH;
59822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_FCLOSE;
59832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INIT_DLOPEN_DLCLOSE;
59846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  INIT_GETPASS;
59856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  INIT_TIMERFD;
59866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  INIT_MLOCKX;
5987799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_FOPENCOOKIE;
5988799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_SEM;
5989799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_PTHREAD_SETCANCEL;
5990799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_MINCORE;
5991799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_PROCESS_VM_READV;
5992799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_CTERMID;
5993799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INIT_CTERMID_R;
5994c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_RECV_RECVFROM;
5995c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_SEND_SENDTO;
5996c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_STAT;
5997c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT_EVENTFD_READ_WRITE;
5998c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT___XSTAT;
5999c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT___XSTAT64;
6000c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT___LXSTAT;
6001c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INIT___LXSTAT64;
6002c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // FIXME: add other *stat interceptors.
60032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
6004