Daily bump.
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_common_interceptors.inc
blobaf27603ebdde3741993bf2067e02c357dd3f8018
1 //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // Common function interceptors for tools like AddressSanitizer,
9 // ThreadSanitizer, MemorySanitizer, etc.
11 // This file should be included into the tool's interceptor file,
12 // which has to define it's own macros:
13 //   COMMON_INTERCEPTOR_ENTER
14 //   COMMON_INTERCEPTOR_READ_RANGE
15 //   COMMON_INTERCEPTOR_WRITE_RANGE
16 //   COMMON_INTERCEPTOR_FD_ACQUIRE
17 //   COMMON_INTERCEPTOR_FD_RELEASE
18 //   COMMON_INTERCEPTOR_SET_THREAD_NAME
19 //===----------------------------------------------------------------------===//
20 #include "interception/interception.h"
21 #include "sanitizer_platform_interceptors.h"
23 #include <stdarg.h>
25 #ifdef _WIN32
26 #define va_copy(dst, src) ((dst) = (src))
27 #endif // _WIN32
29 #if SANITIZER_INTERCEPT_READ
30 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
31   void *ctx;
32   COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
33   SSIZE_T res = REAL(read)(fd, ptr, count);
34   if (res > 0)
35     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
36   if (res >= 0 && fd >= 0)
37     COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
38   return res;
40 #define INIT_READ INTERCEPT_FUNCTION(read)
41 #else
42 #define INIT_READ
43 #endif
45 #if SANITIZER_INTERCEPT_PREAD
46 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
47   void *ctx;
48   COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
49   SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
50   if (res > 0)
51     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
52   if (res >= 0 && fd >= 0)
53     COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
54   return res;
56 #define INIT_PREAD INTERCEPT_FUNCTION(pread)
57 #else
58 #define INIT_PREAD
59 #endif
61 #if SANITIZER_INTERCEPT_PREAD64
62 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
63   void *ctx;
64   COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
65   SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
66   if (res > 0)
67     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
68   if (res >= 0 && fd >= 0)
69     COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
70   return res;
72 #define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
73 #else
74 #define INIT_PREAD64
75 #endif
77 #if SANITIZER_INTERCEPT_WRITE
78 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
79   void *ctx;
80   COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
81   if (fd >= 0)
82     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
83   SSIZE_T res = REAL(write)(fd, ptr, count);
84   if (res > 0)
85     COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
86   return res;
88 #define INIT_WRITE INTERCEPT_FUNCTION(write)
89 #else
90 #define INIT_WRITE
91 #endif
93 #if SANITIZER_INTERCEPT_PWRITE
94 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
95   void *ctx;
96   COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
97   if (fd >= 0)
98     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
99   SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
100   if (res > 0)
101     COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
102   return res;
104 #define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
105 #else
106 #define INIT_PWRITE
107 #endif
109 #if SANITIZER_INTERCEPT_PWRITE64
110 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
111             OFF64_T offset) {
112   void *ctx;
113   COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
114   if (fd >= 0)
115     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
116   SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
117   if (res > 0)
118     COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
119   return res;
121 #define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
122 #else
123 #define INIT_PWRITE64
124 #endif
126 #if SANITIZER_INTERCEPT_PRCTL
127 INTERCEPTOR(int, prctl, int option,
128             unsigned long arg2, unsigned long arg3,   // NOLINT
129             unsigned long arg4, unsigned long arg5) { // NOLINT
130   void *ctx;
131   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
132   static const int PR_SET_NAME = 15;
133   int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
134   if (option == PR_SET_NAME) {
135     char buff[16];
136     internal_strncpy(buff, (char *)arg2, 15);
137     buff[15] = 0;
138     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
139   }
140   return res;
142 #define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
143 #else
144 #define INIT_PRCTL
145 #endif // SANITIZER_INTERCEPT_PRCTL
147 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
148 INTERCEPTOR(void *, localtime, unsigned long *timep) {
149   void *ctx;
150   COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
151   void *res = REAL(localtime)(timep);
152   if (res) {
153     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
154     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
155   }
156   return res;
158 INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
159   void *ctx;
160   COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
161   void *res = REAL(localtime_r)(timep, result);
162   if (res) {
163     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
164     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
165   }
166   return res;
168 INTERCEPTOR(void *, gmtime, unsigned long *timep) {
169   void *ctx;
170   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
171   void *res = REAL(gmtime)(timep);
172   if (res) {
173     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
174     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
175   }
176   return res;
178 INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
179   void *ctx;
180   COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
181   void *res = REAL(gmtime_r)(timep, result);
182   if (res) {
183     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
184     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
185   }
186   return res;
188 INTERCEPTOR(char *, ctime, unsigned long *timep) {
189   void *ctx;
190   COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
191   char *res = REAL(ctime)(timep);
192   if (res) {
193     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
194     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
195   }
196   return res;
198 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
199   void *ctx;
200   COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
201   char *res = REAL(ctime_r)(timep, result);
202   if (res) {
203     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
204     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
205   }
206   return res;
208 INTERCEPTOR(char *, asctime, void *tm) {
209   void *ctx;
210   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
211   char *res = REAL(asctime)(tm);
212   if (res) {
213     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
214     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
215   }
216   return res;
218 INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
219   void *ctx;
220   COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
221   char *res = REAL(asctime_r)(tm, result);
222   if (res) {
223     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
224     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
225   }
226   return res;
228 #define INIT_LOCALTIME_AND_FRIENDS               \
229   INTERCEPT_FUNCTION(localtime);                 \
230   INTERCEPT_FUNCTION(localtime_r);               \
231   INTERCEPT_FUNCTION(gmtime);                    \
232   INTERCEPT_FUNCTION(gmtime_r);                  \
233   INTERCEPT_FUNCTION(ctime);                     \
234   INTERCEPT_FUNCTION(ctime_r);                   \
235   INTERCEPT_FUNCTION(asctime);                   \
236   INTERCEPT_FUNCTION(asctime_r);
237 #else
238 #define INIT_LOCALTIME_AND_FRIENDS
239 #endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
241 #if SANITIZER_INTERCEPT_SCANF
243 #include "sanitizer_common_interceptors_scanf.inc"
245 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
246   {                                                                            \
247     void *ctx;                                                                 \
248     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
249     va_list aq;                                                                \
250     va_copy(aq, ap);                                                           \
251     int res = REAL(vname)(__VA_ARGS__);                                        \
252     if (res > 0)                                                               \
253       scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
254     va_end(aq);                                                                \
255     return res;                                                                \
256   }
258 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
259 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
261 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
262 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
264 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
265 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
267 #if SANITIZER_INTERCEPT_ISOC99_SCANF
268 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
269 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
271 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
272             va_list ap)
273 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
275 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
276 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
277 #endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
279 #define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
280   {                                                                            \
281     void *ctx;                                                                 \
282     COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
283     va_list ap;                                                                \
284     va_start(ap, format);                                                      \
285     int res = vname(__VA_ARGS__, ap);                                          \
286     va_end(ap);                                                                \
287     return res;                                                                \
288   }
290 INTERCEPTOR(int, scanf, const char *format, ...)
291 SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
293 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
294 SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
296 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
297 SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
299 #if SANITIZER_INTERCEPT_ISOC99_SCANF
300 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
301 SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
303 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
304 SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
306 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
307 SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
308 #endif
310 #define INIT_SCANF                                                             \
311   INTERCEPT_FUNCTION(scanf);                                                   \
312   INTERCEPT_FUNCTION(sscanf);                                                  \
313   INTERCEPT_FUNCTION(fscanf);                                                  \
314   INTERCEPT_FUNCTION(vscanf);                                                  \
315   INTERCEPT_FUNCTION(vsscanf);                                                 \
316   INTERCEPT_FUNCTION(vfscanf);                                                 \
317   INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
318   INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
319   INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
320   INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
321   INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
322   INTERCEPT_FUNCTION(__isoc99_vfscanf);
324 #else
325 #define INIT_SCANF
326 #endif
328 #define SANITIZER_COMMON_INTERCEPTORS_INIT                                     \
329   INIT_READ;                                                                   \
330   INIT_PREAD;                                                                  \
331   INIT_PREAD64;                                                                \
332   INIT_PRCTL;                                                                  \
333   INIT_WRITE;                                                                  \
334   INIT_PWRITE;                                                                 \
335   INIT_PWRITE64;                                                               \
336   INIT_LOCALTIME_AND_FRIENDS;                                                  \
337   INIT_SCANF;