1//===-- asan_interceptors.h -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of AddressSanitizer, an address sanity checker.
10//
11// ASan-private header for asan_interceptors.cpp
12//===----------------------------------------------------------------------===//
13#ifndef ASAN_INTERCEPTORS_H
14#define ASAN_INTERCEPTORS_H
15
16#include "asan_interceptors_memintrinsics.h"
17#include "asan_internal.h"
18#include "interception/interception.h"
19#include "sanitizer_common/sanitizer_platform.h"
20#include "sanitizer_common/sanitizer_platform_interceptors.h"
21
22namespace __asan {
23
24void InitializeAsanInterceptors();
25void InitializePlatformInterceptors();
26
27} // namespace __asan
28
29// There is no general interception at all on Fuchsia.
30// Only the functions in asan_interceptors_memintrinsics.h are
31// really defined to replace libc functions.
32#if !SANITIZER_FUCHSIA
33
34// Use macro to describe if specific function should be
35// intercepted on a given platform.
36#if !SANITIZER_WINDOWS
37# define ASAN_INTERCEPT__LONGJMP 1
38# define ASAN_INTERCEPT_INDEX 1
39# define ASAN_INTERCEPT_PTHREAD_CREATE 1
40#else
41# define ASAN_INTERCEPT__LONGJMP 0
42# define ASAN_INTERCEPT_INDEX 0
43# define ASAN_INTERCEPT_PTHREAD_CREATE 0
44#endif
45
46#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
47 SANITIZER_SOLARIS
48# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1
49#else
50# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0
51#endif
52
53#if SANITIZER_GLIBC || SANITIZER_SOLARIS
54# define ASAN_INTERCEPT_SWAPCONTEXT 1
55#else
56# define ASAN_INTERCEPT_SWAPCONTEXT 0
57#endif
58
59#if !SANITIZER_WINDOWS
60# define ASAN_INTERCEPT_SIGLONGJMP 1
61#else
62# define ASAN_INTERCEPT_SIGLONGJMP 0
63#endif
64
65#if SANITIZER_GLIBC
66# define ASAN_INTERCEPT___LONGJMP_CHK 1
67#else
68# define ASAN_INTERCEPT___LONGJMP_CHK 0
69#endif
70
71#if ASAN_HAS_EXCEPTIONS && !SANITIZER_SOLARIS && !SANITIZER_NETBSD && \
72 (!SANITIZER_WINDOWS || (defined(__MINGW32__) && defined(__i386__)))
73# define ASAN_INTERCEPT___CXA_THROW 1
74# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
75# if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
76# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
77# else
78# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 1
79# endif
80#else
81# define ASAN_INTERCEPT___CXA_THROW 0
82# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
83# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 0
84# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0
85#endif
86
87#if !SANITIZER_WINDOWS
88# define ASAN_INTERCEPT___CXA_ATEXIT 1
89#else
90# define ASAN_INTERCEPT___CXA_ATEXIT 0
91#endif
92
93#if SANITIZER_NETBSD
94# define ASAN_INTERCEPT_ATEXIT 1
95#else
96# define ASAN_INTERCEPT_ATEXIT 0
97#endif
98
99#if SANITIZER_GLIBC
100# define ASAN_INTERCEPT___STRDUP 1
101#else
102# define ASAN_INTERCEPT___STRDUP 0
103#endif
104
105#if SANITIZER_GLIBC && ASAN_INTERCEPT_PTHREAD_CREATE
106# define ASAN_INTERCEPT_TIMEDJOIN 1
107# define ASAN_INTERCEPT_TRYJOIN 1
108#else
109# define ASAN_INTERCEPT_TIMEDJOIN 0
110# define ASAN_INTERCEPT_TRYJOIN 0
111#endif
112
113#if SANITIZER_LINUX && \
114 (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \
115 defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64)
116# define ASAN_INTERCEPT_VFORK 1
117#else
118# define ASAN_INTERCEPT_VFORK 0
119#endif
120
121#if SANITIZER_NETBSD
122# define ASAN_INTERCEPT_PTHREAD_ATFORK 1
123#else
124# define ASAN_INTERCEPT_PTHREAD_ATFORK 0
125#endif
126
127DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)
128DECLARE_REAL(char*, strchr, const char *str, int c)
129DECLARE_REAL(SIZE_T, strlen, const char *s)
130DECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size)
131DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen)
132DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
133
134# if !SANITIZER_APPLE
135# define ASAN_INTERCEPT_FUNC(name) \
136 do { \
137 if (!INTERCEPT_FUNCTION(name)) \
138 VReport(1, "AddressSanitizer: failed to intercept '%s'\n", #name); \
139 } while (0)
140# define ASAN_INTERCEPT_FUNC_VER(name, ver) \
141 do { \
142 if (!INTERCEPT_FUNCTION_VER(name, ver)) \
143 VReport(1, "AddressSanitizer: failed to intercept '%s@@%s'\n", \
144 #name, ver); \
145 } while (0)
146# define ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \
147 do { \
148 if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \
149 VReport(1, \
150 "AddressSanitizer: failed to intercept '%s@@%s' or '%s'\n", \
151 #name, ver, #name); \
152 } while (0)
153
154# else
155// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
156# define ASAN_INTERCEPT_FUNC(name)
157# endif // SANITIZER_APPLE
158
159#define ASAN_INTERCEPTOR_ENTER(ctx, func) \
160 AsanInterceptorContext _ctx = {#func}; \
161 ctx = (void *)&_ctx; \
162 (void) ctx;
163#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
164
165#endif // !SANITIZER_FUCHSIA
166
167#endif // ASAN_INTERCEPTORS_H
168