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