Fix GNU coding style for G_.
[official-gcc.git] / libsanitizer / asan / asan_interceptors.cc
bloba8f4b72723fe8eb13e4422ce10e8586df9ffe876
1 //===-- asan_interceptors.cc ----------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
10 // Intercept various libc functions.
11 //===----------------------------------------------------------------------===//
13 #include "asan_interceptors.h"
14 #include "asan_allocator.h"
15 #include "asan_internal.h"
16 #include "asan_mapping.h"
17 #include "asan_poisoning.h"
18 #include "asan_report.h"
19 #include "asan_stack.h"
20 #include "asan_stats.h"
21 #include "asan_suppressions.h"
22 #include "lsan/lsan_common.h"
23 #include "sanitizer_common/sanitizer_libc.h"
25 // There is no general interception at all on Fuchsia.
26 // Only the functions in asan_interceptors_memintrinsics.cc are
27 // really defined to replace libc functions.
28 #if !SANITIZER_FUCHSIA
30 #if SANITIZER_POSIX
31 #include "sanitizer_common/sanitizer_posix.h"
32 #endif
34 #if defined(__i386) && SANITIZER_LINUX
35 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
36 #elif defined(__mips__) && SANITIZER_LINUX
37 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2"
38 #endif
40 namespace __asan {
42 #define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) \
43 ASAN_READ_RANGE((ctx), (s), \
44 common_flags()->strict_string_checks ? (len) + 1 : (n))
46 #define ASAN_READ_STRING(ctx, s, n) \
47 ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
49 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
50 #if SANITIZER_INTERCEPT_STRNLEN
51 if (REAL(strnlen)) {
52 return REAL(strnlen)(s, maxlen);
54 #endif
55 return internal_strnlen(s, maxlen);
58 void SetThreadName(const char *name) {
59 AsanThread *t = GetCurrentThread();
60 if (t)
61 asanThreadRegistry().SetThreadName(t->tid(), name);
64 int OnExit() {
65 if (CAN_SANITIZE_LEAKS && common_flags()->detect_leaks &&
66 __lsan::HasReportedLeaks()) {
67 return common_flags()->exitcode;
69 // FIXME: ask frontend whether we need to return failure.
70 return 0;
73 } // namespace __asan
75 // ---------------------- Wrappers ---------------- {{{1
76 using namespace __asan; // NOLINT
78 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
79 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
81 #define ASAN_INTERCEPTOR_ENTER(ctx, func) \
82 AsanInterceptorContext _ctx = {#func}; \
83 ctx = (void *)&_ctx; \
84 (void) ctx; \
86 #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
87 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
88 ASAN_INTERCEPT_FUNC_VER(name, ver)
89 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
90 ASAN_WRITE_RANGE(ctx, ptr, size)
91 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
92 ASAN_READ_RANGE(ctx, ptr, size)
93 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
94 ASAN_INTERCEPTOR_ENTER(ctx, func); \
95 do { \
96 if (asan_init_is_running) \
97 return REAL(func)(__VA_ARGS__); \
98 if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \
99 return REAL(func)(__VA_ARGS__); \
100 ENSURE_ASAN_INITED(); \
101 } while (false)
102 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
103 do { \
104 } while (false)
105 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
106 do { \
107 } while (false)
108 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
109 do { \
110 } while (false)
111 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
112 do { \
113 } while (false)
114 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
115 // Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)
116 // But asan does not remember UserId's for threads (pthread_t);
117 // and remembers all ever existed threads, so the linear search by UserId
118 // can be slow.
119 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
120 do { \
121 } while (false)
122 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
123 // Strict init-order checking is dlopen-hostile:
124 // https://github.com/google/sanitizers/issues/178
125 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
126 do { \
127 if (flags()->strict_init_order) \
128 StopInitOrderChecking(); \
129 CheckNoDeepBind(filename, flag); \
130 } while (false)
131 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
132 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)
133 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED()
134 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
135 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \
136 if (AsanThread *t = GetCurrentThread()) { \
137 *begin = t->tls_begin(); \
138 *end = t->tls_end(); \
139 } else { \
140 *begin = *end = 0; \
143 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
144 do { \
145 ASAN_INTERCEPTOR_ENTER(ctx, memmove); \
146 ASAN_MEMMOVE_IMPL(ctx, to, from, size); \
147 } while (false)
149 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
150 do { \
151 ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \
152 ASAN_MEMCPY_IMPL(ctx, to, from, size); \
153 } while (false)
155 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
156 do { \
157 ASAN_INTERCEPTOR_ENTER(ctx, memset); \
158 ASAN_MEMSET_IMPL(ctx, block, c, size); \
159 } while (false)
161 #include "sanitizer_common/sanitizer_common_interceptors.inc"
162 #include "sanitizer_common/sanitizer_signal_interceptors.inc"
164 // Syscall interceptors don't have contexts, we don't support suppressions
165 // for them.
166 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
167 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
168 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
169 do { \
170 (void)(p); \
171 (void)(s); \
172 } while (false)
173 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
174 do { \
175 (void)(p); \
176 (void)(s); \
177 } while (false)
178 #include "sanitizer_common/sanitizer_common_syscalls.inc"
180 struct ThreadStartParam {
181 atomic_uintptr_t t;
182 atomic_uintptr_t is_registered;
185 #if ASAN_INTERCEPT_PTHREAD_CREATE
186 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
187 ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
188 AsanThread *t = nullptr;
189 while ((t = reinterpret_cast<AsanThread *>(
190 atomic_load(&param->t, memory_order_acquire))) == nullptr)
191 internal_sched_yield();
192 SetCurrentThread(t);
193 return t->ThreadStart(GetTid(), &param->is_registered);
196 INTERCEPTOR(int, pthread_create, void *thread,
197 void *attr, void *(*start_routine)(void*), void *arg) {
198 EnsureMainThreadIDIsCorrect();
199 // Strict init-order checking is thread-hostile.
200 if (flags()->strict_init_order)
201 StopInitOrderChecking();
202 GET_STACK_TRACE_THREAD;
203 int detached = 0;
204 if (attr)
205 REAL(pthread_attr_getdetachstate)(attr, &detached);
206 ThreadStartParam param;
207 atomic_store(&param.t, 0, memory_order_relaxed);
208 atomic_store(&param.is_registered, 0, memory_order_relaxed);
209 int result;
211 // Ignore all allocations made by pthread_create: thread stack/TLS may be
212 // stored by pthread for future reuse even after thread destruction, and
213 // the linked list it's stored in doesn't even hold valid pointers to the
214 // objects, the latter are calculated by obscure pointer arithmetic.
215 #if CAN_SANITIZE_LEAKS
216 __lsan::ScopedInterceptorDisabler disabler;
217 #endif
218 result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);
220 if (result == 0) {
221 u32 current_tid = GetCurrentTidOrInvalid();
222 AsanThread *t =
223 AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
224 atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
225 // Wait until the AsanThread object is initialized and the ThreadRegistry
226 // entry is in "started" state. One reason for this is that after this
227 // interceptor exits, the child thread's stack may be the only thing holding
228 // the |arg| pointer. This may cause LSan to report a leak if leak checking
229 // happens at a point when the interceptor has already exited, but the stack
230 // range for the child thread is not yet known.
231 while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
232 internal_sched_yield();
234 return result;
237 INTERCEPTOR(int, pthread_join, void *t, void **arg) {
238 return real_pthread_join(t, arg);
241 DEFINE_REAL_PTHREAD_FUNCTIONS
242 #endif // ASAN_INTERCEPT_PTHREAD_CREATE
244 #if ASAN_INTERCEPT_SWAPCONTEXT
245 static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
246 // Align to page size.
247 uptr PageSize = GetPageSizeCached();
248 uptr bottom = stack & ~(PageSize - 1);
249 ssize += stack - bottom;
250 ssize = RoundUpTo(ssize, PageSize);
251 static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb
252 if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) {
253 PoisonShadow(bottom, ssize, 0);
257 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
258 struct ucontext_t *ucp) {
259 static bool reported_warning = false;
260 if (!reported_warning) {
261 Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
262 "functions and may produce false positives in some cases!\n");
263 reported_warning = true;
265 // Clear shadow memory for new context (it may share stack
266 // with current context).
267 uptr stack, ssize;
268 ReadContextStack(ucp, &stack, &ssize);
269 ClearShadowMemoryForContextStack(stack, ssize);
270 int res = REAL(swapcontext)(oucp, ucp);
271 // swapcontext technically does not return, but program may swap context to
272 // "oucp" later, that would look as if swapcontext() returned 0.
273 // We need to clear shadow for ucp once again, as it may be in arbitrary
274 // state.
275 ClearShadowMemoryForContextStack(stack, ssize);
276 return res;
278 #endif // ASAN_INTERCEPT_SWAPCONTEXT
280 #if SANITIZER_NETBSD
281 #define longjmp __longjmp14
282 #define siglongjmp __siglongjmp14
283 #endif
285 INTERCEPTOR(void, longjmp, void *env, int val) {
286 __asan_handle_no_return();
287 REAL(longjmp)(env, val);
290 #if ASAN_INTERCEPT__LONGJMP
291 INTERCEPTOR(void, _longjmp, void *env, int val) {
292 __asan_handle_no_return();
293 REAL(_longjmp)(env, val);
295 #endif
297 #if ASAN_INTERCEPT___LONGJMP_CHK
298 INTERCEPTOR(void, __longjmp_chk, void *env, int val) {
299 __asan_handle_no_return();
300 REAL(__longjmp_chk)(env, val);
302 #endif
304 #if ASAN_INTERCEPT_SIGLONGJMP
305 INTERCEPTOR(void, siglongjmp, void *env, int val) {
306 __asan_handle_no_return();
307 REAL(siglongjmp)(env, val);
309 #endif
311 #if ASAN_INTERCEPT___CXA_THROW
312 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
313 CHECK(REAL(__cxa_throw));
314 __asan_handle_no_return();
315 REAL(__cxa_throw)(a, b, c);
317 #endif
319 #if ASAN_INTERCEPT_INDEX
320 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
321 INTERCEPTOR(char*, index, const char *string, int c)
322 ALIAS(WRAPPER_NAME(strchr));
323 # else
324 # if SANITIZER_MAC
325 DECLARE_REAL(char*, index, const char *string, int c)
326 OVERRIDE_FUNCTION(index, strchr);
327 # else
328 DEFINE_REAL(char*, index, const char *string, int c)
329 # endif
330 # endif
331 #endif // ASAN_INTERCEPT_INDEX
333 // For both strcat() and strncat() we need to check the validity of |to|
334 // argument irrespective of the |from| length.
335 INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT
336 void *ctx;
337 ASAN_INTERCEPTOR_ENTER(ctx, strcat); // NOLINT
338 ENSURE_ASAN_INITED();
339 if (flags()->replace_str) {
340 uptr from_length = REAL(strlen)(from);
341 ASAN_READ_RANGE(ctx, from, from_length + 1);
342 uptr to_length = REAL(strlen)(to);
343 ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
344 ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
345 // If the copying actually happens, the |from| string should not overlap
346 // with the resulting string starting at |to|, which has a length of
347 // to_length + from_length + 1.
348 if (from_length > 0) {
349 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1,
350 from, from_length + 1);
353 return REAL(strcat)(to, from); // NOLINT
356 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
357 void *ctx;
358 ASAN_INTERCEPTOR_ENTER(ctx, strncat);
359 ENSURE_ASAN_INITED();
360 if (flags()->replace_str) {
361 uptr from_length = MaybeRealStrnlen(from, size);
362 uptr copy_length = Min(size, from_length + 1);
363 ASAN_READ_RANGE(ctx, from, copy_length);
364 uptr to_length = REAL(strlen)(to);
365 ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
366 ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
367 if (from_length > 0) {
368 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
369 from, copy_length);
372 return REAL(strncat)(to, from, size);
375 INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
376 void *ctx;
377 ASAN_INTERCEPTOR_ENTER(ctx, strcpy); // NOLINT
378 #if SANITIZER_MAC
379 if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT
380 #endif
381 // strcpy is called from malloc_default_purgeable_zone()
382 // in __asan::ReplaceSystemAlloc() on Mac.
383 if (asan_init_is_running) {
384 return REAL(strcpy)(to, from); // NOLINT
386 ENSURE_ASAN_INITED();
387 if (flags()->replace_str) {
388 uptr from_size = REAL(strlen)(from) + 1;
389 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
390 ASAN_READ_RANGE(ctx, from, from_size);
391 ASAN_WRITE_RANGE(ctx, to, from_size);
393 return REAL(strcpy)(to, from); // NOLINT
396 INTERCEPTOR(char*, strdup, const char *s) {
397 void *ctx;
398 ASAN_INTERCEPTOR_ENTER(ctx, strdup);
399 if (UNLIKELY(!asan_inited)) return internal_strdup(s);
400 ENSURE_ASAN_INITED();
401 uptr length = REAL(strlen)(s);
402 if (flags()->replace_str) {
403 ASAN_READ_RANGE(ctx, s, length + 1);
405 GET_STACK_TRACE_MALLOC;
406 void *new_mem = asan_malloc(length + 1, &stack);
407 REAL(memcpy)(new_mem, s, length + 1);
408 return reinterpret_cast<char*>(new_mem);
411 #if ASAN_INTERCEPT___STRDUP
412 INTERCEPTOR(char*, __strdup, const char *s) {
413 void *ctx;
414 ASAN_INTERCEPTOR_ENTER(ctx, strdup);
415 if (UNLIKELY(!asan_inited)) return internal_strdup(s);
416 ENSURE_ASAN_INITED();
417 uptr length = REAL(strlen)(s);
418 if (flags()->replace_str) {
419 ASAN_READ_RANGE(ctx, s, length + 1);
421 GET_STACK_TRACE_MALLOC;
422 void *new_mem = asan_malloc(length + 1, &stack);
423 REAL(memcpy)(new_mem, s, length + 1);
424 return reinterpret_cast<char*>(new_mem);
426 #endif // ASAN_INTERCEPT___STRDUP
428 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
429 void *ctx;
430 ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
431 ENSURE_ASAN_INITED();
432 if (flags()->replace_str) {
433 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
434 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
435 ASAN_READ_RANGE(ctx, from, from_size);
436 ASAN_WRITE_RANGE(ctx, to, size);
438 return REAL(strncpy)(to, from, size);
441 INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
442 char **endptr, int base) {
443 void *ctx;
444 ASAN_INTERCEPTOR_ENTER(ctx, strtol);
445 ENSURE_ASAN_INITED();
446 if (!flags()->replace_str) {
447 return REAL(strtol)(nptr, endptr, base);
449 char *real_endptr;
450 long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT
451 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
452 return result;
455 INTERCEPTOR(int, atoi, const char *nptr) {
456 void *ctx;
457 ASAN_INTERCEPTOR_ENTER(ctx, atoi);
458 #if SANITIZER_MAC
459 if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);
460 #endif
461 ENSURE_ASAN_INITED();
462 if (!flags()->replace_str) {
463 return REAL(atoi)(nptr);
465 char *real_endptr;
466 // "man atoi" tells that behavior of atoi(nptr) is the same as
467 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
468 // parsed integer can't be stored in *long* type (even if it's
469 // different from int). So, we just imitate this behavior.
470 int result = REAL(strtol)(nptr, &real_endptr, 10);
471 FixRealStrtolEndptr(nptr, &real_endptr);
472 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
473 return result;
476 INTERCEPTOR(long, atol, const char *nptr) { // NOLINT
477 void *ctx;
478 ASAN_INTERCEPTOR_ENTER(ctx, atol);
479 #if SANITIZER_MAC
480 if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);
481 #endif
482 ENSURE_ASAN_INITED();
483 if (!flags()->replace_str) {
484 return REAL(atol)(nptr);
486 char *real_endptr;
487 long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT
488 FixRealStrtolEndptr(nptr, &real_endptr);
489 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
490 return result;
493 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
494 INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT
495 char **endptr, int base) {
496 void *ctx;
497 ASAN_INTERCEPTOR_ENTER(ctx, strtoll);
498 ENSURE_ASAN_INITED();
499 if (!flags()->replace_str) {
500 return REAL(strtoll)(nptr, endptr, base);
502 char *real_endptr;
503 long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT
504 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
505 return result;
508 INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT
509 void *ctx;
510 ASAN_INTERCEPTOR_ENTER(ctx, atoll);
511 ENSURE_ASAN_INITED();
512 if (!flags()->replace_str) {
513 return REAL(atoll)(nptr);
515 char *real_endptr;
516 long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT
517 FixRealStrtolEndptr(nptr, &real_endptr);
518 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
519 return result;
521 #endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
523 #if ASAN_INTERCEPT___CXA_ATEXIT
524 static void AtCxaAtexit(void *unused) {
525 (void)unused;
526 StopInitOrderChecking();
529 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
530 void *dso_handle) {
531 #if SANITIZER_MAC
532 if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);
533 #endif
534 ENSURE_ASAN_INITED();
535 int res = REAL(__cxa_atexit)(func, arg, dso_handle);
536 REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
537 return res;
539 #endif // ASAN_INTERCEPT___CXA_ATEXIT
541 #if ASAN_INTERCEPT_FORK
542 INTERCEPTOR(int, fork, void) {
543 ENSURE_ASAN_INITED();
544 int pid = REAL(fork)();
545 return pid;
547 #endif // ASAN_INTERCEPT_FORK
549 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
550 namespace __asan {
551 void InitializeAsanInterceptors() {
552 static bool was_called_once;
553 CHECK(!was_called_once);
554 was_called_once = true;
555 InitializeCommonInterceptors();
556 InitializeSignalInterceptors();
558 // Intercept str* functions.
559 ASAN_INTERCEPT_FUNC(strcat); // NOLINT
560 ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
561 ASAN_INTERCEPT_FUNC(strncat);
562 ASAN_INTERCEPT_FUNC(strncpy);
563 ASAN_INTERCEPT_FUNC(strdup);
564 #if ASAN_INTERCEPT___STRDUP
565 ASAN_INTERCEPT_FUNC(__strdup);
566 #endif
567 #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
568 ASAN_INTERCEPT_FUNC(index);
569 #endif
571 ASAN_INTERCEPT_FUNC(atoi);
572 ASAN_INTERCEPT_FUNC(atol);
573 ASAN_INTERCEPT_FUNC(strtol);
574 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
575 ASAN_INTERCEPT_FUNC(atoll);
576 ASAN_INTERCEPT_FUNC(strtoll);
577 #endif
579 // Intecept jump-related functions.
580 ASAN_INTERCEPT_FUNC(longjmp);
582 #if ASAN_INTERCEPT_SWAPCONTEXT
583 ASAN_INTERCEPT_FUNC(swapcontext);
584 #endif
585 #if ASAN_INTERCEPT__LONGJMP
586 ASAN_INTERCEPT_FUNC(_longjmp);
587 #endif
588 #if ASAN_INTERCEPT___LONGJMP_CHK
589 ASAN_INTERCEPT_FUNC(__longjmp_chk);
590 #endif
591 #if ASAN_INTERCEPT_SIGLONGJMP
592 ASAN_INTERCEPT_FUNC(siglongjmp);
593 #endif
595 // Intercept exception handling functions.
596 #if ASAN_INTERCEPT___CXA_THROW
597 ASAN_INTERCEPT_FUNC(__cxa_throw);
598 #endif
600 // Intercept threading-related functions
601 #if ASAN_INTERCEPT_PTHREAD_CREATE
602 #if defined(ASAN_PTHREAD_CREATE_VERSION)
603 ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
604 #else
605 ASAN_INTERCEPT_FUNC(pthread_create);
606 #endif
607 ASAN_INTERCEPT_FUNC(pthread_join);
608 #endif
610 // Intercept atexit function.
611 #if ASAN_INTERCEPT___CXA_ATEXIT
612 ASAN_INTERCEPT_FUNC(__cxa_atexit);
613 #endif
615 #if ASAN_INTERCEPT_FORK
616 ASAN_INTERCEPT_FUNC(fork);
617 #endif
619 InitializePlatformInterceptors();
621 VReport(1, "AddressSanitizer: libc interceptors initialized\n");
624 } // namespace __asan
626 #endif // !SANITIZER_FUCHSIA