1//===-- sanitizer_common_interceptors_memintrinsics.inc ---------*- 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// Memintrinsic function interceptors for tools like AddressSanitizer, 10// ThreadSanitizer, MemorySanitizer, etc. 11// 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. 15// 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//===----------------------------------------------------------------------===// 26 27#ifdef SANITIZER_REDEFINE_BUILTINS_H 28#error "Define SANITIZER_COMMON_NO_REDEFINE_BUILTINS in .cpp file" 29#endif 30 31#include "interception/interception.h" 32#include "sanitizer_platform_interceptors.h" 33 34// Platform-specific options. 35#if SANITIZER_APPLE 36#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 37#elif SANITIZER_WINDOWS64 38#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 39#else 40#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1 41#endif // SANITIZER_APPLE 42 43#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL 44#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \ 45 { \ 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); \ 52 } 53#endif 54 55#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL 56#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \ 57 { \ 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); \ 64 } \ 65 return REAL(memmove)(dst, src, size); \ 66 } 67#endif 68 69#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL 70#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \ 71 { \ 72 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \ 73 return internal_memmove(dst, src, size); \ 74 } \ 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); \ 79 } \ 80 return REAL(memcpy)(dst, src, size); \ 81 } 82#endif 83 84#if SANITIZER_INTERCEPT_MEMSET 85INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { 86 void *ctx; 87 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size); 88} 89 90#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset) 91#else 92#define INIT_MEMSET 93#endif 94 95#if SANITIZER_INTERCEPT_MEMMOVE 96INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { 97 void *ctx; 98 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 99} 100 101#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove) 102#else 103#define INIT_MEMMOVE 104#endif 105 106#if SANITIZER_INTERCEPT_MEMCPY 107INTERCEPTOR(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. 113 void *ctx; 114#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 115 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size); 116#else 117 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 118#endif 119} 120 121#define INIT_MEMCPY \ 122 do { \ 123 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ 124 COMMON_INTERCEPT_FUNCTION(memcpy); \ 125 } else { \ 126 ASSIGN_REAL(memcpy, memmove); \ 127 } \ 128 CHECK(REAL(memcpy)); \ 129 } while (false) 130 131#else 132#define INIT_MEMCPY 133#endif 134 135#if SANITIZER_INTERCEPT_AEABI_MEM 136INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) { 137 void *ctx; 138 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 139} 140 141INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) { 142 void *ctx; 143 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 144} 145 146INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) { 147 void *ctx; 148 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 149} 150 151INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) { 152 void *ctx; 153 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 154} 155 156INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) { 157 void *ctx; 158 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 159} 160 161INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) { 162 void *ctx; 163 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 164} 165 166// Note the argument order. 167INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) { 168 void *ctx; 169 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 170} 171 172INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) { 173 void *ctx; 174 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 175} 176 177INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) { 178 void *ctx; 179 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 180} 181 182INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) { 183 void *ctx; 184 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 185} 186 187INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) { 188 void *ctx; 189 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 190} 191 192INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { 193 void *ctx; 194 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 195} 196 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); 210#else 211#define INIT_AEABI_MEM 212#endif // SANITIZER_INTERCEPT_AEABI_MEM 213 214#if SANITIZER_INTERCEPT___BZERO 215INTERCEPTOR(void *, __bzero, void *block, uptr size) { 216 void *ctx; 217 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 218} 219#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero); 220#else 221#define INIT___BZERO 222#endif // SANITIZER_INTERCEPT___BZERO 223 224#if SANITIZER_INTERCEPT_BZERO 225INTERCEPTOR(void *, bzero, void *block, uptr size) { 226 void *ctx; 227 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 228} 229#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero); 230#else 231#define INIT_BZERO 232#endif // SANITIZER_INTERCEPT_BZERO 233 234namespace __sanitizer { 235// This does not need to be called if InitializeCommonInterceptors() is called. 236void InitializeMemintrinsicInterceptors() { 237 INIT_MEMSET; 238 INIT_MEMMOVE; 239 INIT_MEMCPY; 240 INIT_AEABI_MEM; 241 INIT___BZERO; 242 INIT_BZERO; 243} 244} // namespace __sanitizer 245