* config/rs6000/rs6000.c (rs6000_deligitimze_address): Do not
[official-gcc.git] / libsanitizer / asan / asan_interceptors.cc
blob5b544c87fcb85adcae8f5ecfa31c14498545ff10
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 //===----------------------------------------------------------------------===//
12 #include "asan_interceptors.h"
14 #include "asan_allocator.h"
15 #include "asan_intercepted_functions.h"
16 #include "asan_internal.h"
17 #include "asan_mapping.h"
18 #include "asan_report.h"
19 #include "asan_stack.h"
20 #include "asan_stats.h"
21 #include "asan_thread_registry.h"
22 #include "interception/interception.h"
23 #include "sanitizer/asan_interface.h"
24 #include "sanitizer_common/sanitizer_libc.h"
26 namespace __asan {
28 // Instruments read/write access to a single byte in memory.
29 // On error calls __asan_report_error, which aborts the program.
30 #define ACCESS_ADDRESS(address, isWrite) do { \
31 if (!AddrIsInMem(address) || AddressIsPoisoned(address)) { \
32 GET_CURRENT_PC_BP_SP; \
33 __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \
34 } \
35 } while (0)
37 // We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
38 // and ASAN_WRITE_RANGE as macro instead of function so
39 // that no extra frames are created, and stack trace contains
40 // relevant information only.
42 // Instruments read/write access to a memory range.
43 // More complex implementation is possible, for now just
44 // checking the first and the last byte of a range.
45 #define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
46 if (size > 0) { \
47 uptr ptr = (uptr)(offset); \
48 ACCESS_ADDRESS(ptr, isWrite); \
49 ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \
50 } \
51 } while (0)
53 #define ASAN_READ_RANGE(offset, size) do { \
54 ACCESS_MEMORY_RANGE(offset, size, false); \
55 } while (0)
57 #define ASAN_WRITE_RANGE(offset, size) do { \
58 ACCESS_MEMORY_RANGE(offset, size, true); \
59 } while (0)
61 // Behavior of functions like "memcpy" or "strcpy" is undefined
62 // if memory intervals overlap. We report error in this case.
63 // Macro is used to avoid creation of new frames.
64 static inline bool RangesOverlap(const char *offset1, uptr length1,
65 const char *offset2, uptr length2) {
66 return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
68 #define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
69 const char *offset1 = (const char*)_offset1; \
70 const char *offset2 = (const char*)_offset2; \
71 if (RangesOverlap(offset1, length1, offset2, length2)) { \
72 GET_STACK_TRACE_HERE(kStackTraceMax); \
73 ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \
74 offset2, length2, &stack); \
75 } \
76 } while (0)
78 #define ENSURE_ASAN_INITED() do { \
79 CHECK(!asan_init_is_running); \
80 if (!asan_inited) { \
81 __asan_init(); \
82 } \
83 } while (0)
85 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
86 #if ASAN_INTERCEPT_STRNLEN
87 if (REAL(strnlen) != 0) {
88 return REAL(strnlen)(s, maxlen);
90 #endif
91 return internal_strnlen(s, maxlen);
94 } // namespace __asan
96 // ---------------------- Wrappers ---------------- {{{1
97 using namespace __asan; // NOLINT
99 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
100 AsanThread *t = (AsanThread*)arg;
101 asanThreadRegistry().SetCurrent(t);
102 return t->ThreadStart();
105 #if ASAN_INTERCEPT_PTHREAD_CREATE
106 INTERCEPTOR(int, pthread_create, void *thread,
107 void *attr, void *(*start_routine)(void*), void *arg) {
108 GET_STACK_TRACE_HERE(kStackTraceMax);
109 u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
110 AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
111 asanThreadRegistry().RegisterThread(t);
112 return REAL(pthread_create)(thread, attr, asan_thread_start, t);
114 #endif // ASAN_INTERCEPT_PTHREAD_CREATE
116 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
117 INTERCEPTOR(void*, signal, int signum, void *handler) {
118 if (!AsanInterceptsSignal(signum)) {
119 return REAL(signal)(signum, handler);
121 return 0;
124 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
125 struct sigaction *oldact) {
126 if (!AsanInterceptsSignal(signum)) {
127 return REAL(sigaction)(signum, act, oldact);
129 return 0;
131 #elif ASAN_POSIX
132 // We need to have defined REAL(sigaction) on posix systems.
133 DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
134 struct sigaction *oldact);
135 #endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
137 #if ASAN_INTERCEPT_SWAPCONTEXT
138 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
139 struct ucontext_t *ucp) {
140 static bool reported_warning = false;
141 if (!reported_warning) {
142 Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
143 "functions and may produce false positives in some cases!\n");
144 reported_warning = true;
146 // Clear shadow memory for new context (it may share stack
147 // with current context).
148 ClearShadowMemoryForContext(ucp);
149 int res = REAL(swapcontext)(oucp, ucp);
150 // swapcontext technically does not return, but program may swap context to
151 // "oucp" later, that would look as if swapcontext() returned 0.
152 // We need to clear shadow for ucp once again, as it may be in arbitrary
153 // state.
154 ClearShadowMemoryForContext(ucp);
155 return res;
157 #endif
159 INTERCEPTOR(void, longjmp, void *env, int val) {
160 __asan_handle_no_return();
161 REAL(longjmp)(env, val);
164 #if ASAN_INTERCEPT__LONGJMP
165 INTERCEPTOR(void, _longjmp, void *env, int val) {
166 __asan_handle_no_return();
167 REAL(_longjmp)(env, val);
169 #endif
171 #if ASAN_INTERCEPT_SIGLONGJMP
172 INTERCEPTOR(void, siglongjmp, void *env, int val) {
173 __asan_handle_no_return();
174 REAL(siglongjmp)(env, val);
176 #endif
178 #if ASAN_INTERCEPT___CXA_THROW
179 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
180 CHECK(REAL(__cxa_throw));
181 __asan_handle_no_return();
182 REAL(__cxa_throw)(a, b, c);
184 #endif
186 // intercept mlock and friends.
187 // Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
188 // All functions return 0 (success).
189 static void MlockIsUnsupported() {
190 static bool printed = 0;
191 if (printed) return;
192 printed = true;
193 Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
196 extern "C" {
197 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
198 MlockIsUnsupported();
199 return 0;
202 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
203 MlockIsUnsupported();
204 return 0;
207 INTERCEPTOR(int, mlockall, int flags) {
208 MlockIsUnsupported();
209 return 0;
212 INTERCEPTOR(int, munlockall, void) {
213 MlockIsUnsupported();
214 return 0;
216 } // extern "C"
218 static inline int CharCmp(unsigned char c1, unsigned char c2) {
219 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
222 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
223 int c1_low = ToLower(c1);
224 int c2_low = ToLower(c2);
225 return c1_low - c2_low;
228 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
229 if (!asan_inited) return internal_memcmp(a1, a2, size);
230 ENSURE_ASAN_INITED();
231 unsigned char c1 = 0, c2 = 0;
232 const unsigned char *s1 = (const unsigned char*)a1;
233 const unsigned char *s2 = (const unsigned char*)a2;
234 uptr i;
235 for (i = 0; i < size; i++) {
236 c1 = s1[i];
237 c2 = s2[i];
238 if (c1 != c2) break;
240 ASAN_READ_RANGE(s1, Min(i + 1, size));
241 ASAN_READ_RANGE(s2, Min(i + 1, size));
242 return CharCmp(c1, c2);
245 INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {
246 if (!asan_inited) return internal_memcpy(to, from, size);
247 // memcpy is called during __asan_init() from the internals
248 // of printf(...).
249 if (asan_init_is_running) {
250 return REAL(memcpy)(to, from, size);
252 ENSURE_ASAN_INITED();
253 if (flags()->replace_intrin) {
254 if (to != from) {
255 // We do not treat memcpy with to==from as a bug.
256 // See http://llvm.org/bugs/show_bug.cgi?id=11763.
257 CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);
259 ASAN_WRITE_RANGE(from, size);
260 ASAN_READ_RANGE(to, size);
262 #if MAC_INTERPOSE_FUNCTIONS
263 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8.
264 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116.
265 return internal_memcpy(to, from, size);
266 #else
267 return REAL(memcpy)(to, from, size);
268 #endif
271 INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
272 if (!asan_inited) return internal_memmove(to, from, size);
273 if (asan_init_is_running) {
274 return REAL(memmove)(to, from, size);
276 ENSURE_ASAN_INITED();
277 if (flags()->replace_intrin) {
278 ASAN_WRITE_RANGE(from, size);
279 ASAN_READ_RANGE(to, size);
281 #if MAC_INTERPOSE_FUNCTIONS
282 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8.
283 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116.
284 return internal_memmove(to, from, size);
285 #else
286 return REAL(memmove)(to, from, size);
287 #endif
290 INTERCEPTOR(void*, memset, void *block, int c, uptr size) {
291 if (!asan_inited) return internal_memset(block, c, size);
292 // memset is called inside Printf.
293 if (asan_init_is_running) {
294 return REAL(memset)(block, c, size);
296 ENSURE_ASAN_INITED();
297 if (flags()->replace_intrin) {
298 ASAN_WRITE_RANGE(block, size);
300 return REAL(memset)(block, c, size);
303 INTERCEPTOR(char*, strchr, const char *str, int c) {
304 if (!asan_inited) return internal_strchr(str, c);
305 // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is
306 // used.
307 if (asan_init_is_running) {
308 return REAL(strchr)(str, c);
310 ENSURE_ASAN_INITED();
311 char *result = REAL(strchr)(str, c);
312 if (flags()->replace_str) {
313 uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1;
314 ASAN_READ_RANGE(str, bytes_read);
316 return result;
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 DEFINE_REAL(char*, index, const char *string, int c)
325 # endif
326 #endif // ASAN_INTERCEPT_INDEX
328 // For both strcat() and strncat() we need to check the validity of |to|
329 // argument irrespective of the |from| length.
330 INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT
331 ENSURE_ASAN_INITED();
332 if (flags()->replace_str) {
333 uptr from_length = REAL(strlen)(from);
334 ASAN_READ_RANGE(from, from_length + 1);
335 uptr to_length = REAL(strlen)(to);
336 ASAN_READ_RANGE(to, to_length);
337 ASAN_WRITE_RANGE(to + to_length, from_length + 1);
338 // If the copying actually happens, the |from| string should not overlap
339 // with the resulting string starting at |to|, which has a length of
340 // to_length + from_length + 1.
341 if (from_length > 0) {
342 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1,
343 from, from_length + 1);
346 return REAL(strcat)(to, from); // NOLINT
349 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
350 ENSURE_ASAN_INITED();
351 if (flags()->replace_str) {
352 uptr from_length = MaybeRealStrnlen(from, size);
353 uptr copy_length = Min(size, from_length + 1);
354 ASAN_READ_RANGE(from, copy_length);
355 uptr to_length = REAL(strlen)(to);
356 ASAN_READ_RANGE(to, to_length);
357 ASAN_WRITE_RANGE(to + to_length, from_length + 1);
358 if (from_length > 0) {
359 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
360 from, copy_length);
363 return REAL(strncat)(to, from, size);
366 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
367 if (!asan_inited) return internal_strcmp(s1, s2);
368 if (asan_init_is_running) {
369 return REAL(strcmp)(s1, s2);
371 ENSURE_ASAN_INITED();
372 unsigned char c1, c2;
373 uptr i;
374 for (i = 0; ; i++) {
375 c1 = (unsigned char)s1[i];
376 c2 = (unsigned char)s2[i];
377 if (c1 != c2 || c1 == '\0') break;
379 ASAN_READ_RANGE(s1, i + 1);
380 ASAN_READ_RANGE(s2, i + 1);
381 return CharCmp(c1, c2);
384 INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
385 #if MAC_INTERPOSE_FUNCTIONS
386 if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT
387 #endif
388 // strcpy is called from malloc_default_purgeable_zone()
389 // in __asan::ReplaceSystemAlloc() on Mac.
390 if (asan_init_is_running) {
391 return REAL(strcpy)(to, from); // NOLINT
393 ENSURE_ASAN_INITED();
394 if (flags()->replace_str) {
395 uptr from_size = REAL(strlen)(from) + 1;
396 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
397 ASAN_READ_RANGE(from, from_size);
398 ASAN_WRITE_RANGE(to, from_size);
400 return REAL(strcpy)(to, from); // NOLINT
403 #if ASAN_INTERCEPT_STRDUP
404 INTERCEPTOR(char*, strdup, const char *s) {
405 #if MAC_INTERPOSE_FUNCTIONS
406 // FIXME: because internal_strdup() uses InternalAlloc(), which currently
407 // just calls malloc() on Mac, we can't use internal_strdup() with the
408 // dynamic runtime. We can remove the call to REAL(strdup) once InternalAlloc
409 // starts using mmap() instead.
410 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=123.
411 if (!asan_inited) return REAL(strdup)(s);
412 #endif
413 if (!asan_inited) return internal_strdup(s);
414 ENSURE_ASAN_INITED();
415 if (flags()->replace_str) {
416 uptr length = REAL(strlen)(s);
417 ASAN_READ_RANGE(s, length + 1);
419 return REAL(strdup)(s);
421 #endif
423 INTERCEPTOR(uptr, strlen, const char *s) {
424 if (!asan_inited) return internal_strlen(s);
425 // strlen is called from malloc_default_purgeable_zone()
426 // in __asan::ReplaceSystemAlloc() on Mac.
427 if (asan_init_is_running) {
428 return REAL(strlen)(s);
430 ENSURE_ASAN_INITED();
431 uptr length = REAL(strlen)(s);
432 if (flags()->replace_str) {
433 ASAN_READ_RANGE(s, length + 1);
435 return length;
438 #if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP
439 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
440 ENSURE_ASAN_INITED();
441 unsigned char c1, c2;
442 uptr i;
443 for (i = 0; ; i++) {
444 c1 = (unsigned char)s1[i];
445 c2 = (unsigned char)s2[i];
446 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
448 ASAN_READ_RANGE(s1, i + 1);
449 ASAN_READ_RANGE(s2, i + 1);
450 return CharCaseCmp(c1, c2);
453 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, uptr n) {
454 ENSURE_ASAN_INITED();
455 unsigned char c1 = 0, c2 = 0;
456 uptr i;
457 for (i = 0; i < n; i++) {
458 c1 = (unsigned char)s1[i];
459 c2 = (unsigned char)s2[i];
460 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
462 ASAN_READ_RANGE(s1, Min(i + 1, n));
463 ASAN_READ_RANGE(s2, Min(i + 1, n));
464 return CharCaseCmp(c1, c2);
466 #endif // ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP
468 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
469 if (!asan_inited) return internal_strncmp(s1, s2, size);
470 // strncmp is called from malloc_default_purgeable_zone()
471 // in __asan::ReplaceSystemAlloc() on Mac.
472 if (asan_init_is_running) {
473 return REAL(strncmp)(s1, s2, size);
475 ENSURE_ASAN_INITED();
476 unsigned char c1 = 0, c2 = 0;
477 uptr i;
478 for (i = 0; i < size; i++) {
479 c1 = (unsigned char)s1[i];
480 c2 = (unsigned char)s2[i];
481 if (c1 != c2 || c1 == '\0') break;
483 ASAN_READ_RANGE(s1, Min(i + 1, size));
484 ASAN_READ_RANGE(s2, Min(i + 1, size));
485 return CharCmp(c1, c2);
488 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
489 ENSURE_ASAN_INITED();
490 if (flags()->replace_str) {
491 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
492 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
493 ASAN_READ_RANGE(from, from_size);
494 ASAN_WRITE_RANGE(to, size);
496 return REAL(strncpy)(to, from, size);
499 #if ASAN_INTERCEPT_STRNLEN
500 INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) {
501 ENSURE_ASAN_INITED();
502 uptr length = REAL(strnlen)(s, maxlen);
503 if (flags()->replace_str) {
504 ASAN_READ_RANGE(s, Min(length + 1, maxlen));
506 return length;
508 #endif // ASAN_INTERCEPT_STRNLEN
510 static inline bool IsValidStrtolBase(int base) {
511 return (base == 0) || (2 <= base && base <= 36);
514 static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
515 CHECK(endptr != 0);
516 if (nptr == *endptr) {
517 // No digits were found at strtol call, we need to find out the last
518 // symbol accessed by strtoll on our own.
519 // We get this symbol by skipping leading blanks and optional +/- sign.
520 while (IsSpace(*nptr)) nptr++;
521 if (*nptr == '+' || *nptr == '-') nptr++;
522 *endptr = (char*)nptr;
524 CHECK(*endptr >= nptr);
527 INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
528 char **endptr, int base) {
529 ENSURE_ASAN_INITED();
530 if (!flags()->replace_str) {
531 return REAL(strtol)(nptr, endptr, base);
533 char *real_endptr;
534 long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT
535 if (endptr != 0) {
536 *endptr = real_endptr;
538 if (IsValidStrtolBase(base)) {
539 FixRealStrtolEndptr(nptr, &real_endptr);
540 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
542 return result;
545 INTERCEPTOR(int, atoi, const char *nptr) {
546 #if MAC_INTERPOSE_FUNCTIONS
547 if (!asan_inited) return REAL(atoi)(nptr);
548 #endif
549 ENSURE_ASAN_INITED();
550 if (!flags()->replace_str) {
551 return REAL(atoi)(nptr);
553 char *real_endptr;
554 // "man atoi" tells that behavior of atoi(nptr) is the same as
555 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
556 // parsed integer can't be stored in *long* type (even if it's
557 // different from int). So, we just imitate this behavior.
558 int result = REAL(strtol)(nptr, &real_endptr, 10);
559 FixRealStrtolEndptr(nptr, &real_endptr);
560 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
561 return result;
564 INTERCEPTOR(long, atol, const char *nptr) { // NOLINT
565 #if MAC_INTERPOSE_FUNCTIONS
566 if (!asan_inited) return REAL(atol)(nptr);
567 #endif
568 ENSURE_ASAN_INITED();
569 if (!flags()->replace_str) {
570 return REAL(atol)(nptr);
572 char *real_endptr;
573 long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT
574 FixRealStrtolEndptr(nptr, &real_endptr);
575 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
576 return result;
579 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
580 INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT
581 char **endptr, int base) {
582 ENSURE_ASAN_INITED();
583 if (!flags()->replace_str) {
584 return REAL(strtoll)(nptr, endptr, base);
586 char *real_endptr;
587 long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT
588 if (endptr != 0) {
589 *endptr = real_endptr;
591 // If base has unsupported value, strtoll can exit with EINVAL
592 // without reading any characters. So do additional checks only
593 // if base is valid.
594 if (IsValidStrtolBase(base)) {
595 FixRealStrtolEndptr(nptr, &real_endptr);
596 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
598 return result;
601 INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT
602 ENSURE_ASAN_INITED();
603 if (!flags()->replace_str) {
604 return REAL(atoll)(nptr);
606 char *real_endptr;
607 long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT
608 FixRealStrtolEndptr(nptr, &real_endptr);
609 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
610 return result;
612 #endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
614 #define ASAN_INTERCEPT_FUNC(name) do { \
615 if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \
616 Report("AddressSanitizer: failed to intercept '" #name "'\n"); \
617 } while (0)
619 #if defined(_WIN32)
620 INTERCEPTOR_WINAPI(DWORD, CreateThread,
621 void* security, uptr stack_size,
622 DWORD (__stdcall *start_routine)(void*), void* arg,
623 DWORD flags, void* tid) {
624 GET_STACK_TRACE_HERE(kStackTraceMax);
625 u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
626 AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
627 asanThreadRegistry().RegisterThread(t);
628 return REAL(CreateThread)(security, stack_size,
629 asan_thread_start, t, flags, tid);
632 namespace __asan {
633 void InitializeWindowsInterceptors() {
634 ASAN_INTERCEPT_FUNC(CreateThread);
637 } // namespace __asan
638 #endif
640 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
641 namespace __asan {
642 void InitializeAsanInterceptors() {
643 static bool was_called_once;
644 CHECK(was_called_once == false);
645 was_called_once = true;
646 #if MAC_INTERPOSE_FUNCTIONS
647 return;
648 #endif
649 // Intercept mem* functions.
650 ASAN_INTERCEPT_FUNC(memcmp);
651 ASAN_INTERCEPT_FUNC(memmove);
652 ASAN_INTERCEPT_FUNC(memset);
653 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
654 ASAN_INTERCEPT_FUNC(memcpy);
655 } else {
656 #if !MAC_INTERPOSE_FUNCTIONS
657 // If we're using dynamic interceptors on Mac, these two are just plain
658 // functions.
659 internal_memcpy(&REAL(memcpy), &REAL(memmove), sizeof(REAL(memmove)));
660 #endif
663 // Intercept str* functions.
664 ASAN_INTERCEPT_FUNC(strcat); // NOLINT
665 ASAN_INTERCEPT_FUNC(strchr);
666 ASAN_INTERCEPT_FUNC(strcmp);
667 ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
668 ASAN_INTERCEPT_FUNC(strlen);
669 ASAN_INTERCEPT_FUNC(strncat);
670 ASAN_INTERCEPT_FUNC(strncmp);
671 ASAN_INTERCEPT_FUNC(strncpy);
672 #if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP
673 ASAN_INTERCEPT_FUNC(strcasecmp);
674 ASAN_INTERCEPT_FUNC(strncasecmp);
675 #endif
676 #if ASAN_INTERCEPT_STRDUP
677 ASAN_INTERCEPT_FUNC(strdup);
678 #endif
679 #if ASAN_INTERCEPT_STRNLEN
680 ASAN_INTERCEPT_FUNC(strnlen);
681 #endif
682 #if ASAN_INTERCEPT_INDEX
683 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
684 ASAN_INTERCEPT_FUNC(index);
685 # else
686 CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr)));
687 # endif
688 #endif
690 ASAN_INTERCEPT_FUNC(atoi);
691 ASAN_INTERCEPT_FUNC(atol);
692 ASAN_INTERCEPT_FUNC(strtol);
693 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
694 ASAN_INTERCEPT_FUNC(atoll);
695 ASAN_INTERCEPT_FUNC(strtoll);
696 #endif
698 #if ASAN_INTERCEPT_MLOCKX
699 // Intercept mlock/munlock.
700 ASAN_INTERCEPT_FUNC(mlock);
701 ASAN_INTERCEPT_FUNC(munlock);
702 ASAN_INTERCEPT_FUNC(mlockall);
703 ASAN_INTERCEPT_FUNC(munlockall);
704 #endif
706 // Intecept signal- and jump-related functions.
707 ASAN_INTERCEPT_FUNC(longjmp);
708 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
709 ASAN_INTERCEPT_FUNC(sigaction);
710 ASAN_INTERCEPT_FUNC(signal);
711 #endif
712 #if ASAN_INTERCEPT_SWAPCONTEXT
713 ASAN_INTERCEPT_FUNC(swapcontext);
714 #endif
715 #if ASAN_INTERCEPT__LONGJMP
716 ASAN_INTERCEPT_FUNC(_longjmp);
717 #endif
718 #if ASAN_INTERCEPT_SIGLONGJMP
719 ASAN_INTERCEPT_FUNC(siglongjmp);
720 #endif
722 // Intercept exception handling functions.
723 #if ASAN_INTERCEPT___CXA_THROW
724 INTERCEPT_FUNCTION(__cxa_throw);
725 #endif
727 // Intercept threading-related functions
728 #if ASAN_INTERCEPT_PTHREAD_CREATE
729 ASAN_INTERCEPT_FUNC(pthread_create);
730 #endif
732 // Some Windows-specific interceptors.
733 #if defined(_WIN32)
734 InitializeWindowsInterceptors();
735 #endif
737 // Some Mac-specific interceptors.
738 #if defined(__APPLE__)
739 InitializeMacInterceptors();
740 #endif
742 if (flags()->verbosity > 0) {
743 Report("AddressSanitizer: libc interceptors initialized\n");
747 } // namespace __asan