1 //===-- sanitizer_common_interceptors_memintrinsics.inc ---------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Memintrinsic function interceptors for tools like AddressSanitizer,
10 // ThreadSanitizer, MemorySanitizer, etc.
12 // These interceptors are part of the common interceptors, but separated out so
13 // that implementations may add them, if necessary, to a separate source file
14 // that should define SANITIZER_COMMON_NO_REDEFINE_BUILTINS at the top.
16 // This file should be included into the tool's memintrinsic interceptor file,
17 // which has to define its own macros:
18 // COMMON_INTERCEPTOR_ENTER
19 // COMMON_INTERCEPTOR_READ_RANGE
20 // COMMON_INTERCEPTOR_WRITE_RANGE
21 // COMMON_INTERCEPTOR_MEMSET_IMPL
22 // COMMON_INTERCEPTOR_MEMMOVE_IMPL
23 // COMMON_INTERCEPTOR_MEMCPY_IMPL
24 // COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
25 //===----------------------------------------------------------------------===//
27 #ifdef SANITIZER_REDEFINE_BUILTINS_H
28 #error "Define SANITIZER_COMMON_NO_REDEFINE_BUILTINS in .cpp file"
31 #include "interception/interception.h"
32 #include "sanitizer_platform_interceptors.h"
34 // Platform-specific options.
36 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
37 #elif SANITIZER_WINDOWS64
38 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
40 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
41 #endif // SANITIZER_APPLE
43 #ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
44 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
46 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \
47 return internal_memset(dst, v, size); \
48 COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \
49 if (common_flags()->intercept_intrin) \
50 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
51 return REAL(memset)(dst, v, size); \
55 #ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL
56 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \
58 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \
59 return internal_memmove(dst, src, size); \
60 COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size); \
61 if (common_flags()->intercept_intrin) { \
62 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
63 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \
65 return REAL(memmove)(dst, src, size); \
69 #ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL
70 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \
72 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \
73 return internal_memmove(dst, src, size); \
75 COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size); \
76 if (common_flags()->intercept_intrin) { \
77 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
78 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \
80 return REAL(memcpy)(dst, src, size); \
84 #if SANITIZER_INTERCEPT_MEMSET
85 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
87 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size);
90 #define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
95 #if SANITIZER_INTERCEPT_MEMMOVE
96 INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {
98 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
101 #define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
106 #if SANITIZER_INTERCEPT_MEMCPY
107 INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
108 // On OS X, calling internal_memcpy here will cause memory corruptions,
109 // because memcpy and memmove are actually aliases of the same
110 // implementation. We need to use internal_memmove here.
111 // N.B.: If we switch this to internal_ we'll have to use internal_memmove
112 // due to memcpy being an alias of memmove on OS X.
114 #if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
115 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
117 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
121 #define INIT_MEMCPY \
123 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \
124 COMMON_INTERCEPT_FUNCTION(memcpy); \
126 ASSIGN_REAL(memcpy, memmove); \
128 CHECK(REAL(memcpy)); \
135 #if SANITIZER_INTERCEPT_AEABI_MEM
136 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
138 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
141 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
143 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
146 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
148 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
151 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
153 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
156 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
158 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
161 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
163 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
166 // Note the argument order.
167 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
169 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
172 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
174 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
177 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
179 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
182 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
184 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
187 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
189 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
192 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
194 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
197 #define INIT_AEABI_MEM \
198 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \
199 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
200 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
201 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \
202 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \
203 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \
204 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \
205 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \
206 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \
207 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \
208 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \
209 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
211 #define INIT_AEABI_MEM
212 #endif // SANITIZER_INTERCEPT_AEABI_MEM
214 #if SANITIZER_INTERCEPT___BZERO
215 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
217 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
219 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
222 #endif // SANITIZER_INTERCEPT___BZERO
224 #if SANITIZER_INTERCEPT_BZERO
225 INTERCEPTOR(void *, bzero, void *block, uptr size) {
227 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
229 #define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero);
232 #endif // SANITIZER_INTERCEPT_BZERO
234 namespace __sanitizer {
235 // This does not need to be called if InitializeCommonInterceptors() is called.
236 void InitializeMemintrinsicInterceptors() {
244 } // namespace __sanitizer