blob: 7c52eb22f40f6ed98623c9f5de1307316060d8d1 [file] [log] [blame]
Evgeniy Stepanov4f32c0b2013-01-18 13:01:18 +00001//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
Kostya Serebryany8530e2b2012-12-12 09:54:35 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Common function interceptors for tools like AddressSanitizer,
11// ThreadSanitizer, MemorySanitizer, etc.
12//
13// This file should be included into the tool's interceptor file,
14// which has to define it's own macros:
15// COMMON_INTERCEPTOR_ENTER
16// COMMON_INTERCEPTOR_READ_RANGE
17// COMMON_INTERCEPTOR_WRITE_RANGE
Dmitry Vyukov0586dcc2013-10-03 14:12:09 +000018// COMMON_INTERCEPTOR_INITIALIZE_RANGE
Kostya Serebryanyc8033192013-01-17 13:09:00 +000019// COMMON_INTERCEPTOR_FD_ACQUIRE
20// COMMON_INTERCEPTOR_FD_RELEASE
Dmitry Vyukov67f55442013-10-11 14:13:11 +000021// COMMON_INTERCEPTOR_FD_ACCESS
Kostya Serebryanyc20b3212013-01-18 06:43:13 +000022// COMMON_INTERCEPTOR_SET_THREAD_NAME
Dmitry Vyukov14dd9802013-10-03 15:22:29 +000023// COMMON_INTERCEPTOR_ON_EXIT
Alexey Samsonov5e2d3772013-10-16 08:20:31 +000024// COMMON_INTERCEPTOR_MUTEX_LOCK
25// COMMON_INTERCEPTOR_MUTEX_UNLOCK
Kostya Serebryany8530e2b2012-12-12 09:54:35 +000026//===----------------------------------------------------------------------===//
Kostya Serebryany6afa1b02012-12-13 06:31:40 +000027#include "interception/interception.h"
Alexey Samsonov74737d52012-12-13 08:50:16 +000028#include "sanitizer_platform_interceptors.h"
Kostya Serebryanyb1cc4e42012-12-13 05:27:08 +000029
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +000030#include <stdarg.h>
31
Evgeniy Stepanov30e110e2013-03-19 14:54:17 +000032#if SANITIZER_WINDOWS
Evgeniy Stepanov348bd122013-02-11 14:08:12 +000033#define va_copy(dst, src) ((dst) = (src))
34#endif // _WIN32
35
Dmitry Vyukov0586dcc2013-10-03 14:12:09 +000036#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
Alexey Samsonov5e2d3772013-10-16 08:20:31 +000037#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size)
Dmitry Vyukov0586dcc2013-10-03 14:12:09 +000038#endif
39
Dmitry Vyukov67f55442013-10-11 14:13:11 +000040#ifndef COMMON_INTERCEPTOR_FD_ACCESS
Alexey Samsonov5e2d3772013-10-16 08:20:31 +000041#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)
42#endif
43
44#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
45#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m)
46#endif
47
48#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
49#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m)
Dmitry Vyukov67f55442013-10-11 14:13:11 +000050#endif
51
Alexey Samsonov67505a82013-07-16 12:51:53 +000052#if SANITIZER_INTERCEPT_STRCMP
53static inline int CharCmpX(unsigned char c1, unsigned char c2) {
54 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
55}
56
57INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
58 void *ctx;
59 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
60 unsigned char c1, c2;
61 uptr i;
62 for (i = 0; ; i++) {
63 c1 = (unsigned char)s1[i];
64 c2 = (unsigned char)s2[i];
65 if (c1 != c2 || c1 == '\0') break;
66 }
67 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
68 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
69 return CharCmpX(c1, c2);
70}
71
72INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
73 void *ctx;
74 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
75 unsigned char c1 = 0, c2 = 0;
76 uptr i;
77 for (i = 0; i < size; i++) {
78 c1 = (unsigned char)s1[i];
79 c2 = (unsigned char)s2[i];
80 if (c1 != c2 || c1 == '\0') break;
81 }
82 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
83 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
84 return CharCmpX(c1, c2);
85}
86
87#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp)
88#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp)
89#else
90#define INIT_STRCMP
91#define INIT_STRNCMP
92#endif
93
Dmitry Vyukovbe523662013-03-26 12:40:23 +000094#if SANITIZER_INTERCEPT_STRCASECMP
95static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
96 int c1_low = ToLower(c1);
97 int c2_low = ToLower(c2);
98 return c1_low - c2_low;
99}
100
101INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
102 void *ctx;
103 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
104 unsigned char c1 = 0, c2 = 0;
105 uptr i;
106 for (i = 0; ; i++) {
107 c1 = (unsigned char)s1[i];
108 c2 = (unsigned char)s2[i];
109 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
110 break;
111 }
112 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
113 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
114 return CharCaseCmp(c1, c2);
115}
116
117INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
118 void *ctx;
119 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
120 unsigned char c1 = 0, c2 = 0;
121 uptr i;
122 for (i = 0; i < n; i++) {
123 c1 = (unsigned char)s1[i];
124 c2 = (unsigned char)s2[i];
125 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
126 break;
127 }
128 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
129 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
130 return CharCaseCmp(c1, c2);
131}
132
133#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
134#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
135#else
136#define INIT_STRCASECMP
137#define INIT_STRNCASECMP
138#endif
139
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000140#if SANITIZER_INTERCEPT_FREXP
141INTERCEPTOR(double, frexp, double x, int *exp) {
142 void *ctx;
143 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
144 double res = REAL(frexp)(x, exp);
145 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
146 return res;
147}
148
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +0000149#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
150#else
151#define INIT_FREXP
152#endif // SANITIZER_INTERCEPT_FREXP
153
154#if SANITIZER_INTERCEPT_FREXPF_FREXPL
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000155INTERCEPTOR(float, frexpf, float x, int *exp) {
156 void *ctx;
157 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
158 float res = REAL(frexpf)(x, exp);
159 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
160 return res;
161}
162
163INTERCEPTOR(long double, frexpl, long double x, int *exp) {
164 void *ctx;
165 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
166 long double res = REAL(frexpl)(x, exp);
167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
168 return res;
169}
170
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +0000171#define INIT_FREXPF_FREXPL \
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000172 INTERCEPT_FUNCTION(frexpf); \
173 INTERCEPT_FUNCTION(frexpl)
174#else
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +0000175#define INIT_FREXPF_FREXPL
176#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000177
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000178#if SI_NOT_WINDOWS
179static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
180 SIZE_T iovlen, SIZE_T maxlen) {
181 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
182 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
183 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
184 maxlen -= sz;
185 }
186}
187
188static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
189 SIZE_T iovlen, SIZE_T maxlen) {
190 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
191 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
192 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
193 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
194 maxlen -= sz;
195 }
196}
197#endif
198
Alexey Samsonov8ffd8772012-12-13 08:36:13 +0000199#if SANITIZER_INTERCEPT_READ
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000200INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000201 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000202 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000203 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000204 SSIZE_T res = REAL(read)(fd, ptr, count);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000205 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000206 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
Kostya Serebryanyc8033192013-01-17 13:09:00 +0000207 if (res >= 0 && fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000208 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000209 return res;
210}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000211#define INIT_READ INTERCEPT_FUNCTION(read)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000212#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000213#define INIT_READ
Alexey Samsonov8ffd8772012-12-13 08:36:13 +0000214#endif
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000215
Alexey Samsonovc333dff2012-12-13 08:10:23 +0000216#if SANITIZER_INTERCEPT_PREAD
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000217INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000218 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000219 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000220 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000221 SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000222 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000223 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
Kostya Serebryanyc8033192013-01-17 13:09:00 +0000224 if (res >= 0 && fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000225 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000226 return res;
227}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000228#define INIT_PREAD INTERCEPT_FUNCTION(pread)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000229#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000230#define INIT_PREAD
Alexey Samsonovc333dff2012-12-13 08:10:23 +0000231#endif
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000232
Kostya Serebryanyb1cc4e42012-12-13 05:27:08 +0000233#if SANITIZER_INTERCEPT_PREAD64
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000234INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000235 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000236 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000237 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000238 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000239 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000240 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
Kostya Serebryanyc8033192013-01-17 13:09:00 +0000241 if (res >= 0 && fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000242 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000243 return res;
244}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000245#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
Alexey Samsonovc333dff2012-12-13 08:10:23 +0000246#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000247#define INIT_PREAD64
Alexander Potapenko1f5e23e2012-12-12 11:52:26 +0000248#endif
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000249
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000250#if SANITIZER_INTERCEPT_READV
251INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
252 int iovcnt) {
253 void *ctx;
254 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000255 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000256 SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
257 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
258 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
259 return res;
260}
261#define INIT_READV INTERCEPT_FUNCTION(readv)
262#else
263#define INIT_READV
264#endif
265
266#if SANITIZER_INTERCEPT_PREADV
267INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
268 OFF_T offset) {
269 void *ctx;
270 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000271 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000272 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
273 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
274 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
275 return res;
276}
277#define INIT_PREADV INTERCEPT_FUNCTION(preadv)
278#else
279#define INIT_PREADV
280#endif
281
282#if SANITIZER_INTERCEPT_PREADV64
283INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
284 OFF64_T offset) {
285 void *ctx;
286 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000287 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000288 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
289 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
290 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
291 return res;
292}
293#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64)
294#else
295#define INIT_PREADV64
296#endif
297
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000298#if SANITIZER_INTERCEPT_WRITE
299INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000300 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000301 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000302 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000303 if (fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000304 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000305 SSIZE_T res = REAL(write)(fd, ptr, count);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000306 // FIXME: this check should be _before_ the call to REAL(write), not after
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000307 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000308 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000309 return res;
310}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000311#define INIT_WRITE INTERCEPT_FUNCTION(write)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000312#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000313#define INIT_WRITE
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000314#endif
315
316#if SANITIZER_INTERCEPT_PWRITE
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000317INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000318 void *ctx;
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000319 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000320 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000321 if (fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000322 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000323 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000324 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000325 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000326 return res;
327}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000328#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000329#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000330#define INIT_PWRITE
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000331#endif
332
333#if SANITIZER_INTERCEPT_PWRITE64
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000334INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
335 OFF64_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000336 void *ctx;
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000337 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000338 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000339 if (fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000340 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000341 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000342 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000343 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000344 return res;
345}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000346#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000347#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000348#define INIT_PWRITE64
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000349#endif
350
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000351#if SANITIZER_INTERCEPT_WRITEV
352INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
353 int iovcnt) {
354 void *ctx;
355 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000356 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000357 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
358 SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
359 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
360 return res;
361}
362#define INIT_WRITEV INTERCEPT_FUNCTION(writev)
363#else
364#define INIT_WRITEV
365#endif
366
367#if SANITIZER_INTERCEPT_PWRITEV
368INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
369 OFF_T offset) {
370 void *ctx;
371 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000372 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000373 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
374 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
375 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
376 return res;
377}
378#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev)
379#else
380#define INIT_PWRITEV
381#endif
382
383#if SANITIZER_INTERCEPT_PWRITEV64
384INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
385 OFF64_T offset) {
386 void *ctx;
387 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
Dmitry Vyukov67f55442013-10-11 14:13:11 +0000388 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000389 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
390 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
391 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
392 return res;
393}
394#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64)
395#else
396#define INIT_PWRITEV64
397#endif
398
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000399#if SANITIZER_INTERCEPT_PRCTL
Evgeniy Stepanov69b109a2013-02-20 11:06:07 +0000400INTERCEPTOR(int, prctl, int option,
401 unsigned long arg2, unsigned long arg3, // NOLINT
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000402 unsigned long arg4, unsigned long arg5) { // NOLINT
403 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000404 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000405 static const int PR_SET_NAME = 15;
406 int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
407 if (option == PR_SET_NAME) {
408 char buff[16];
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000409 internal_strncpy(buff, (char *)arg2, 15);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000410 buff[15] = 0;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000411 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000412 }
413 return res;
414}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000415#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000416#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000417#define INIT_PRCTL
418#endif // SANITIZER_INTERCEPT_PRCTL
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000419
Evgeniy Stepanovfef66052013-04-08 08:25:22 +0000420
421#if SANITIZER_INTERCEPT_TIME
422INTERCEPTOR(unsigned long, time, unsigned long *t) {
423 void *ctx;
424 COMMON_INTERCEPTOR_ENTER(ctx, time, t);
425 unsigned long res = REAL(time)(t);
Alexander Potapenko15832c22013-04-10 15:13:00 +0000426 if (t && res != (unsigned long)-1) {
Evgeniy Stepanovfef66052013-04-08 08:25:22 +0000427 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
428 }
429 return res;
430}
431#define INIT_TIME \
432 INTERCEPT_FUNCTION(time);
433#else
434#define INIT_TIME
435#endif // SANITIZER_INTERCEPT_TIME
436
437
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000438#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000439static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
Dmitry Vyukov0586dcc2013-10-03 14:12:09 +0000441 if (tm->tm_zone) {
442 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
443 // can point to shared memory and tsan would report a data race.
444 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone,
445 REAL(strlen(tm->tm_zone)) + 1);
446 }
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000447}
448
449INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000450 void *ctx;
451 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000452 __sanitizer_tm *res = REAL(localtime)(timep);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000453 if (res) {
454 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000455 unpoison_tm(ctx, res);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000456 }
457 return res;
458}
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000459INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000460 void *ctx;
461 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000462 __sanitizer_tm *res = REAL(localtime_r)(timep, result);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000463 if (res) {
464 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000465 unpoison_tm(ctx, res);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000466 }
467 return res;
468}
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000469INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000470 void *ctx;
471 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000472 __sanitizer_tm *res = REAL(gmtime)(timep);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000473 if (res) {
474 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000475 unpoison_tm(ctx, res);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000476 }
477 return res;
478}
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000479INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000480 void *ctx;
481 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000482 __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000483 if (res) {
484 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000485 unpoison_tm(ctx, res);
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000486 }
487 return res;
488}
489INTERCEPTOR(char *, ctime, unsigned long *timep) {
490 void *ctx;
491 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
492 char *res = REAL(ctime)(timep);
493 if (res) {
494 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
496 }
497 return res;
498}
499INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
500 void *ctx;
501 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
502 char *res = REAL(ctime_r)(timep, result);
503 if (res) {
504 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
505 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
506 }
507 return res;
508}
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000509INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000510 void *ctx;
511 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
512 char *res = REAL(asctime)(tm);
513 if (res) {
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000514 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000515 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
516 }
517 return res;
518}
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000519INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000520 void *ctx;
521 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
522 char *res = REAL(asctime_r)(tm, result);
523 if (res) {
Evgeniy Stepanovcf390322013-10-02 14:30:03 +0000524 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000525 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
526 }
527 return res;
528}
529#define INIT_LOCALTIME_AND_FRIENDS \
530 INTERCEPT_FUNCTION(localtime); \
531 INTERCEPT_FUNCTION(localtime_r); \
532 INTERCEPT_FUNCTION(gmtime); \
533 INTERCEPT_FUNCTION(gmtime_r); \
534 INTERCEPT_FUNCTION(ctime); \
535 INTERCEPT_FUNCTION(ctime_r); \
536 INTERCEPT_FUNCTION(asctime); \
537 INTERCEPT_FUNCTION(asctime_r);
538#else
539#define INIT_LOCALTIME_AND_FRIENDS
540#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
541
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000542#if SANITIZER_INTERCEPT_SCANF
543
Evgeniy Stepanov4f32c0b2013-01-18 13:01:18 +0000544#include "sanitizer_common_interceptors_scanf.inc"
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000545
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000546#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000547 { \
548 void *ctx; \
549 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
550 va_list aq; \
551 va_copy(aq, ap); \
552 int res = REAL(vname)(__VA_ARGS__); \
553 if (res > 0) \
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000554 scanf_common(ctx, res, allowGnuMalloc, format, aq); \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000555 va_end(aq); \
556 return res; \
557 }
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000558
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000559INTERCEPTOR(int, vscanf, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000560VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000561
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000562INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000563VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000564
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000565INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000566VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000567
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000568#if SANITIZER_INTERCEPT_ISOC99_SCANF
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000569INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000570VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000571
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000572INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
573 va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000574VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000575
576INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000577VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000578#endif // SANITIZER_INTERCEPT_ISOC99_SCANF
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000579
580#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \
581 { \
582 void *ctx; \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000583 va_list ap; \
584 va_start(ap, format); \
Dmitry Vyukov1c571df2013-09-26 18:38:54 +0000585 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000586 int res = vname(__VA_ARGS__, ap); \
587 va_end(ap); \
588 return res; \
589 }
590
591INTERCEPTOR(int, scanf, const char *format, ...)
592SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
593
594INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
595SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
596
597INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
598SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
599
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000600#if SANITIZER_INTERCEPT_ISOC99_SCANF
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000601INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
602SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
603
604INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
605SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
606
607INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
608SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000609#endif
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000610
Evgeniy Stepanovba150772013-08-22 13:59:15 +0000611#endif
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000612
Evgeniy Stepanovba150772013-08-22 13:59:15 +0000613#if SANITIZER_INTERCEPT_SCANF
614#define INIT_SCANF \
615 INTERCEPT_FUNCTION(scanf); \
616 INTERCEPT_FUNCTION(sscanf); \
617 INTERCEPT_FUNCTION(fscanf); \
618 INTERCEPT_FUNCTION(vscanf); \
619 INTERCEPT_FUNCTION(vsscanf); \
620 INTERCEPT_FUNCTION(vfscanf);
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000621#else
622#define INIT_SCANF
623#endif
624
Evgeniy Stepanovba150772013-08-22 13:59:15 +0000625#if SANITIZER_INTERCEPT_ISOC99_SCANF
626#define INIT_ISOC99_SCANF \
627 INTERCEPT_FUNCTION(__isoc99_scanf); \
628 INTERCEPT_FUNCTION(__isoc99_sscanf); \
629 INTERCEPT_FUNCTION(__isoc99_fscanf); \
630 INTERCEPT_FUNCTION(__isoc99_vscanf); \
631 INTERCEPT_FUNCTION(__isoc99_vsscanf); \
632 INTERCEPT_FUNCTION(__isoc99_vfscanf);
633#else
634#define INIT_ISOC99_SCANF
635#endif
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +0000636
Evgeniy Stepanov4e95e942013-06-07 13:19:33 +0000637#if SANITIZER_INTERCEPT_IOCTL
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +0000638#include "sanitizer_common_interceptors_ioctl.inc"
Evgeniy Stepanov4e95e942013-06-07 13:19:33 +0000639INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
640 void *ctx;
641 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
642
643 CHECK(ioctl_initialized);
644
645 // Note: TSan does not use common flags, and they are zero-initialized.
646 // This effectively disables ioctl handling in TSan.
647 if (!common_flags()->handle_ioctl)
648 return REAL(ioctl)(d, request, arg);
649
650 const ioctl_desc *desc = ioctl_lookup(request);
651 if (!desc)
652 Printf("WARNING: unknown ioctl %x\n", request);
653
654 if (desc)
655 ioctl_common_pre(ctx, desc, d, request, arg);
656 int res = REAL(ioctl)(d, request, arg);
657 // FIXME: some ioctls have different return values for success and failure.
658 if (desc && res != -1)
659 ioctl_common_post(ctx, desc, res, d, request, arg);
660 return res;
661}
Evgeniy Stepanov4ce6f792013-06-07 14:56:54 +0000662#define INIT_IOCTL \
663 ioctl_init(); \
664 INTERCEPT_FUNCTION(ioctl);
Evgeniy Stepanov4e95e942013-06-07 13:19:33 +0000665#else
666#define INIT_IOCTL
667#endif
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +0000668
669
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000670#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000671INTERCEPTOR(void *, getpwnam, const char *name) {
672 void *ctx;
673 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
674 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
675 void *res = REAL(getpwnam)(name);
676 if (res != 0)
677 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
678 return res;
679}
680INTERCEPTOR(void *, getpwuid, u32 uid) {
681 void *ctx;
682 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
683 void *res = REAL(getpwuid)(uid);
684 if (res != 0)
685 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
686 return res;
687}
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000688INTERCEPTOR(void *, getgrnam, const char *name) {
689 void *ctx;
690 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
691 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
692 void *res = REAL(getgrnam)(name);
693 if (res != 0)
694 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
695 return res;
696}
697INTERCEPTOR(void *, getgrgid, u32 gid) {
698 void *ctx;
699 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
700 void *res = REAL(getgrgid)(gid);
701 if (res != 0)
702 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
703 return res;
704}
705#define INIT_GETPWNAM_AND_FRIENDS \
706 INTERCEPT_FUNCTION(getpwnam); \
707 INTERCEPT_FUNCTION(getpwuid); \
708 INTERCEPT_FUNCTION(getgrnam); \
709 INTERCEPT_FUNCTION(getgrgid);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000710#else
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000711#define INIT_GETPWNAM_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000712#endif
713
714
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000715#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000716INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
717 char *buf, SIZE_T buflen, void **result) {
718 void *ctx;
719 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
720 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
721 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
722 if (!res) {
723 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
724 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
725 }
726 return res;
727}
728INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
729 char *buf, SIZE_T buflen, void **result) {
730 void *ctx;
731 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
732 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
733 if (!res) {
734 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
736 }
737 return res;
738}
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000739INTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
740 char *buf, SIZE_T buflen, void **result) {
741 void *ctx;
742 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
743 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
744 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
745 if (!res) {
746 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
747 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
748 }
749 return res;
750}
751INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
752 char *buf, SIZE_T buflen, void **result) {
753 void *ctx;
754 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
755 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
756 if (!res) {
757 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
758 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
759 }
760 return res;
761}
762#define INIT_GETPWNAM_R_AND_FRIENDS \
763 INTERCEPT_FUNCTION(getpwnam_r); \
764 INTERCEPT_FUNCTION(getpwuid_r); \
765 INTERCEPT_FUNCTION(getgrnam_r); \
766 INTERCEPT_FUNCTION(getgrgid_r);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000767#else
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000768#define INIT_GETPWNAM_R_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000769#endif
770
771
772#if SANITIZER_INTERCEPT_CLOCK_GETTIME
773INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
774 void *ctx;
775 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
776 int res = REAL(clock_getres)(clk_id, tp);
Evgeniy Stepanov7cdae162013-04-23 11:48:31 +0000777 if (!res && tp) {
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000778 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
779 }
780 return res;
781}
782INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
783 void *ctx;
784 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
785 int res = REAL(clock_gettime)(clk_id, tp);
786 if (!res) {
787 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
788 }
789 return res;
790}
791INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
792 void *ctx;
793 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
794 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
795 return REAL(clock_settime)(clk_id, tp);
796}
797#define INIT_CLOCK_GETTIME \
798 INTERCEPT_FUNCTION(clock_getres); \
799 INTERCEPT_FUNCTION(clock_gettime); \
800 INTERCEPT_FUNCTION(clock_settime);
801#else
802#define INIT_CLOCK_GETTIME
803#endif
804
805
806#if SANITIZER_INTERCEPT_GETITIMER
807INTERCEPTOR(int, getitimer, int which, void *curr_value) {
808 void *ctx;
809 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
810 int res = REAL(getitimer)(which, curr_value);
Evgeniy Stepanov39d68ed2013-08-06 09:54:33 +0000811 if (!res && curr_value) {
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000812 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
813 }
814 return res;
815}
816INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
817 void *ctx;
818 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
Evgeniy Stepanov39d68ed2013-08-06 09:54:33 +0000819 if (new_value)
820 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000821 int res = REAL(setitimer)(which, new_value, old_value);
822 if (!res && old_value) {
823 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
824 }
825 return res;
826}
827#define INIT_GETITIMER \
828 INTERCEPT_FUNCTION(getitimer); \
829 INTERCEPT_FUNCTION(setitimer);
830#else
831#define INIT_GETITIMER
832#endif
833
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000834#if SANITIZER_INTERCEPT_GLOB
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000835static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000836 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
837 // +1 for NULL pointer at the end.
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000838 if (pglob->gl_pathv)
839 COMMON_INTERCEPTOR_WRITE_RANGE(
840 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000841 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
842 char *p = pglob->gl_pathv[i];
843 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
844 }
845}
846
Timur Iskhodzhanoveaca82c2013-07-15 16:11:39 +0000847static THREADLOCAL __sanitizer_glob_t* pglob_copy;
Evgeniy Stepanov3fa122e2013-07-09 12:07:59 +0000848static THREADLOCAL void* glob_ctx;
849
850static void wrapped_gl_closedir(void *dir) {
851 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
852 pglob_copy->gl_closedir(dir);
853}
854
855static void *wrapped_gl_readdir(void *dir) {
856 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
857 return pglob_copy->gl_readdir(dir);
858}
859
860static void *wrapped_gl_opendir(const char *s) {
861 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
862 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
863 return pglob_copy->gl_opendir(s);
864}
865
866static int wrapped_gl_lstat(const char *s, void *st) {
867 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
868 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
869 return pglob_copy->gl_lstat(s, st);
870}
871
872static int wrapped_gl_stat(const char *s, void *st) {
873 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
874 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
875 return pglob_copy->gl_stat(s, st);
876}
877
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000878INTERCEPTOR(int, glob, const char *pattern, int flags,
879 int (*errfunc)(const char *epath, int eerrno),
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000880 __sanitizer_glob_t *pglob) {
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000881 void *ctx;
882 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
Evgeniy Stepanov3fa122e2013-07-09 12:07:59 +0000883 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
884 wrapped_gl_readdir, wrapped_gl_opendir,
885 wrapped_gl_lstat, wrapped_gl_stat};
886 if (flags & glob_altdirfunc) {
887 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
888 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
889 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
890 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
891 Swap(pglob->gl_stat, glob_copy.gl_stat);
892 pglob_copy = &glob_copy;
893 glob_ctx = ctx;
894 }
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000895 int res = REAL(glob)(pattern, flags, errfunc, pglob);
Evgeniy Stepanov3fa122e2013-07-09 12:07:59 +0000896 if (flags & glob_altdirfunc) {
897 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
898 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
899 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
900 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
901 Swap(pglob->gl_stat, glob_copy.gl_stat);
902 }
903 pglob_copy = 0;
904 glob_ctx = 0;
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000905 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000906 return res;
907}
908
909INTERCEPTOR(int, glob64, const char *pattern, int flags,
910 int (*errfunc)(const char *epath, int eerrno),
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000911 __sanitizer_glob_t *pglob) {
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000912 void *ctx;
913 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
Evgeniy Stepanov57876cf2013-07-09 12:34:25 +0000914 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
915 wrapped_gl_readdir, wrapped_gl_opendir,
916 wrapped_gl_lstat, wrapped_gl_stat};
917 if (flags & glob_altdirfunc) {
918 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
919 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
920 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
921 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
922 Swap(pglob->gl_stat, glob_copy.gl_stat);
923 pglob_copy = &glob_copy;
924 glob_ctx = ctx;
925 }
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000926 int res = REAL(glob64)(pattern, flags, errfunc, pglob);
Evgeniy Stepanov57876cf2013-07-09 12:34:25 +0000927 if (flags & glob_altdirfunc) {
928 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
929 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
930 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
931 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
932 Swap(pglob->gl_stat, glob_copy.gl_stat);
933 }
934 pglob_copy = 0;
935 glob_ctx = 0;
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000936 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000937 return res;
938}
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000939#define INIT_GLOB \
940 INTERCEPT_FUNCTION(glob); \
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000941 INTERCEPT_FUNCTION(glob64);
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000942#else // SANITIZER_INTERCEPT_GLOB
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000943#define INIT_GLOB
Evgeniy Stepanov906f2c12013-07-02 14:08:52 +0000944#endif // SANITIZER_INTERCEPT_GLOB
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000945
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000946#if SANITIZER_INTERCEPT_WAIT
Alexander Potapenko6a659df2013-05-20 13:32:35 +0000947// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
948// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
949// details.
950INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000951 void *ctx;
952 COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
953 int res = REAL(wait)(status);
Dmitry Vyukovf82eb242013-04-29 09:04:24 +0000954 if (res != -1 && status)
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
956 return res;
957}
Kostya Serebryany30e970f2013-05-22 08:54:30 +0000958INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
959 int options) {
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000960 void *ctx;
961 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
962 int res = REAL(waitid)(idtype, id, infop, options);
Dmitry Vyukovf82eb242013-04-29 09:04:24 +0000963 if (res != -1 && infop)
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000964 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
965 return res;
966}
Alexander Potapenko6a659df2013-05-20 13:32:35 +0000967INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000968 void *ctx;
969 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
970 int res = REAL(waitpid)(pid, status, options);
Dmitry Vyukovf82eb242013-04-29 09:04:24 +0000971 if (res != -1 && status)
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000972 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
973 return res;
974}
975INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
976 void *ctx;
977 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
978 int res = REAL(wait3)(status, options, rusage);
979 if (res != -1) {
Dmitry Vyukovf82eb242013-04-29 09:04:24 +0000980 if (status)
981 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000982 if (rusage)
983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
984 }
985 return res;
986}
987INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
988 void *ctx;
989 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
990 int res = REAL(wait4)(pid, status, options, rusage);
991 if (res != -1) {
Dmitry Vyukovf82eb242013-04-29 09:04:24 +0000992 if (status)
993 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000994 if (rusage)
995 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
996 }
997 return res;
998}
999#define INIT_WAIT \
1000 INTERCEPT_FUNCTION(wait); \
1001 INTERCEPT_FUNCTION(waitid); \
1002 INTERCEPT_FUNCTION(waitpid); \
1003 INTERCEPT_FUNCTION(wait3); \
1004 INTERCEPT_FUNCTION(wait4);
1005#else
1006#define INIT_WAIT
1007#endif
1008
Evgeniy Stepanov9530eb72013-04-23 14:05:15 +00001009#if SANITIZER_INTERCEPT_INET
1010INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
1011 void *ctx;
1012 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
1013 uptr sz = __sanitizer_in_addr_sz(af);
1014 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
1015 // FIXME: figure out read size based on the address family.
1016 char *res = REAL(inet_ntop)(af, src, dst, size);
1017 if (res)
1018 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1019 return res;
1020}
1021INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
1022 void *ctx;
1023 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
1024 // FIXME: figure out read size based on the address family.
1025 int res = REAL(inet_pton)(af, src, dst);
1026 if (res == 1) {
1027 uptr sz = __sanitizer_in_addr_sz(af);
1028 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1029 }
1030 return res;
1031}
1032#define INIT_INET \
1033 INTERCEPT_FUNCTION(inet_ntop); \
1034 INTERCEPT_FUNCTION(inet_pton);
1035#else
1036#define INIT_INET
1037#endif
1038
Evgeniy Stepanov9d600872013-06-24 13:56:14 +00001039#if SANITIZER_INTERCEPT_INET
1040INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
1041 void *ctx;
1042 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
1043 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
1044 int res = REAL(inet_aton)(cp, dst);
1045 if (res != 0) {
1046 uptr sz = __sanitizer_in_addr_sz(af_inet);
1047 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1048 }
1049 return res;
1050}
1051#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton);
1052#else
1053#define INIT_INET_ATON
1054#endif
1055
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00001056#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
1057INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
1058 void *ctx;
1059 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
1060 int res = REAL(pthread_getschedparam)(thread, policy, param);
1061 if (res == 0) {
1062 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
1063 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
1064 }
1065 return res;
1066}
1067#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
1068#else
1069#define INIT_PTHREAD_GETSCHEDPARAM
1070#endif
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +00001071
Evgeniy Stepanov447ef192013-05-22 12:50:26 +00001072#if SANITIZER_INTERCEPT_GETADDRINFO
1073INTERCEPTOR(int, getaddrinfo, char *node, char *service,
1074 struct __sanitizer_addrinfo *hints,
1075 struct __sanitizer_addrinfo **out) {
1076 void *ctx;
1077 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1078 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1079 if (service)
1080 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1081 if (hints)
1082 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
1083 int res = REAL(getaddrinfo)(node, service, hints, out);
Evgeniy Stepanov3538eb82013-05-28 14:34:37 +00001084 if (res == 0 && out) {
1085 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
Evgeniy Stepanov447ef192013-05-22 12:50:26 +00001086 struct __sanitizer_addrinfo *p = *out;
1087 while (p) {
Evgeniy Stepanov3538eb82013-05-28 14:34:37 +00001088 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
Evgeniy Stepanov447ef192013-05-22 12:50:26 +00001089 if (p->ai_addr)
Evgeniy Stepanov512c6162013-05-29 12:33:31 +00001090 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
Evgeniy Stepanov447ef192013-05-22 12:50:26 +00001091 if (p->ai_canonname)
1092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1093 REAL(strlen)(p->ai_canonname) + 1);
1094 p = p->ai_next;
1095 }
1096 }
1097 return res;
1098}
1099#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
1100#else
1101#define INIT_GETADDRINFO
1102#endif
1103
Evgeniy Stepanov9eedf482013-07-01 13:51:31 +00001104#if SANITIZER_INTERCEPT_GETNAMEINFO
1105INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
1106 unsigned hostlen, char *serv, unsigned servlen, int flags) {
1107 void *ctx;
1108 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
1109 serv, servlen, flags);
1110 // FIXME: consider adding READ_RANGE(sockaddr, salen)
1111 // There is padding in in_addr that may make this too noisy
1112 int res =
1113 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
1114 if (res == 0) {
1115 if (host && hostlen)
1116 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
1117 if (serv && servlen)
1118 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
1119 }
1120 return res;
1121}
1122#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo);
1123#else
1124#define INIT_GETNAMEINFO
1125#endif
1126
Evgeniy Stepanov9f58c5c2013-05-22 13:46:22 +00001127#if SANITIZER_INTERCEPT_GETSOCKNAME
1128INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
1129 void *ctx;
1130 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
1131 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1132 int addrlen_in = *addrlen;
1133 int res = REAL(getsockname)(sock_fd, addr, addrlen);
1134 if (res == 0) {
1135 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
1136 }
1137 return res;
1138}
1139#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
1140#else
1141#define INIT_GETSOCKNAME
1142#endif
Evgeniy Stepanov447ef192013-05-22 12:50:26 +00001143
Evgeniy Stepanov33b14852013-05-23 11:41:58 +00001144#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +00001145static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
1146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
1147 if (h->h_name)
1148 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
1149 char **p = h->h_aliases;
1150 while (*p) {
1151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
1152 ++p;
1153 }
1154 COMMON_INTERCEPTOR_WRITE_RANGE(
1155 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
1156 p = h->h_addr_list;
1157 while (*p) {
1158 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
1159 ++p;
1160 }
1161 COMMON_INTERCEPTOR_WRITE_RANGE(
1162 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
1163}
Evgeniy Stepanov33b14852013-05-23 11:41:58 +00001164#endif
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +00001165
1166#if SANITIZER_INTERCEPT_GETHOSTBYNAME
1167INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
1168 void *ctx;
1169 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
1170 struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
1171 if (res) write_hostent(ctx, res);
1172 return res;
1173}
1174
1175INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
1176 int type) {
1177 void *ctx;
1178 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
1179 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1180 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
1181 if (res) write_hostent(ctx, res);
1182 return res;
1183}
1184
Dmitry Vyukov1d02bea2013-10-02 14:04:23 +00001185INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +00001186 void *ctx;
Dmitry Vyukov1d02bea2013-10-02 14:04:23 +00001187 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
1188 struct __sanitizer_hostent *res = REAL(gethostent)(fake);
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +00001189 if (res) write_hostent(ctx, res);
1190 return res;
1191}
1192
1193INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
1194 void *ctx;
1195 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
1196 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
1197 if (res) write_hostent(ctx, res);
1198 return res;
1199}
1200#define INIT_GETHOSTBYNAME \
1201 INTERCEPT_FUNCTION(gethostent); \
1202 INTERCEPT_FUNCTION(gethostbyaddr); \
1203 INTERCEPT_FUNCTION(gethostbyname); \
1204 INTERCEPT_FUNCTION(gethostbyname2);
1205#else
1206#define INIT_GETHOSTBYNAME
1207#endif
1208
1209#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1210INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
1211 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
1212 void *ctx;
1213 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
1214 h_errnop);
1215 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
1216 if (res == 0) {
1217 if (result) {
1218 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1219 if (*result) write_hostent(ctx, *result);
1220 }
1221 if (h_errnop)
1222 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1223 }
1224 return res;
1225}
1226
1227INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
1228 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1229 __sanitizer_hostent **result, int *h_errnop) {
1230 void *ctx;
1231 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
1232 buflen, result, h_errnop);
1233 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1234 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
1235 h_errnop);
1236 if (res == 0) {
1237 if (result) {
1238 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1239 if (*result) write_hostent(ctx, *result);
1240 }
1241 if (h_errnop)
1242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1243 }
1244 return res;
1245}
1246
1247INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
1248 char *buf, SIZE_T buflen, __sanitizer_hostent **result,
1249 int *h_errnop) {
1250 void *ctx;
1251 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
1252 h_errnop);
1253 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
1254 if (res == 0) {
1255 if (result) {
1256 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1257 if (*result) write_hostent(ctx, *result);
1258 }
1259 if (h_errnop)
1260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1261 }
1262 return res;
1263}
1264
1265INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
1266 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1267 __sanitizer_hostent **result, int *h_errnop) {
1268 void *ctx;
1269 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
1270 result, h_errnop);
1271 int res =
1272 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
1273 if (res == 0) {
1274 if (result) {
1275 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1276 if (*result) write_hostent(ctx, *result);
1277 }
1278 if (h_errnop)
1279 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1280 }
1281 return res;
1282}
1283#define INIT_GETHOSTBYNAME_R \
1284 INTERCEPT_FUNCTION(gethostent_r); \
1285 INTERCEPT_FUNCTION(gethostbyaddr_r); \
1286 INTERCEPT_FUNCTION(gethostbyname_r); \
1287 INTERCEPT_FUNCTION(gethostbyname2_r);
1288#else
1289#define INIT_GETHOSTBYNAME_R
1290#endif
1291
Evgeniy Stepanovf32be422013-05-23 11:38:08 +00001292#if SANITIZER_INTERCEPT_GETSOCKOPT
1293INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1294 int *optlen) {
1295 void *ctx;
1296 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1297 optlen);
1298 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1299 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1300 if (res == 0)
1301 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1302 return res;
1303}
1304#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
1305#else
1306#define INIT_GETSOCKOPT
1307#endif
1308
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +00001309#if SANITIZER_INTERCEPT_ACCEPT
1310INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
1311 void *ctx;
1312 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
1313 unsigned addrlen0;
1314 if (addrlen) {
1315 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1316 addrlen0 = *addrlen;
1317 }
1318 int fd2 = REAL(accept)(fd, addr, addrlen);
1319 if (fd2 >= 0) {
1320 if (fd >= 0)
1321 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1322 if (addr && addrlen)
1323 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1324 }
1325 return fd2;
1326}
1327#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
1328#else
1329#define INIT_ACCEPT
1330#endif
1331
1332#if SANITIZER_INTERCEPT_ACCEPT4
1333INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
1334 void *ctx;
1335 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
1336 unsigned addrlen0;
1337 if (addrlen) {
1338 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1339 addrlen0 = *addrlen;
1340 }
1341 int fd2 = REAL(accept4)(fd, addr, addrlen, f);
1342 if (fd2 >= 0) {
1343 if (fd >= 0)
1344 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1345 if (addr && addrlen)
1346 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1347 }
1348 return fd2;
1349}
1350#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
1351#else
1352#define INIT_ACCEPT4
1353#endif
1354
Evgeniy Stepanovc87088b2013-05-29 10:03:11 +00001355#if SANITIZER_INTERCEPT_MODF
1356INTERCEPTOR(double, modf, double x, double *iptr) {
1357 void *ctx;
1358 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1359 double res = REAL(modf)(x, iptr);
1360 if (iptr) {
1361 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1362 }
1363 return res;
1364}
1365INTERCEPTOR(float, modff, float x, float *iptr) {
1366 void *ctx;
1367 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1368 float res = REAL(modff)(x, iptr);
1369 if (iptr) {
1370 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1371 }
1372 return res;
1373}
1374INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1375 void *ctx;
1376 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1377 long double res = REAL(modfl)(x, iptr);
1378 if (iptr) {
1379 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1380 }
1381 return res;
1382}
1383#define INIT_MODF \
1384 INTERCEPT_FUNCTION(modf); \
1385 INTERCEPT_FUNCTION(modff); \
1386 INTERCEPT_FUNCTION(modfl);
1387#else
1388#define INIT_MODF
1389#endif
1390
Evgeniy Stepanov9666d892013-05-29 11:30:00 +00001391#if SANITIZER_INTERCEPT_RECVMSG
Evgeniy Stepanoveb7c24b2013-06-26 09:16:45 +00001392static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
1393 SSIZE_T maxlen) {
Evgeniy Stepanov9666d892013-05-29 11:30:00 +00001394 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
Evgeniy Stepanovab8bf092013-10-17 11:32:30 +00001395 if (msg->msg_name && msg->msg_namelen)
1396 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
1397 if (msg->msg_iov && msg->msg_iovlen)
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +00001398 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
1399 sizeof(*msg->msg_iov) * msg->msg_iovlen);
1400 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
Evgeniy Stepanovab8bf092013-10-17 11:32:30 +00001401 if (msg->msg_control && msg->msg_controllen)
Evgeniy Stepanov9666d892013-05-29 11:30:00 +00001402 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
1403}
1404
1405INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
1406 int flags) {
1407 void *ctx;
1408 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
1409 SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
1410 if (res >= 0) {
1411 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +00001412 if (msg) write_msghdr(ctx, msg, res);
Evgeniy Stepanov9666d892013-05-29 11:30:00 +00001413 }
1414 return res;
1415}
1416#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
1417#else
1418#define INIT_RECVMSG
1419#endif
1420
Evgeniy Stepanovbc33e132013-05-29 11:49:25 +00001421#if SANITIZER_INTERCEPT_GETPEERNAME
1422INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1423 void *ctx;
1424 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1425 unsigned addr_sz;
1426 if (addrlen) addr_sz = *addrlen;
1427 int res = REAL(getpeername)(sockfd, addr, addrlen);
1428 if (!res && addr && addrlen)
1429 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1430 return res;
1431}
1432#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1433#else
1434#define INIT_GETPEERNAME
1435#endif
1436
Evgeniy Stepanov359d7fc2013-06-24 14:25:33 +00001437#if SANITIZER_INTERCEPT_SYSINFO
1438INTERCEPTOR(int, sysinfo, void *info) {
1439 void *ctx;
1440 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
1441 int res = REAL(sysinfo)(info);
1442 if (!res && info)
1443 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
1444 return res;
1445}
1446#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo);
1447#else
1448#define INIT_SYSINFO
1449#endif
1450
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001451#if SANITIZER_INTERCEPT_READDIR
Evgeniy Stepanova0379b52013-06-27 09:37:27 +00001452INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001453 void *ctx;
1454 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
Evgeniy Stepanova0379b52013-06-27 09:37:27 +00001455 __sanitizer_dirent *res = REAL(readdir)(dirp);
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001456 if (res)
Evgeniy Stepanova0379b52013-06-27 09:37:27 +00001457 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001458 return res;
1459}
1460
Alexey Samsonov52d08d82013-06-28 12:13:31 +00001461INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
1462 __sanitizer_dirent **result) {
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001463 void *ctx;
1464 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
1465 int res = REAL(readdir_r)(dirp, entry, result);
1466 if (!res) {
Chandler Carruth5a482cd2013-07-11 18:51:40 +00001467 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1468 if (*result)
1469 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001470 }
1471 return res;
1472}
1473
1474#define INIT_READDIR \
1475 INTERCEPT_FUNCTION(readdir); \
1476 INTERCEPT_FUNCTION(readdir_r);
1477#else
1478#define INIT_READDIR
1479#endif
1480
1481#if SANITIZER_INTERCEPT_READDIR64
Evgeniy Stepanova0379b52013-06-27 09:37:27 +00001482INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001483 void *ctx;
1484 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
Evgeniy Stepanova0379b52013-06-27 09:37:27 +00001485 __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001486 if (res)
Evgeniy Stepanova0379b52013-06-27 09:37:27 +00001487 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001488 return res;
1489}
1490
Alexey Samsonov52d08d82013-06-28 12:13:31 +00001491INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
1492 __sanitizer_dirent64 **result) {
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001493 void *ctx;
1494 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
1495 int res = REAL(readdir64_r)(dirp, entry, result);
1496 if (!res) {
Chandler Carruth5a482cd2013-07-11 18:51:40 +00001497 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1498 if (*result)
1499 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001500 }
1501 return res;
1502}
1503#define INIT_READDIR64 \
1504 INTERCEPT_FUNCTION(readdir64); \
1505 INTERCEPT_FUNCTION(readdir64_r);
1506#else
1507#define INIT_READDIR64
1508#endif
1509
Evgeniy Stepanov341b9e62013-06-28 11:02:43 +00001510#if SANITIZER_INTERCEPT_PTRACE
1511INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
1512 void *ctx;
1513 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
1514
1515 if (data) {
1516 if (request == ptrace_setregs)
1517 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
1518 else if (request == ptrace_setfpregs)
1519 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1520 else if (request == ptrace_setfpxregs)
1521 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1522 else if (request == ptrace_setsiginfo)
1523 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
1524 else if (request == ptrace_setregset) {
1525 __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1526 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
1527 }
1528 }
1529
1530 uptr res = REAL(ptrace)(request, pid, addr, data);
1531
1532 if (!res && data) {
1533 // Note that PEEK* requests assing different meaning to the return value.
1534 // This function does not handle them (nor does it need to).
1535 if (request == ptrace_getregs)
1536 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
1537 else if (request == ptrace_getfpregs)
1538 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1539 else if (request == ptrace_getfpxregs)
1540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1541 else if (request == ptrace_getsiginfo)
1542 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
1543 else if (request == ptrace_getregset) {
1544 __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1545 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
1546 }
1547 }
1548 return res;
1549}
1550
1551#define INIT_PTRACE \
1552 INTERCEPT_FUNCTION(ptrace);
1553#else
1554#define INIT_PTRACE
1555#endif
1556
Evgeniy Stepanov3cae6042013-07-02 09:23:45 +00001557#if SANITIZER_INTERCEPT_SETLOCALE
1558INTERCEPTOR(char *, setlocale, int category, char *locale) {
1559 void *ctx;
1560 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
1561 if (locale)
1562 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
Evgeniy Stepanov80144892013-07-02 13:34:44 +00001563 char *res = REAL(setlocale)(category, locale);
Evgeniy Stepanov3cae6042013-07-02 09:23:45 +00001564 if (res)
1565 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1566 return res;
1567}
1568
1569#define INIT_SETLOCALE \
1570 INTERCEPT_FUNCTION(setlocale);
1571#else
1572#define INIT_SETLOCALE
1573#endif
1574
Evgeniy Stepanov80144892013-07-02 13:34:44 +00001575#if SANITIZER_INTERCEPT_GETCWD
1576INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
1577 void *ctx;
1578 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
1579 char *res = REAL(getcwd)(buf, size);
1580 if (res)
1581 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1582 return res;
1583}
1584#define INIT_GETCWD \
1585 INTERCEPT_FUNCTION(getcwd);
1586#else
1587#define INIT_GETCWD
1588#endif
1589
1590#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
Dmitry Vyukov1d02bea2013-10-02 14:04:23 +00001591INTERCEPTOR(char *, get_current_dir_name, int fake) {
Evgeniy Stepanov80144892013-07-02 13:34:44 +00001592 void *ctx;
Dmitry Vyukov1d02bea2013-10-02 14:04:23 +00001593 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
1594 char *res = REAL(get_current_dir_name)(fake);
Evgeniy Stepanov80144892013-07-02 13:34:44 +00001595 if (res)
1596 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1597 return res;
1598}
1599
1600#define INIT_GET_CURRENT_DIR_NAME \
1601 INTERCEPT_FUNCTION(get_current_dir_name);
1602#else
1603#define INIT_GET_CURRENT_DIR_NAME
1604#endif
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001605
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001606#if SANITIZER_INTERCEPT_STRTOIMAX
1607INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
1608 void *ctx;
1609 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
1610 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
1611 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1612 return res;
1613}
1614
1615INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
1616 void *ctx;
1617 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
1618 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
1619 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1620 return res;
1621}
1622
1623#define INIT_STRTOIMAX \
1624 INTERCEPT_FUNCTION(strtoimax); \
1625 INTERCEPT_FUNCTION(strtoumax);
1626#else
1627#define INIT_STRTOIMAX
1628#endif
1629
1630#if SANITIZER_INTERCEPT_MBSTOWCS
1631INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
1632 void *ctx;
1633 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
1634 SIZE_T res = REAL(mbstowcs)(dest, src, len);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001635 if (res != (SIZE_T) - 1 && dest) {
Alexey Samsonove43d2102013-07-12 11:59:58 +00001636 SIZE_T write_cnt = res + (res < len);
1637 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1638 }
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001639 return res;
1640}
1641
1642INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
1643 void *ps) {
1644 void *ctx;
1645 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001646 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1647 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
Chandler Carruth5a482cd2013-07-11 18:51:40 +00001648 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001649 if (res != (SIZE_T)(-1) && dest && src) {
1650 // This function, and several others, may or may not write the terminating
1651 // \0 character. They write it iff they clear *src.
1652 SIZE_T write_cnt = res + !*src;
Alexey Samsonove43d2102013-07-12 11:59:58 +00001653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1654 }
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001655 return res;
1656}
1657
1658#define INIT_MBSTOWCS \
1659 INTERCEPT_FUNCTION(mbstowcs); \
1660 INTERCEPT_FUNCTION(mbsrtowcs);
1661#else
1662#define INIT_MBSTOWCS
1663#endif
1664
1665#if SANITIZER_INTERCEPT_MBSNRTOWCS
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001666INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
1667 SIZE_T len, void *ps) {
1668 void *ctx;
1669 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001670 if (src) {
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001671 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001672 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001673 }
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001674 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001675 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001676 if (res != (SIZE_T)(-1) && dest && src) {
1677 SIZE_T write_cnt = res + !*src;
Alexey Samsonove43d2102013-07-12 11:59:58 +00001678 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1679 }
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001680 return res;
1681}
1682
1683#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs);
1684#else
1685#define INIT_MBSNRTOWCS
1686#endif
1687
1688#if SANITIZER_INTERCEPT_WCSTOMBS
1689INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
1690 void *ctx;
1691 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
1692 SIZE_T res = REAL(wcstombs)(dest, src, len);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001693 if (res != (SIZE_T) - 1 && dest) {
Alexey Samsonove43d2102013-07-12 11:59:58 +00001694 SIZE_T write_cnt = res + (res < len);
1695 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1696 }
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001697 return res;
1698}
1699
1700INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
1701 void *ps) {
1702 void *ctx;
1703 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001704 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1705 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
Chandler Carruth5a482cd2013-07-11 18:51:40 +00001706 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001707 if (res != (SIZE_T) - 1 && dest && src) {
1708 SIZE_T write_cnt = res + !*src;
Alexey Samsonove43d2102013-07-12 11:59:58 +00001709 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1710 }
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001711 return res;
1712}
1713
1714#define INIT_WCSTOMBS \
1715 INTERCEPT_FUNCTION(wcstombs); \
1716 INTERCEPT_FUNCTION(wcsrtombs);
1717#else
1718#define INIT_WCSTOMBS
1719#endif
1720
1721#if SANITIZER_INTERCEPT_WCSNRTOMBS
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001722INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
1723 SIZE_T len, void *ps) {
1724 void *ctx;
1725 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001726 if (src) {
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001727 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001728 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001729 }
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001730 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001731 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
Alexey Samsonov098c58f2013-07-12 12:33:23 +00001732 if (res != (SIZE_T) - 1 && dest && src) {
1733 SIZE_T write_cnt = res + !*src;
Alexey Samsonove43d2102013-07-12 11:59:58 +00001734 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1735 }
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001736 return res;
1737}
1738
1739#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs);
1740#else
1741#define INIT_WCSNRTOMBS
1742#endif
1743
Evgeniy Stepanovea727682013-07-04 14:03:31 +00001744
1745#if SANITIZER_INTERCEPT_TCGETATTR
1746INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
1747 void *ctx;
1748 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
1749 int res = REAL(tcgetattr)(fd, termios_p);
1750 if (!res && termios_p)
1751 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
1752 return res;
1753}
1754
1755#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr);
1756#else
1757#define INIT_TCGETATTR
1758#endif
1759
Evgeniy Stepanov12eb79d2013-07-09 09:53:37 +00001760
1761#if SANITIZER_INTERCEPT_REALPATH
1762INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
1763 void *ctx;
1764 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
1765 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1766
1767 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
1768 // version of a versioned symbol. For realpath(), this gives us something
1769 // (called __old_realpath) that does not handle NULL in the second argument.
1770 // Handle it as part of the interceptor.
1771 char *allocated_path = 0;
1772 if (!resolved_path)
1773 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
1774
1775 char *res = REAL(realpath)(path, resolved_path);
1776 if (allocated_path && !res)
1777 WRAP(free)(allocated_path);
1778 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1779 return res;
1780}
1781#define INIT_REALPATH INTERCEPT_FUNCTION(realpath);
1782#else
1783#define INIT_REALPATH
1784#endif
1785
1786#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
1787INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
1788 void *ctx;
1789 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
1790 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1791 char *res = REAL(canonicalize_file_name)(path);
1792 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1793 return res;
1794}
1795#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name);
1796#else
1797#define INIT_CANONICALIZE_FILE_NAME
1798#endif
1799
Evgeniy Stepanov5ec19bc2013-07-30 12:46:59 +00001800#if SANITIZER_INTERCEPT_CONFSTR
1801INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
1802 void *ctx;
1803 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
1804 SIZE_T res = REAL(confstr)(name, buf, len);
1805 if (buf && res)
1806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
1807 return res;
1808}
1809#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr);
1810#else
1811#define INIT_CONFSTR
1812#endif
1813
Evgeniy Stepanov84ba74c2013-08-07 09:10:16 +00001814#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
1815INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
1816 void *ctx;
1817 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
1818 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
1819 if (mask && !res)
1820 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
1821 return res;
1822}
1823#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity);
1824#else
1825#define INIT_SCHED_GETAFFINITY
1826#endif
1827
Evgeniy Stepanov12049792013-08-08 11:44:05 +00001828#if SANITIZER_INTERCEPT_STRERROR
1829INTERCEPTOR(char *, strerror, int errnum) {
1830 void *ctx;
1831 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
1832 char *res = REAL(strerror)(errnum);
1833 if (res)
Dmitry Vyukov3e5c47d2013-10-21 07:40:19 +00001834 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
Evgeniy Stepanov12049792013-08-08 11:44:05 +00001835 return res;
1836}
1837#define INIT_STRERROR INTERCEPT_FUNCTION(strerror);
1838#else
1839#define INIT_STRERROR
1840#endif
1841
1842#if SANITIZER_INTERCEPT_STRERROR_R
1843INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
1844 void *ctx;
1845 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
1846 char *res = REAL(strerror_r)(errnum, buf, buflen);
1847 // There are 2 versions of strerror_r:
1848 // * POSIX version returns 0 on success, negative error code on failure,
1849 // writes message to buf.
1850 // * GNU version returns message pointer, which points to either buf or some
1851 // static storage.
Evgeniy Stepanovd9a5e242013-09-09 08:58:54 +00001852 SIZE_T posix_res = (SIZE_T)res;
1853 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
Evgeniy Stepanov12049792013-08-08 11:44:05 +00001854 // POSIX version. Spec is not clear on whether buf is NULL-terminated.
Evgeniy Stepanovd9a5e242013-09-09 08:58:54 +00001855 // At least on OSX, buf contents are valid even when the call fails.
Evgeniy Stepanov12049792013-08-08 11:44:05 +00001856 SIZE_T sz = internal_strnlen(buf, buflen);
1857 if (sz < buflen) ++sz;
1858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
Evgeniy Stepanovd9a5e242013-09-09 08:58:54 +00001859 } else {
Evgeniy Stepanov12049792013-08-08 11:44:05 +00001860 // GNU version.
1861 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1862 }
1863 return res;
1864}
1865#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r);
1866#else
1867#define INIT_STRERROR_R
1868#endif
1869
Evgeniy Stepanov224226c2013-08-08 13:57:15 +00001870#if SANITIZER_INTERCEPT_SCANDIR
1871typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
1872typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
1873 const struct __sanitizer_dirent **);
1874
1875static THREADLOCAL void *scandir_ctx;
1876static THREADLOCAL scandir_filter_f scandir_filter;
1877static THREADLOCAL scandir_compar_f scandir_compar;
1878
1879static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
1880 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1);
1881 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen);
1882 return scandir_filter(dir);
1883}
1884
1885static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
1886 const struct __sanitizer_dirent **b) {
1887 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2);
1888 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a));
1889 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen);
1890 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b));
1891 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen);
1892 return scandir_compar(a, b);
1893}
1894
1895INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
1896 scandir_filter_f filter, scandir_compar_f compar) {
1897 void *ctx;
1898 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
1899 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
Alexey Samsonov5bd21742013-08-23 07:43:56 +00001900 CHECK_EQ(0, scandir_ctx);
Evgeniy Stepanov224226c2013-08-08 13:57:15 +00001901 scandir_ctx = ctx;
1902 scandir_filter = filter;
1903 scandir_compar = compar;
1904 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0,
1905 compar ? wrapped_scandir_compar : 0);
1906 scandir_ctx = 0;
1907 scandir_filter = 0;
1908 scandir_compar = 0;
1909 if (namelist && res > 0) {
1910 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
1911 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
1912 for (int i = 0; i < res; ++i)
1913 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
1914 (*namelist)[i]->d_reclen);
1915 }
1916 return res;
1917}
1918#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir);
1919#else
1920#define INIT_SCANDIR
1921#endif
1922
1923#if SANITIZER_INTERCEPT_SCANDIR64
1924typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
1925typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
1926 const struct __sanitizer_dirent64 **);
1927
1928static THREADLOCAL void *scandir64_ctx;
1929static THREADLOCAL scandir64_filter_f scandir64_filter;
1930static THREADLOCAL scandir64_compar_f scandir64_compar;
1931
1932static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
1933 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1);
1934 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen);
1935 return scandir64_filter(dir);
1936}
1937
1938static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
1939 const struct __sanitizer_dirent64 **b) {
1940 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2);
1941 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a));
1942 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen);
1943 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b));
1944 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen);
1945 return scandir64_compar(a, b);
1946}
1947
1948INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
1949 scandir64_filter_f filter, scandir64_compar_f compar) {
1950 void *ctx;
1951 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
1952 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
Alexey Samsonov5bd21742013-08-23 07:43:56 +00001953 CHECK_EQ(0, scandir64_ctx);
Evgeniy Stepanov224226c2013-08-08 13:57:15 +00001954 scandir64_ctx = ctx;
1955 scandir64_filter = filter;
1956 scandir64_compar = compar;
1957 int res =
1958 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0,
1959 compar ? wrapped_scandir64_compar : 0);
1960 scandir64_ctx = 0;
1961 scandir64_filter = 0;
1962 scandir64_compar = 0;
1963 if (namelist && res > 0) {
1964 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
1965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
1966 for (int i = 0; i < res; ++i)
1967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
1968 (*namelist)[i]->d_reclen);
1969 }
1970 return res;
1971}
1972#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64);
1973#else
1974#define INIT_SCANDIR64
1975#endif
1976
Evgeniy Stepanovedff34b2013-08-12 11:01:40 +00001977#if SANITIZER_INTERCEPT_GETGROUPS
1978INTERCEPTOR(int, getgroups, int size, u32 *lst) {
1979 void *ctx;
1980 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
1981 int res = REAL(getgroups)(size, lst);
1982 if (res && lst)
1983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
1984 return res;
1985}
1986#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups);
1987#else
1988#define INIT_GETGROUPS
1989#endif
1990
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +00001991#if SANITIZER_INTERCEPT_POLL
1992static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
1993 __sanitizer_nfds_t nfds) {
1994 for (unsigned i = 0; i < nfds; ++i) {
1995 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
1996 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
1997 }
1998}
1999
2000static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
2001 __sanitizer_nfds_t nfds) {
2002 for (unsigned i = 0; i < nfds; ++i)
Alexey Samsonov5bd21742013-08-23 07:43:56 +00002003 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
2004 sizeof(fds[i].revents));
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +00002005}
2006
2007INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2008 int timeout) {
2009 void *ctx;
2010 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
2011 if (fds && nfds) read_pollfd(ctx, fds, nfds);
2012 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
2013 if (fds && nfds) write_pollfd(ctx, fds, nfds);
2014 return res;
2015}
2016#define INIT_POLL INTERCEPT_FUNCTION(poll);
2017#else
2018#define INIT_POLL
2019#endif
2020
2021#if SANITIZER_INTERCEPT_PPOLL
2022INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
Evgeniy Stepanovb32d1bf2013-08-27 11:10:04 +00002023 void *timeout_ts, __sanitizer_sigset_t *sigmask) {
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +00002024 void *ctx;
2025 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
2026 if (fds && nfds) read_pollfd(ctx, fds, nfds);
2027 if (timeout_ts)
2028 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
Evgeniy Stepanovb32d1bf2013-08-27 11:10:04 +00002029 // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +00002030 int res =
2031 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
2032 if (fds && nfds) write_pollfd(ctx, fds, nfds);
2033 return res;
2034}
2035#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll);
2036#else
2037#define INIT_PPOLL
2038#endif
2039
Evgeniy Stepanovc5a38552013-09-24 14:38:22 +00002040#if SANITIZER_INTERCEPT_WORDEXP
2041INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
2042 void *ctx;
2043 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
2044 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
2045 int res = REAL(wordexp)(s, p, flags);
2046 if (!res && p) {
2047 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2048 if (p->we_wordc)
2049 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
2050 sizeof(*p->we_wordv) * p->we_wordc);
2051 for (uptr i = 0; i < p->we_wordc; ++i) {
2052 char *w = p->we_wordv[i];
2053 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
2054 }
2055 }
2056 return res;
2057}
2058#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp);
2059#else
2060#define INIT_WORDEXP
2061#endif
2062
Evgeniy Stepanov9a949a82013-09-25 14:47:43 +00002063#if SANITIZER_INTERCEPT_SIGWAIT
2064INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
2065 void *ctx;
2066 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
2067 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2068 int res = REAL(sigwait)(set, sig);
2069 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
2070 return res;
2071}
2072#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait);
2073#else
2074#define INIT_SIGWAIT
2075#endif
2076
2077#if SANITIZER_INTERCEPT_SIGWAITINFO
2078INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
2079 void *ctx;
2080 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
2081 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2082 int res = REAL(sigwaitinfo)(set, info);
2083 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2084 return res;
2085}
2086#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo);
2087#else
2088#define INIT_SIGWAITINFO
2089#endif
2090
2091#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
2092INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
2093 void *timeout) {
2094 void *ctx;
2095 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
2096 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
2097 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2098 int res = REAL(sigtimedwait)(set, info, timeout);
2099 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2100 return res;
2101}
2102#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait);
2103#else
2104#define INIT_SIGTIMEDWAIT
2105#endif
2106
2107#if SANITIZER_INTERCEPT_SIGSETOPS
2108INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
2109 void *ctx;
2110 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
2111 int res = REAL(sigemptyset)(set);
2112 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2113 return res;
2114}
2115
2116INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
2117 void *ctx;
2118 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
2119 int res = REAL(sigfillset)(set);
2120 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2121 return res;
2122}
2123#define INIT_SIGSETOPS \
2124 INTERCEPT_FUNCTION(sigemptyset); \
2125 INTERCEPT_FUNCTION(sigfillset);
2126#else
2127#define INIT_SIGSETOPS
2128#endif
2129
2130#if SANITIZER_INTERCEPT_SIGPENDING
2131INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
2132 void *ctx;
2133 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
2134 int res = REAL(sigpending)(set);
2135 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2136 return res;
2137}
2138#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending);
2139#else
2140#define INIT_SIGPENDING
2141#endif
2142
2143#if SANITIZER_INTERCEPT_SIGPROCMASK
2144INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
2145 __sanitizer_sigset_t *oldset) {
2146 void *ctx;
2147 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
2148 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2149 int res = REAL(sigprocmask)(how, set, oldset);
2150 if (!res && oldset)
2151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
2152 return res;
2153}
2154#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask);
2155#else
2156#define INIT_SIGPROCMASK
2157#endif
2158
Evgeniy Stepanov1394be12013-09-27 12:40:23 +00002159#if SANITIZER_INTERCEPT_BACKTRACE
2160INTERCEPTOR(int, backtrace, void **buffer, int size) {
2161 void *ctx;
2162 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
2163 int res = REAL(backtrace)(buffer, size);
2164 if (res && buffer)
2165 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
2166 return res;
2167}
2168
2169INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
2170 void *ctx;
2171 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
2172 if (buffer && size)
2173 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
2174 char ** res = REAL(backtrace_symbols)(buffer, size);
2175 if (res && size) {
2176 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
2177 for (int i = 0; i < size; ++i)
2178 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
2179 }
2180 return res;
2181}
2182#define INIT_BACKTRACE \
2183 INTERCEPT_FUNCTION(backtrace); \
2184 INTERCEPT_FUNCTION(backtrace_symbols);
2185#else
2186#define INIT_BACKTRACE
2187#endif
2188
Dmitry Vyukov14dd9802013-10-03 15:22:29 +00002189#if SANITIZER_INTERCEPT__EXIT
2190INTERCEPTOR(void, _exit, int status) {
2191 void *ctx;
2192 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
2193 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
2194 if (status == 0)
2195 status = status1;
2196 REAL(_exit)(status);
2197}
2198#define INIT__EXIT INTERCEPT_FUNCTION(_exit);
2199#else
2200#define INIT__EXIT
2201#endif
2202
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002203#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
2204INTERCEPTOR(int, pthread_mutex_lock, void *m) {
2205 void *ctx;
2206 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
2207 int res = REAL(pthread_mutex_lock)(m);
2208 if (res == 0)
2209 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2210 return res;
2211}
2212
2213INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
2214 void *ctx;
2215 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
2216 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2217 return REAL(pthread_mutex_unlock)(m);
2218}
2219
2220#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock)
2221#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock)
2222#else
2223#define INIT_PTHREAD_MUTEX_LOCK
2224#define INIT_PTHREAD_MUTEX_UNLOCK
2225#endif
2226
2227#if SANITIZER_INTERCEPT_PTHREAD_COND
2228INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {
2229 void *ctx;
2230 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m);
2231 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2232 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2233 int res = REAL(pthread_cond_wait)(c, m);
2234 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2235 return res;
2236}
2237
2238INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
2239 void *ctx;
2240 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a);
2241 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz);
2242 return REAL(pthread_cond_init)(c, a);
2243}
2244
Alexey Samsonovfc813462013-10-17 09:24:03 +00002245INTERCEPTOR(int, pthread_cond_signal, void *c) {
2246 void *ctx;
2247 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c);
2248 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2249 return REAL(pthread_cond_signal)(c);
2250}
2251
2252INTERCEPTOR(int, pthread_cond_broadcast, void *c) {
2253 void *ctx;
2254 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c);
2255 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2256 return REAL(pthread_cond_broadcast)(c);
2257}
2258
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002259#define INIT_PTHREAD_COND_WAIT \
2260 INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2)
2261#define INIT_PTHREAD_COND_INIT \
2262 INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2)
Alexey Samsonovfc813462013-10-17 09:24:03 +00002263#define INIT_PTHREAD_COND_SIGNAL \
2264 INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2)
2265#define INIT_PTHREAD_COND_BROADCAST \
2266 INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2)
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002267#else
2268#define INIT_PTHREAD_COND_WAIT
2269#define INIT_PTHREAD_COND_INIT
Alexey Samsonovfc813462013-10-17 09:24:03 +00002270#define INIT_PTHREAD_COND_SIGNAL
2271#define INIT_PTHREAD_COND_BROADCAST
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002272#endif
2273
Evgeniy Stepanov4d7297d2013-10-18 09:41:43 +00002274#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
2275static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
2276 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
2277 if (mnt->mnt_fsname)
2278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
2279 REAL(strlen)(mnt->mnt_fsname) + 1);
2280 if (mnt->mnt_dir)
2281 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
2282 REAL(strlen)(mnt->mnt_dir) + 1);
2283 if (mnt->mnt_type)
2284 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
2285 REAL(strlen)(mnt->mnt_type) + 1);
2286 if (mnt->mnt_opts)
2287 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
2288 REAL(strlen)(mnt->mnt_opts) + 1);
2289}
2290#endif
2291
2292#if SANITIZER_INTERCEPT_GETMNTENT
2293INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
2294 void *ctx;
2295 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
2296 __sanitizer_mntent *res = REAL(getmntent)(fp);
2297 if (res) write_mntent(ctx, res);
2298 return res;
2299}
2300#define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent);
2301#else
2302#define INIT_GETMNTENT
2303#endif
2304
2305#if SANITIZER_INTERCEPT_GETMNTENT_R
2306INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
2307 __sanitizer_mntent *mntbuf, char *buf, int buflen) {
2308 void *ctx;
2309 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
2310 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
2311 if (res) write_mntent(ctx, res);
2312 return res;
2313}
2314#define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r);
2315#else
2316#define INIT_GETMNTENT_R
2317#endif
2318
Evgeniy Stepanov5cee73e2013-10-18 11:14:16 +00002319#if SANITIZER_INTERCEPT_STATFS
2320INTERCEPTOR(int, statfs, char *path, void *buf) {
2321 void *ctx;
2322 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
2323 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2324 int res = REAL(statfs)(path, buf);
2325 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
2326 return res;
2327}
2328INTERCEPTOR(int, fstatfs, int fd, void *buf) {
2329 void *ctx;
2330 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
2331 int res = REAL(fstatfs)(fd, buf);
2332 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
2333 return res;
2334}
2335#define INIT_STATFS \
2336 INTERCEPT_FUNCTION(statfs); \
2337 INTERCEPT_FUNCTION(fstatfs);
2338#else
2339#define INIT_STATFS
2340#endif
2341
2342#if SANITIZER_INTERCEPT_STATFS64
2343INTERCEPTOR(int, statfs64, char *path, void *buf) {
2344 void *ctx;
2345 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
2346 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2347 int res = REAL(statfs64)(path, buf);
2348 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
2349 return res;
2350}
2351INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
2352 void *ctx;
2353 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
2354 int res = REAL(fstatfs64)(fd, buf);
2355 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
2356 return res;
2357}
2358#define INIT_STATFS64 \
2359 INTERCEPT_FUNCTION(statfs64); \
2360 INTERCEPT_FUNCTION(fstatfs64);
2361#else
2362#define INIT_STATFS64
2363#endif
2364
2365#if SANITIZER_INTERCEPT_STATVFS
2366INTERCEPTOR(int, statvfs, char *path, void *buf) {
2367 void *ctx;
2368 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
2369 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2370 int res = REAL(statvfs)(path, buf);
2371 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
2372 return res;
2373}
2374INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
2375 void *ctx;
2376 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
2377 int res = REAL(fstatvfs)(fd, buf);
2378 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
2379 return res;
2380}
2381#define INIT_STATVFS \
2382 INTERCEPT_FUNCTION(statvfs); \
2383 INTERCEPT_FUNCTION(fstatvfs);
2384#else
2385#define INIT_STATVFS
2386#endif
2387
2388#if SANITIZER_INTERCEPT_STATVFS64
2389INTERCEPTOR(int, statvfs64, char *path, void *buf) {
2390 void *ctx;
2391 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
2392 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2393 int res = REAL(statvfs64)(path, buf);
2394 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
2395 return res;
2396}
2397INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
2398 void *ctx;
2399 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
2400 int res = REAL(fstatvfs64)(fd, buf);
2401 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
2402 return res;
2403}
2404#define INIT_STATVFS64 \
2405 INTERCEPT_FUNCTION(statvfs64); \
2406 INTERCEPT_FUNCTION(fstatvfs64);
2407#else
2408#define INIT_STATVFS64
2409#endif
Evgeniy Stepanov4d7297d2013-10-18 09:41:43 +00002410
Evgeniy Stepanov285d4582013-10-22 12:24:48 +00002411#if SANITIZER_INTERCEPT_INITGROUPS
2412INTERCEPTOR(int, initgroups, char *user, u32 group) {
2413 void *ctx;
2414 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
2415 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
2416 int res = REAL(initgroups)(user, group);
2417 return res;
2418}
2419#define INIT_INITGROUPS INTERCEPT_FUNCTION(initgroups);
2420#else
2421#define INIT_INITGROUPS
2422#endif
2423
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +00002424#if SANITIZER_INTERCEPT_ETHER
2425INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
2426 void *ctx;
2427 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
2428 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2429 char *res = REAL(ether_ntoa)(addr);
2430 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2431 return res;
2432}
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +00002433INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
2434 void *ctx;
2435 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
2436 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2437 __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
2438 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res));
2439 return res;
2440}
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +00002441INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
2442 void *ctx;
2443 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
2444 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2445 int res = REAL(ether_ntohost)(hostname, addr);
2446 if (!res && hostname)
2447 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2448 return res;
2449}
2450INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
2451 void *ctx;
2452 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
2453 if (hostname)
2454 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2455 int res = REAL(ether_hostton)(hostname, addr);
2456 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2457 return res;
2458}
2459INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
2460 char *hostname) {
2461 void *ctx;
2462 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
2463 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
2464 int res = REAL(ether_line)(line, addr, hostname);
2465 if (!res) {
2466 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2467 if (hostname)
2468 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2469 }
2470 return res;
2471}
2472#define INIT_ETHER \
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +00002473 INTERCEPT_FUNCTION(ether_ntoa); \
2474 INTERCEPT_FUNCTION(ether_aton); \
2475 INTERCEPT_FUNCTION(ether_ntohost); \
2476 INTERCEPT_FUNCTION(ether_hostton); \
2477 INTERCEPT_FUNCTION(ether_line);
2478#else
2479#define INIT_ETHER
2480#endif
2481
Evgeniy Stepanov220d1f72013-10-23 15:21:10 +00002482#if SANITIZER_INTERCEPT_ETHER_R
2483INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
2484 void *ctx;
2485 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
2486 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2487 char *res = REAL(ether_ntoa_r)(addr, buf);
2488 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2489 return res;
2490}
2491INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
2492 __sanitizer_ether_addr *addr) {
2493 void *ctx;
2494 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
2495 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2496 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
2497 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
2498 return res;
2499}
2500#define INIT_ETHER_R \
2501 INTERCEPT_FUNCTION(ether_ntoa_r); \
2502 INTERCEPT_FUNCTION(ether_aton_r);
2503#else
2504#define INIT_ETHER_R
2505#endif
2506
Evgeniy Stepanov10362d62013-10-24 14:47:34 +00002507#if SANITIZER_INTERCEPT_SHMCTL
2508INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
2509 void *ctx;
2510 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
2511 int res = REAL(shmctl)(shmid, cmd, buf);
2512 if (res >= 0) {
2513 unsigned sz = 0;
2514 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
2515 sz = struct_shmid_ds_sz;
2516 else if (cmd == shmctl_ipc_info)
2517 sz = struct_shminfo_sz;
2518 else if (cmd == shmctl_shm_info)
2519 sz = struct_shm_info_sz;
2520 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2521 }
2522 return res;
2523}
2524#define INIT_SHMCTL INTERCEPT_FUNCTION(shmctl);
2525#else
2526#define INIT_SHMCTL
2527#endif
2528
Evgeniy Stepanovaff25aa2013-10-25 08:58:13 +00002529#if SANITIZER_INTERCEPT_RANDOM_R
2530INTERCEPTOR(int, random_r, void *buf, u32 *result) {
2531 void *ctx;
2532 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
2533 int res = REAL(random_r)(buf, result);
2534 if (!res && result)
2535 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2536 return res;
2537}
2538#define INIT_RANDOM_R INTERCEPT_FUNCTION(random_r);
2539#else
2540#define INIT_RANDOM_R
2541#endif
2542
Evgeniy Stepanove236dbb2013-10-25 13:01:31 +00002543#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \
2544 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED
2545#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
2546 INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) { \
2547 void *ctx; \
2548 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \
2549 int res = REAL(pthread_attr_get##what)(attr, r); \
2550 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
2551 return res; \
2552 }
2553#endif
2554
2555#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
2556INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
2557INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
2558INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
2559INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
2560INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
2561INTERCEPTOR_PTHREAD_ATTR_GET(stackaddr, sizeof(void *))
2562INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
2563INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
2564 void *ctx;
2565 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
2566 int res = REAL(pthread_attr_getstack)(attr, addr, size);
2567 if (!res) {
2568 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2569 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
2570 }
2571 return res;
2572}
2573
2574#define INIT_PTHREAD_ATTR_GET \
2575 INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
2576 INTERCEPT_FUNCTION(pthread_attr_getguardsize); \
2577 INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
2578 INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
Evgeniy Stepanove236dbb2013-10-25 13:01:31 +00002579 INTERCEPT_FUNCTION(pthread_attr_getscope); \
2580 INTERCEPT_FUNCTION(pthread_attr_getstackaddr); \
2581 INTERCEPT_FUNCTION(pthread_attr_getstacksize); \
Evgeniy Stepanovec208e02013-10-25 14:24:31 +00002582 INTERCEPT_FUNCTION(pthread_attr_getstack);
Evgeniy Stepanove236dbb2013-10-25 13:01:31 +00002583#else
2584#define INIT_PTHREAD_ATTR_GET
2585#endif
2586
2587#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
2588INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
2589
2590#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
2591 INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
2592#else
2593#define INIT_PTHREAD_ATTR_GETINHERITSCHED
2594#endif
2595
2596#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
2597INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
2598 void *cpuset) {
2599 void *ctx;
2600 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
2601 cpuset);
2602 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
2603 if (!res && cpusetsize && cpuset)
2604 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
2605 return res;
2606}
2607
2608#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
2609 INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
2610#else
2611#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
2612#endif
2613
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00002614#define SANITIZER_COMMON_INTERCEPTORS_INIT \
Alexey Samsonov67505a82013-07-16 12:51:53 +00002615 INIT_STRCMP; \
2616 INIT_STRNCMP; \
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00002617 INIT_STRCASECMP; \
2618 INIT_STRNCASECMP; \
2619 INIT_READ; \
2620 INIT_PREAD; \
2621 INIT_PREAD64; \
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +00002622 INIT_READV; \
2623 INIT_PREADV; \
2624 INIT_PREADV64; \
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00002625 INIT_WRITE; \
2626 INIT_PWRITE; \
2627 INIT_PWRITE64; \
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +00002628 INIT_WRITEV; \
2629 INIT_PWRITEV; \
2630 INIT_PWRITEV64; \
2631 INIT_PRCTL; \
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00002632 INIT_LOCALTIME_AND_FRIENDS; \
2633 INIT_SCANF; \
Evgeniy Stepanovba150772013-08-22 13:59:15 +00002634 INIT_ISOC99_SCANF; \
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00002635 INIT_FREXP; \
2636 INIT_FREXPF_FREXPL; \
2637 INIT_GETPWNAM_AND_FRIENDS; \
2638 INIT_GETPWNAM_R_AND_FRIENDS; \
2639 INIT_CLOCK_GETTIME; \
2640 INIT_GETITIMER; \
2641 INIT_TIME; \
2642 INIT_GLOB; \
2643 INIT_WAIT; \
2644 INIT_INET; \
Evgeniy Stepanov447ef192013-05-22 12:50:26 +00002645 INIT_PTHREAD_GETSCHEDPARAM; \
Evgeniy Stepanov9f58c5c2013-05-22 13:46:22 +00002646 INIT_GETADDRINFO; \
Evgeniy Stepanov9eedf482013-07-01 13:51:31 +00002647 INIT_GETNAMEINFO; \
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +00002648 INIT_GETSOCKNAME; \
2649 INIT_GETHOSTBYNAME; \
Evgeniy Stepanovf32be422013-05-23 11:38:08 +00002650 INIT_GETHOSTBYNAME_R; \
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +00002651 INIT_GETSOCKOPT; \
2652 INIT_ACCEPT; \
Evgeniy Stepanovc87088b2013-05-29 10:03:11 +00002653 INIT_ACCEPT4; \
Evgeniy Stepanov9666d892013-05-29 11:30:00 +00002654 INIT_MODF; \
Evgeniy Stepanovbc33e132013-05-29 11:49:25 +00002655 INIT_RECVMSG; \
Evgeniy Stepanov745dd0d2013-06-07 13:00:47 +00002656 INIT_GETPEERNAME; \
Evgeniy Stepanov9d600872013-06-24 13:56:14 +00002657 INIT_IOCTL; \
Evgeniy Stepanov359d7fc2013-06-24 14:25:33 +00002658 INIT_INET_ATON; \
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00002659 INIT_SYSINFO; \
2660 INIT_READDIR; \
Evgeniy Stepanov341b9e62013-06-28 11:02:43 +00002661 INIT_READDIR64; \
Evgeniy Stepanov3cae6042013-07-02 09:23:45 +00002662 INIT_PTRACE; \
Evgeniy Stepanov80144892013-07-02 13:34:44 +00002663 INIT_SETLOCALE; \
2664 INIT_GETCWD; \
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00002665 INIT_GET_CURRENT_DIR_NAME; \
2666 INIT_STRTOIMAX; \
2667 INIT_MBSTOWCS; \
2668 INIT_MBSNRTOWCS; \
2669 INIT_WCSTOMBS; \
Evgeniy Stepanovea727682013-07-04 14:03:31 +00002670 INIT_WCSNRTOMBS; \
Evgeniy Stepanov12eb79d2013-07-09 09:53:37 +00002671 INIT_TCGETATTR; \
2672 INIT_REALPATH; \
Evgeniy Stepanov5ec19bc2013-07-30 12:46:59 +00002673 INIT_CANONICALIZE_FILE_NAME; \
Evgeniy Stepanov84ba74c2013-08-07 09:10:16 +00002674 INIT_CONFSTR; \
Evgeniy Stepanov12049792013-08-08 11:44:05 +00002675 INIT_SCHED_GETAFFINITY; \
2676 INIT_STRERROR; \
Evgeniy Stepanov224226c2013-08-08 13:57:15 +00002677 INIT_STRERROR_R; \
2678 INIT_SCANDIR; \
Evgeniy Stepanovedff34b2013-08-12 11:01:40 +00002679 INIT_SCANDIR64; \
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +00002680 INIT_GETGROUPS; \
2681 INIT_POLL; \
Evgeniy Stepanovc5a38552013-09-24 14:38:22 +00002682 INIT_PPOLL; \
Evgeniy Stepanov9a949a82013-09-25 14:47:43 +00002683 INIT_WORDEXP; \
2684 INIT_SIGWAIT; \
2685 INIT_SIGWAITINFO; \
2686 INIT_SIGTIMEDWAIT; \
2687 INIT_SIGSETOPS; \
2688 INIT_SIGPENDING; \
Evgeniy Stepanov1394be12013-09-27 12:40:23 +00002689 INIT_SIGPROCMASK; \
Dmitry Vyukov14dd9802013-10-03 15:22:29 +00002690 INIT_BACKTRACE; \
2691 INIT__EXIT; \
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002692 INIT_PTHREAD_MUTEX_LOCK; \
2693 INIT_PTHREAD_MUTEX_UNLOCK; \
2694 INIT_PTHREAD_COND_WAIT; \
2695 INIT_PTHREAD_COND_INIT; \
Alexey Samsonovfc813462013-10-17 09:24:03 +00002696 INIT_PTHREAD_COND_SIGNAL; \
2697 INIT_PTHREAD_COND_BROADCAST; \
Evgeniy Stepanov4d7297d2013-10-18 09:41:43 +00002698 INIT_GETMNTENT; \
2699 INIT_GETMNTENT_R; \
Evgeniy Stepanov5cee73e2013-10-18 11:14:16 +00002700 INIT_STATFS; \
2701 INIT_STATFS64; \
2702 INIT_STATVFS; \
2703 INIT_STATVFS64; \
Evgeniy Stepanov285d4582013-10-22 12:24:48 +00002704 INIT_INITGROUPS; \
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +00002705 INIT_ETHER; \
Evgeniy Stepanov220d1f72013-10-23 15:21:10 +00002706 INIT_ETHER_R; \
Evgeniy Stepanov10362d62013-10-24 14:47:34 +00002707 INIT_SHMCTL; \
Evgeniy Stepanovaff25aa2013-10-25 08:58:13 +00002708 INIT_RANDOM_R; \
Evgeniy Stepanove236dbb2013-10-25 13:01:31 +00002709 INIT_PTHREAD_ATTR_GET; \
2710 INIT_PTHREAD_ATTR_GETINHERITSCHED; \
2711 INIT_PTHREAD_ATTR_GETAFFINITY_NP; \
Dmitry Vyukov14dd9802013-10-03 15:22:29 +00002712/**/