]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/esan/esan_interceptors.cpp
Merge compiler-rt r291274.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / esan / esan_interceptors.cpp
1 //===-- esan_interceptors.cpp ---------------------------------------------===//
2 //
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 // This file is a part of EfficiencySanitizer, a family of performance tuners.
11 //
12 // Interception routines for the esan run-time.
13 //===----------------------------------------------------------------------===//
14
15 #include "esan.h"
16 #include "esan_shadow.h"
17 #include "interception/interception.h"
18 #include "sanitizer_common/sanitizer_common.h"
19 #include "sanitizer_common/sanitizer_libc.h"
20 #include "sanitizer_common/sanitizer_linux.h"
21 #include "sanitizer_common/sanitizer_stacktrace.h"
22
23 using namespace __esan; // NOLINT
24
25 #define CUR_PC() (StackTrace::GetCurrentPc())
26
27 //===----------------------------------------------------------------------===//
28 // Interception via sanitizer common interceptors
29 //===----------------------------------------------------------------------===//
30
31 // Get the per-platform defines for what is possible to intercept
32 #include "sanitizer_common/sanitizer_platform_interceptors.h"
33
34 // TODO(bruening): tsan disables several interceptors (getpwent, etc.) claiming
35 // that interception is a perf hit: should we do the same?
36
37 // We have no need to intercept:
38 #undef SANITIZER_INTERCEPT_TLS_GET_ADDR
39
40 // TODO(bruening): the common realpath interceptor assumes malloc is
41 // intercepted!  We should try to parametrize that, though we'll
42 // intercept malloc soon ourselves and can then remove this undef.
43 #undef SANITIZER_INTERCEPT_REALPATH
44
45 // We provide our own version:
46 #undef SANITIZER_INTERCEPT_SIGPROCMASK
47
48 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!EsanIsInitialized)
49
50 #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
51 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver)                          \
52   INTERCEPT_FUNCTION_VER(name, ver)
53
54 // We must initialize during early interceptors, to support tcmalloc.
55 // This means that for some apps we fully initialize prior to
56 // __esan_init() being called.
57 // We currently do not use ctx.
58 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                               \
59   do {                                                                         \
60     if (UNLIKELY(COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)) {                 \
61       if (!UNLIKELY(EsanDuringInit))                                           \
62         initializeLibrary(__esan_which_tool);                                  \
63       return REAL(func)(__VA_ARGS__);                                          \
64     }                                                                          \
65     ctx = nullptr;                                                             \
66     (void)ctx;                                                                 \
67   } while (false)
68
69 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, func, ...)                      \
70   COMMON_INTERCEPTOR_ENTER(ctx, func, __VA_ARGS__)
71
72 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                         \
73   processRangeAccess(CUR_PC(), (uptr)ptr, size, true)
74
75 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)                          \
76   processRangeAccess(CUR_PC(), (uptr)ptr, size, false)
77
78 // This is only called if the app explicitly calls exit(), not on
79 // a normal exit.
80 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) finalizeLibrary()
81
82 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path)                          \
83   do {                                                                         \
84     (void)(ctx);                                                               \
85     (void)(file);                                                              \
86     (void)(path);                                                              \
87   } while (false)
88 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file)                               \
89   do {                                                                         \
90     (void)(ctx);                                                               \
91     (void)(file);                                                              \
92   } while (false)
93 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)                    \
94   do {                                                                         \
95     (void)(filename);                                                          \
96     (void)(handle);                                                            \
97   } while (false)
98 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED()                                  \
99   do {                                                                         \
100   } while (false)
101 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u)                                     \
102   do {                                                                         \
103     (void)(ctx);                                                               \
104     (void)(u);                                                                 \
105   } while (false)
106 #define COMMON_INTERCEPTOR_RELEASE(ctx, u)                                     \
107   do {                                                                         \
108     (void)(ctx);                                                               \
109     (void)(u);                                                                 \
110   } while (false)
111 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path)                              \
112   do {                                                                         \
113     (void)(ctx);                                                               \
114     (void)(path);                                                              \
115   } while (false)
116 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd)                                 \
117   do {                                                                         \
118     (void)(ctx);                                                               \
119     (void)(fd);                                                                \
120   } while (false)
121 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd)                                 \
122   do {                                                                         \
123     (void)(ctx);                                                               \
124     (void)(fd);                                                                \
125   } while (false)
126 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)                                  \
127   do {                                                                         \
128     (void)(ctx);                                                               \
129     (void)(fd);                                                                \
130   } while (false)
131 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd)                    \
132   do {                                                                         \
133     (void)(ctx);                                                               \
134     (void)(fd);                                                                \
135     (void)(newfd);                                                             \
136   } while (false)
137 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name)                          \
138   do {                                                                         \
139     (void)(ctx);                                                               \
140     (void)(name);                                                              \
141   } while (false)
142 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name)                 \
143   do {                                                                         \
144     (void)(ctx);                                                               \
145     (void)(thread);                                                            \
146     (void)(name);                                                              \
147   } while (false)
148 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
149 #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m)                                  \
150   do {                                                                         \
151     (void)(ctx);                                                               \
152     (void)(m);                                                                 \
153   } while (false)
154 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m)                                \
155   do {                                                                         \
156     (void)(ctx);                                                               \
157     (void)(m);                                                                 \
158   } while (false)
159 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m)                                \
160   do {                                                                         \
161     (void)(ctx);                                                               \
162     (void)(m);                                                                 \
163   } while (false)
164 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg)                            \
165   do {                                                                         \
166     (void)(ctx);                                                               \
167     (void)(msg);                                                               \
168   } while (false)
169 #define COMMON_INTERCEPTOR_USER_CALLBACK_START()                               \
170   do {                                                                         \
171   } while (false)
172 #define COMMON_INTERCEPTOR_USER_CALLBACK_END()                                 \
173   do {                                                                         \
174   } while (false)
175
176 #include "sanitizer_common/sanitizer_common_interceptors.inc"
177
178 //===----------------------------------------------------------------------===//
179 // Syscall interception
180 //===----------------------------------------------------------------------===//
181
182 // We want the caller's PC b/c unlike the other function interceptors these
183 // are separate pre and post functions called around the app's syscall().
184
185 #define COMMON_SYSCALL_PRE_READ_RANGE(ptr, size)                               \
186   processRangeAccess(GET_CALLER_PC(), (uptr)ptr, size, false)
187
188 #define COMMON_SYSCALL_PRE_WRITE_RANGE(ptr, size)                              \
189   do {                                                                         \
190     (void)(ptr);                                                               \
191     (void)(size);                                                              \
192   } while (false)
193
194 #define COMMON_SYSCALL_POST_READ_RANGE(ptr, size)                              \
195   do {                                                                         \
196     (void)(ptr);                                                               \
197     (void)(size);                                                              \
198   } while (false)
199
200 // The actual amount written is in post, not pre.
201 #define COMMON_SYSCALL_POST_WRITE_RANGE(ptr, size)                             \
202   processRangeAccess(GET_CALLER_PC(), (uptr)ptr, size, true)
203
204 #define COMMON_SYSCALL_ACQUIRE(addr)                                           \
205   do {                                                                         \
206     (void)(addr);                                                              \
207   } while (false)
208 #define COMMON_SYSCALL_RELEASE(addr)                                           \
209   do {                                                                         \
210     (void)(addr);                                                              \
211   } while (false)
212 #define COMMON_SYSCALL_FD_CLOSE(fd)                                            \
213   do {                                                                         \
214     (void)(fd);                                                                \
215   } while (false)
216 #define COMMON_SYSCALL_FD_ACQUIRE(fd)                                          \
217   do {                                                                         \
218     (void)(fd);                                                                \
219   } while (false)
220 #define COMMON_SYSCALL_FD_RELEASE(fd)                                          \
221   do {                                                                         \
222     (void)(fd);                                                                \
223   } while (false)
224 #define COMMON_SYSCALL_PRE_FORK()                                              \
225   do {                                                                         \
226   } while (false)
227 #define COMMON_SYSCALL_POST_FORK(res)                                          \
228   do {                                                                         \
229     (void)(res);                                                               \
230   } while (false)
231
232 #include "sanitizer_common/sanitizer_common_syscalls.inc"
233
234 //===----------------------------------------------------------------------===//
235 // Custom interceptors
236 //===----------------------------------------------------------------------===//
237
238 // TODO(bruening): move more of these to the common interception pool as they
239 // are shared with tsan and asan.
240 // While our other files match LLVM style, here we match sanitizer style as we
241 // expect to move these to the common pool.
242
243 INTERCEPTOR(char *, strcpy, char *dst, const char *src) { // NOLINT
244   void *ctx;
245   COMMON_INTERCEPTOR_ENTER(ctx, strcpy, dst, src);
246   uptr srclen = internal_strlen(src);
247   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, srclen + 1);
248   COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclen + 1);
249   return REAL(strcpy)(dst, src); // NOLINT
250 }
251
252 INTERCEPTOR(char *, strncpy, char *dst, char *src, uptr n) {
253   void *ctx;
254   COMMON_INTERCEPTOR_ENTER(ctx, strncpy, dst, src, n);
255   uptr srclen = internal_strnlen(src, n);
256   uptr copied_size = srclen + 1 > n ? n : srclen + 1;
257   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, copied_size);
258   COMMON_INTERCEPTOR_READ_RANGE(ctx, src, copied_size);
259   return REAL(strncpy)(dst, src, n);
260 }
261
262 INTERCEPTOR(int, open, const char *name, int flags, int mode) {
263   void *ctx;
264   COMMON_INTERCEPTOR_ENTER(ctx, open, name, flags, mode);
265   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
266   return REAL(open)(name, flags, mode);
267 }
268
269 #if SANITIZER_LINUX
270 INTERCEPTOR(int, open64, const char *name, int flags, int mode) {
271   void *ctx;
272   COMMON_INTERCEPTOR_ENTER(ctx, open64, name, flags, mode);
273   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
274   return REAL(open64)(name, flags, mode);
275 }
276 #define ESAN_MAYBE_INTERCEPT_OPEN64 INTERCEPT_FUNCTION(open64)
277 #else
278 #define ESAN_MAYBE_INTERCEPT_OPEN64
279 #endif
280
281 INTERCEPTOR(int, creat, const char *name, int mode) {
282   void *ctx;
283   COMMON_INTERCEPTOR_ENTER(ctx, creat, name, mode);
284   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
285   return REAL(creat)(name, mode);
286 }
287
288 #if SANITIZER_LINUX
289 INTERCEPTOR(int, creat64, const char *name, int mode) {
290   void *ctx;
291   COMMON_INTERCEPTOR_ENTER(ctx, creat64, name, mode);
292   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
293   return REAL(creat64)(name, mode);
294 }
295 #define ESAN_MAYBE_INTERCEPT_CREAT64 INTERCEPT_FUNCTION(creat64)
296 #else
297 #define ESAN_MAYBE_INTERCEPT_CREAT64
298 #endif
299
300 INTERCEPTOR(int, unlink, char *path) {
301   void *ctx;
302   COMMON_INTERCEPTOR_ENTER(ctx, unlink, path);
303   COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
304   return REAL(unlink)(path);
305 }
306
307 INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) {
308   void *ctx;
309   COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, f);
310   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size * nmemb);
311   return REAL(fread)(ptr, size, nmemb, f);
312 }
313
314 INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) {
315   void *ctx;
316   COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, f);
317   COMMON_INTERCEPTOR_READ_RANGE(ctx, p, size * nmemb);
318   return REAL(fwrite)(p, size, nmemb, f);
319 }
320
321 INTERCEPTOR(int, puts, const char *s) {
322   void *ctx;
323   COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
324   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s));
325   return REAL(puts)(s);
326 }
327
328 INTERCEPTOR(int, rmdir, char *path) {
329   void *ctx;
330   COMMON_INTERCEPTOR_ENTER(ctx, rmdir, path);
331   COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
332   return REAL(rmdir)(path);
333 }
334
335 //===----------------------------------------------------------------------===//
336 // Shadow-related interceptors
337 //===----------------------------------------------------------------------===//
338
339 // These are candidates for sharing with all sanitizers if shadow memory
340 // support is also standardized.
341
342 INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags,
343                  int fd, OFF_T off) {
344   if (UNLIKELY(REAL(mmap) == nullptr)) {
345     // With esan init during interceptor init and a static libc preventing
346     // our early-calloc from triggering, we can end up here before our
347     // REAL pointer is set up.
348     return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
349   }
350   void *ctx;
351   COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
352   if (!fixMmapAddr(&addr, sz, flags))
353     return (void *)-1;
354   void *result = REAL(mmap)(addr, sz, prot, flags, fd, off);
355   return (void *)checkMmapResult((uptr)result, sz);
356 }
357
358 #if SANITIZER_LINUX
359 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags,
360                  int fd, OFF64_T off) {
361   void *ctx;
362   COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
363   if (!fixMmapAddr(&addr, sz, flags))
364     return (void *)-1;
365   void *result = REAL(mmap64)(addr, sz, prot, flags, fd, off);
366   return (void *)checkMmapResult((uptr)result, sz);
367 }
368 #define ESAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
369 #else
370 #define ESAN_MAYBE_INTERCEPT_MMAP64
371 #endif
372
373 //===----------------------------------------------------------------------===//
374 // Signal-related interceptors
375 //===----------------------------------------------------------------------===//
376
377 #if SANITIZER_LINUX
378 typedef void (*signal_handler_t)(int);
379 INTERCEPTOR(signal_handler_t, signal, int signum, signal_handler_t handler) {
380   void *ctx;
381   COMMON_INTERCEPTOR_ENTER(ctx, signal, signum, handler);
382   signal_handler_t result;
383   if (!processSignal(signum, handler, &result))
384     return result;
385   else
386     return REAL(signal)(signum, handler);
387 }
388 #define ESAN_MAYBE_INTERCEPT_SIGNAL INTERCEPT_FUNCTION(signal)
389 #else
390 #error Platform not supported
391 #define ESAN_MAYBE_INTERCEPT_SIGNAL
392 #endif
393
394 #if SANITIZER_LINUX
395 DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,
396              struct sigaction *oldact)
397 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
398             struct sigaction *oldact) {
399   void *ctx;
400   COMMON_INTERCEPTOR_ENTER(ctx, sigaction, signum, act, oldact);
401   if (!processSigaction(signum, act, oldact))
402     return 0;
403   else
404     return REAL(sigaction)(signum, act, oldact);
405 }
406
407 // This is required to properly use internal_sigaction.
408 namespace __sanitizer {
409 int real_sigaction(int signum, const void *act, void *oldact) {
410   if (REAL(sigaction) == nullptr) {
411     // With an instrumented allocator, this is called during interceptor init
412     // and we need a raw syscall solution.
413     return internal_sigaction_syscall(signum, act, oldact);
414   }
415   return REAL(sigaction)(signum, (const struct sigaction *)act,
416                          (struct sigaction *)oldact);
417 }
418 } // namespace __sanitizer
419
420 #define ESAN_MAYBE_INTERCEPT_SIGACTION INTERCEPT_FUNCTION(sigaction)
421 #else
422 #error Platform not supported
423 #define ESAN_MAYBE_INTERCEPT_SIGACTION
424 #endif
425
426 #if SANITIZER_LINUX
427 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
428             __sanitizer_sigset_t *oldset) {
429   void *ctx;
430   COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
431   int res = 0;
432   if (processSigprocmask(how, set, oldset))
433     res = REAL(sigprocmask)(how, set, oldset);
434   if (!res && oldset)
435     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
436   return res;
437 }
438 #define ESAN_MAYBE_INTERCEPT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask)
439 #else
440 #define ESAN_MAYBE_INTERCEPT_SIGPROCMASK
441 #endif
442
443 #if !SANITIZER_WINDOWS
444 INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
445             __sanitizer_sigset_t *oldset) {
446   void *ctx;
447   COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
448   int res = 0;
449   if (processSigprocmask(how, set, oldset))
450     res = REAL(sigprocmask)(how, set, oldset);
451   if (!res && oldset)
452     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
453   return res;
454 }
455 #define ESAN_MAYBE_INTERCEPT_PTHREAD_SIGMASK INTERCEPT_FUNCTION(pthread_sigmask)
456 #else
457 #define ESAN_MAYBE_INTERCEPT_PTHREAD_SIGMASK
458 #endif
459
460 //===----------------------------------------------------------------------===//
461 // Malloc interceptors
462 //===----------------------------------------------------------------------===//
463
464 static const uptr early_alloc_buf_size = 4096;
465 static uptr allocated_bytes;
466 static char early_alloc_buf[early_alloc_buf_size];
467
468 static bool isInEarlyAllocBuf(const void *ptr) {
469   return ((uptr)ptr >= (uptr)early_alloc_buf &&
470           ((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
471 }
472
473 static void *handleEarlyAlloc(uptr size) {
474   // If esan is initialized during an interceptor (which happens with some
475   // tcmalloc implementations that call pthread_mutex_lock), the call from
476   // dlsym to calloc will deadlock.
477   // dlsym may also call malloc before REAL(malloc) is retrieved from dlsym.
478   // We work around it by using a static buffer for the early malloc/calloc
479   // requests.
480   // This solution will also allow us to deliberately intercept malloc & family
481   // in the future (to perform tool actions on each allocation, without
482   // replacing the allocator), as it also solves the problem of intercepting
483   // calloc when it will itself be called before its REAL pointer is
484   // initialized.
485   // We do not handle multiple threads here.  This only happens at process init
486   // time, and while it's possible for a shared library to create early threads
487   // that race here, we consider that to be a corner case extreme enough that
488   // it's not worth the effort to handle.
489   void *mem = (void *)&early_alloc_buf[allocated_bytes];
490   allocated_bytes += size;
491   CHECK_LT(allocated_bytes, early_alloc_buf_size);
492   return mem;
493 }
494
495 INTERCEPTOR(void*, calloc, uptr size, uptr n) {
496   if (EsanDuringInit && REAL(calloc) == nullptr)
497     return handleEarlyAlloc(size * n);
498   void *ctx;
499   COMMON_INTERCEPTOR_ENTER(ctx, calloc, size, n);
500   void *res = REAL(calloc)(size, n);
501   // The memory is zeroed and thus is all written.
502   COMMON_INTERCEPTOR_WRITE_RANGE(nullptr, (uptr)res, size * n);
503   return res;
504 }
505
506 INTERCEPTOR(void*, malloc, uptr size) {
507   if (EsanDuringInit && REAL(malloc) == nullptr)
508     return handleEarlyAlloc(size);
509   void *ctx;
510   COMMON_INTERCEPTOR_ENTER(ctx, malloc, size);
511   return REAL(malloc)(size);
512 }
513
514 INTERCEPTOR(void, free, void *p) {
515   void *ctx;
516   // There are only a few early allocation requests, so we simply skip the free.
517   if (isInEarlyAllocBuf(p))
518     return;
519   COMMON_INTERCEPTOR_ENTER(ctx, free, p);
520   REAL(free)(p);
521 }
522
523 namespace __esan {
524
525 void initializeInterceptors() {
526   InitializeCommonInterceptors();
527
528   INTERCEPT_FUNCTION(strcpy); // NOLINT
529   INTERCEPT_FUNCTION(strncpy);
530
531   INTERCEPT_FUNCTION(open);
532   ESAN_MAYBE_INTERCEPT_OPEN64;
533   INTERCEPT_FUNCTION(creat);
534   ESAN_MAYBE_INTERCEPT_CREAT64;
535   INTERCEPT_FUNCTION(unlink);
536   INTERCEPT_FUNCTION(fread);
537   INTERCEPT_FUNCTION(fwrite);
538   INTERCEPT_FUNCTION(puts);
539   INTERCEPT_FUNCTION(rmdir);
540
541   INTERCEPT_FUNCTION(mmap);
542   ESAN_MAYBE_INTERCEPT_MMAP64;
543
544   ESAN_MAYBE_INTERCEPT_SIGNAL;
545   ESAN_MAYBE_INTERCEPT_SIGACTION;
546   ESAN_MAYBE_INTERCEPT_SIGPROCMASK;
547   ESAN_MAYBE_INTERCEPT_PTHREAD_SIGMASK;
548
549   INTERCEPT_FUNCTION(calloc);
550   INTERCEPT_FUNCTION(malloc);
551   INTERCEPT_FUNCTION(free);
552
553   // TODO(bruening): intercept routines that other sanitizers intercept that
554   // are not in the common pool or here yet, ideally by adding to the common
555   // pool.  Examples include wcslen and bcopy.
556
557   // TODO(bruening): there are many more libc routines that read or write data
558   // structures that no sanitizer is intercepting: sigaction, strtol, etc.
559 }
560
561 } // namespace __esan