10b57cec5SDimitry Andric //===-- asan_interceptors.h -------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file is a part of AddressSanitizer, an address sanity checker. 100b57cec5SDimitry Andric // 1168d75effSDimitry Andric // ASan-private header for asan_interceptors.cpp 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric #ifndef ASAN_INTERCEPTORS_H 140b57cec5SDimitry Andric #define ASAN_INTERCEPTORS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "asan_interceptors_memintrinsics.h" 17e8d8bef9SDimitry Andric #include "asan_internal.h" 180b57cec5SDimitry Andric #include "interception/interception.h" 19e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_platform.h" 200b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_platform_interceptors.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace __asan { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric void InitializeAsanInterceptors(); 250b57cec5SDimitry Andric void InitializePlatformInterceptors(); 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric } // namespace __asan 280b57cec5SDimitry Andric 29fe6060f1SDimitry Andric // There is no general interception at all on Fuchsia. 300b57cec5SDimitry Andric // Only the functions in asan_interceptors_memintrinsics.h are 310b57cec5SDimitry Andric // really defined to replace libc functions. 32fe6060f1SDimitry Andric #if !SANITIZER_FUCHSIA 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // Use macro to describe if specific function should be 350b57cec5SDimitry Andric // intercepted on a given platform. 360b57cec5SDimitry Andric #if !SANITIZER_WINDOWS 370b57cec5SDimitry Andric # define ASAN_INTERCEPT__LONGJMP 1 380b57cec5SDimitry Andric # define ASAN_INTERCEPT_INDEX 1 390b57cec5SDimitry Andric # define ASAN_INTERCEPT_PTHREAD_CREATE 1 400b57cec5SDimitry Andric #else 410b57cec5SDimitry Andric # define ASAN_INTERCEPT__LONGJMP 0 420b57cec5SDimitry Andric # define ASAN_INTERCEPT_INDEX 0 430b57cec5SDimitry Andric # define ASAN_INTERCEPT_PTHREAD_CREATE 0 440b57cec5SDimitry Andric #endif 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ 470b57cec5SDimitry Andric SANITIZER_SOLARIS 480b57cec5SDimitry Andric # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1 490b57cec5SDimitry Andric #else 500b57cec5SDimitry Andric # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0 510b57cec5SDimitry Andric #endif 520b57cec5SDimitry Andric 53e8d8bef9SDimitry Andric #if SANITIZER_GLIBC || SANITIZER_SOLARIS 540b57cec5SDimitry Andric # define ASAN_INTERCEPT_SWAPCONTEXT 1 550b57cec5SDimitry Andric #else 560b57cec5SDimitry Andric # define ASAN_INTERCEPT_SWAPCONTEXT 0 570b57cec5SDimitry Andric #endif 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric #if !SANITIZER_WINDOWS 600b57cec5SDimitry Andric # define ASAN_INTERCEPT_SIGLONGJMP 1 610b57cec5SDimitry Andric #else 620b57cec5SDimitry Andric # define ASAN_INTERCEPT_SIGLONGJMP 0 630b57cec5SDimitry Andric #endif 640b57cec5SDimitry Andric 65e8d8bef9SDimitry Andric #if SANITIZER_GLIBC 660b57cec5SDimitry Andric # define ASAN_INTERCEPT___LONGJMP_CHK 1 670b57cec5SDimitry Andric #else 680b57cec5SDimitry Andric # define ASAN_INTERCEPT___LONGJMP_CHK 0 690b57cec5SDimitry Andric #endif 700b57cec5SDimitry Andric 71*06c3fb27SDimitry Andric #if ASAN_HAS_EXCEPTIONS && !SANITIZER_SOLARIS && !SANITIZER_NETBSD && \ 72*06c3fb27SDimitry Andric (!SANITIZER_WINDOWS || (defined(__MINGW32__) && defined(__i386__))) 730b57cec5SDimitry Andric # define ASAN_INTERCEPT___CXA_THROW 1 740b57cec5SDimitry Andric # define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 750b57cec5SDimitry Andric # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__)) 760b57cec5SDimitry Andric # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1 770b57cec5SDimitry Andric # else 780b57cec5SDimitry Andric # define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 1 790b57cec5SDimitry Andric # endif 800b57cec5SDimitry Andric #else 810b57cec5SDimitry Andric # define ASAN_INTERCEPT___CXA_THROW 0 820b57cec5SDimitry Andric # define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 830b57cec5SDimitry Andric # define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 0 840b57cec5SDimitry Andric # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0 850b57cec5SDimitry Andric #endif 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric #if !SANITIZER_WINDOWS 880b57cec5SDimitry Andric # define ASAN_INTERCEPT___CXA_ATEXIT 1 890b57cec5SDimitry Andric #else 900b57cec5SDimitry Andric # define ASAN_INTERCEPT___CXA_ATEXIT 0 910b57cec5SDimitry Andric #endif 920b57cec5SDimitry Andric 9368d75effSDimitry Andric #if SANITIZER_NETBSD 9468d75effSDimitry Andric # define ASAN_INTERCEPT_ATEXIT 1 9568d75effSDimitry Andric #else 9668d75effSDimitry Andric # define ASAN_INTERCEPT_ATEXIT 0 9768d75effSDimitry Andric #endif 9868d75effSDimitry Andric 99e8d8bef9SDimitry Andric #if SANITIZER_GLIBC 1000b57cec5SDimitry Andric # define ASAN_INTERCEPT___STRDUP 1 1010b57cec5SDimitry Andric #else 1020b57cec5SDimitry Andric # define ASAN_INTERCEPT___STRDUP 0 1030b57cec5SDimitry Andric #endif 1040b57cec5SDimitry Andric 105*06c3fb27SDimitry Andric #if SANITIZER_GLIBC && ASAN_INTERCEPT_PTHREAD_CREATE 106*06c3fb27SDimitry Andric # define ASAN_INTERCEPT_TIMEDJOIN 1 107*06c3fb27SDimitry Andric # define ASAN_INTERCEPT_TRYJOIN 1 108*06c3fb27SDimitry Andric #else 109*06c3fb27SDimitry Andric # define ASAN_INTERCEPT_TIMEDJOIN 0 110*06c3fb27SDimitry Andric # define ASAN_INTERCEPT_TRYJOIN 0 111*06c3fb27SDimitry Andric #endif 112*06c3fb27SDimitry Andric 113e8d8bef9SDimitry Andric #if SANITIZER_LINUX && \ 114e8d8bef9SDimitry Andric (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \ 115bdd1243dSDimitry Andric defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) 1160b57cec5SDimitry Andric # define ASAN_INTERCEPT_VFORK 1 1170b57cec5SDimitry Andric #else 1180b57cec5SDimitry Andric # define ASAN_INTERCEPT_VFORK 0 1190b57cec5SDimitry Andric #endif 1200b57cec5SDimitry Andric 12168d75effSDimitry Andric #if SANITIZER_NETBSD 12268d75effSDimitry Andric # define ASAN_INTERCEPT_PTHREAD_ATFORK 1 12368d75effSDimitry Andric #else 12468d75effSDimitry Andric # define ASAN_INTERCEPT_PTHREAD_ATFORK 0 12568d75effSDimitry Andric #endif 12668d75effSDimitry Andric 1270b57cec5SDimitry Andric DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size) 1280b57cec5SDimitry Andric DECLARE_REAL(char*, strchr, const char *str, int c) 1290b57cec5SDimitry Andric DECLARE_REAL(SIZE_T, strlen, const char *s) 1300b57cec5SDimitry Andric DECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size) 1310b57cec5SDimitry Andric DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen) 1320b57cec5SDimitry Andric DECLARE_REAL(char*, strstr, const char *s1, const char *s2) 1330b57cec5SDimitry Andric 13481ad6265SDimitry Andric # if !SANITIZER_APPLE 1350b57cec5SDimitry Andric # define ASAN_INTERCEPT_FUNC(name) \ 1360b57cec5SDimitry Andric do { \ 1370b57cec5SDimitry Andric if (!INTERCEPT_FUNCTION(name)) \ 138e8d8bef9SDimitry Andric VReport(1, "AddressSanitizer: failed to intercept '%s'\n", #name); \ 1390b57cec5SDimitry Andric } while (0) 1400b57cec5SDimitry Andric # define ASAN_INTERCEPT_FUNC_VER(name, ver) \ 1410b57cec5SDimitry Andric do { \ 1420b57cec5SDimitry Andric if (!INTERCEPT_FUNCTION_VER(name, ver)) \ 143349cc55cSDimitry Andric VReport(1, "AddressSanitizer: failed to intercept '%s@@%s'\n", \ 144349cc55cSDimitry Andric #name, ver); \ 1450b57cec5SDimitry Andric } while (0) 146fe6060f1SDimitry Andric # define ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \ 147fe6060f1SDimitry Andric do { \ 148fe6060f1SDimitry Andric if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \ 149349cc55cSDimitry Andric VReport(1, \ 150349cc55cSDimitry Andric "AddressSanitizer: failed to intercept '%s@@%s' or '%s'\n", \ 151349cc55cSDimitry Andric #name, ver, #name); \ 152fe6060f1SDimitry Andric } while (0) 153fe6060f1SDimitry Andric 1540b57cec5SDimitry Andric # else 1550b57cec5SDimitry Andric // OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. 1560b57cec5SDimitry Andric # define ASAN_INTERCEPT_FUNC(name) 15781ad6265SDimitry Andric # endif // SANITIZER_APPLE 1580b57cec5SDimitry Andric 159*06c3fb27SDimitry Andric #define ASAN_INTERCEPTOR_ENTER(ctx, func) \ 160*06c3fb27SDimitry Andric AsanInterceptorContext _ctx = {#func}; \ 161*06c3fb27SDimitry Andric ctx = (void *)&_ctx; \ 162*06c3fb27SDimitry Andric (void) ctx; 163*06c3fb27SDimitry Andric #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name) 164*06c3fb27SDimitry Andric 1650b57cec5SDimitry Andric #endif // !SANITIZER_FUCHSIA 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric #endif // ASAN_INTERCEPTORS_H 168