247 lines · plain
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-exception6//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 so13// that implementations may add them, if necessary, to a separate source file14// 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_ENTER19// COMMON_INTERCEPTOR_READ_RANGE20// COMMON_INTERCEPTOR_WRITE_RANGE21// COMMON_INTERCEPTOR_MEMSET_IMPL22// COMMON_INTERCEPTOR_MEMMOVE_IMPL23// COMMON_INTERCEPTOR_MEMCPY_IMPL24// COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED25//===----------------------------------------------------------------------===//26 27#ifdef SANITIZER_REDEFINE_BUILTINS_H28#error "Define SANITIZER_COMMON_NO_REDEFINE_BUILTINS in .cpp file"29#endif30 31#include "interception/interception.h"32#include "sanitizer_platform_interceptors.h"33 34// Platform-specific options.35#if SANITIZER_APPLE36# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 037#elif SANITIZER_WINDOWS6438# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 039#elif SANITIZER_AIX40# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 041#else42# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 143#endif // SANITIZER_APPLE44 45#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL46#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \47 { \48 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \49 return internal_memset(dst, v, size); \50 COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \51 if (common_flags()->intercept_intrin) \52 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \53 return REAL(memset)(dst, v, size); \54 }55#endif56 57#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL58#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \59 { \60 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \61 return internal_memmove(dst, src, size); \62 COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size); \63 if (common_flags()->intercept_intrin) { \64 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \65 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \66 } \67 return REAL(memmove)(dst, src, size); \68 }69#endif70 71#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL72#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \73 { \74 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \75 return internal_memmove(dst, src, size); \76 } \77 COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size); \78 if (common_flags()->intercept_intrin) { \79 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \80 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \81 } \82 return REAL(memcpy)(dst, src, size); \83 }84#endif85 86#if SANITIZER_INTERCEPT_MEMSET87INTERCEPTOR(void *, memset, void *dst, int v, usize size) {88 void *ctx;89 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size);90}91 92#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)93#else94#define INIT_MEMSET95#endif96 97#if SANITIZER_INTERCEPT_MEMMOVE98INTERCEPTOR(void *, memmove, void *dst, const void *src, usize size) {99 void *ctx;100 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);101}102 103#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)104#else105#define INIT_MEMMOVE106#endif107 108#if SANITIZER_INTERCEPT_MEMCPY109INTERCEPTOR(void *, memcpy, void *dst, const void *src, usize size) {110 // On OS X, calling internal_memcpy here will cause memory corruptions,111 // because memcpy and memmove are actually aliases of the same112 // implementation. We need to use internal_memmove here.113 // N.B.: If we switch this to internal_ we'll have to use internal_memmove114 // due to memcpy being an alias of memmove on OS X.115 void *ctx;116#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE117 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);118#else119 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);120#endif121}122 123#define INIT_MEMCPY \124 do { \125 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \126 COMMON_INTERCEPT_FUNCTION(memcpy); \127 } else { \128 ASSIGN_REAL(memcpy, memmove); \129 } \130 CHECK(REAL(memcpy)); \131 } while (false)132 133#else134#define INIT_MEMCPY135#endif136 137#if SANITIZER_INTERCEPT_AEABI_MEM138INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, usize size) {139 void *ctx;140 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);141}142 143INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, usize size) {144 void *ctx;145 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);146}147 148INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, usize size) {149 void *ctx;150 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);151}152 153INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, usize size) {154 void *ctx;155 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);156}157 158INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, usize size) {159 void *ctx;160 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);161}162 163INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, usize size) {164 void *ctx;165 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);166}167 168// Note the argument order.169INTERCEPTOR(void *, __aeabi_memset, void *block, usize size, int c) {170 void *ctx;171 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);172}173 174INTERCEPTOR(void *, __aeabi_memset4, void *block, usize size, int c) {175 void *ctx;176 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);177}178 179INTERCEPTOR(void *, __aeabi_memset8, void *block, usize size, int c) {180 void *ctx;181 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);182}183 184INTERCEPTOR(void *, __aeabi_memclr, void *block, usize size) {185 void *ctx;186 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);187}188 189INTERCEPTOR(void *, __aeabi_memclr4, void *block, usize size) {190 void *ctx;191 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);192}193 194INTERCEPTOR(void *, __aeabi_memclr8, void *block, usize size) {195 void *ctx;196 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);197}198 199#define INIT_AEABI_MEM \200 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \201 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \202 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \203 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \204 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \205 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \206 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \207 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \208 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \209 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \210 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \211 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);212#else213#define INIT_AEABI_MEM214#endif // SANITIZER_INTERCEPT_AEABI_MEM215 216#if SANITIZER_INTERCEPT___BZERO217INTERCEPTOR(void *, __bzero, void *block, usize size) {218 void *ctx;219 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);220}221#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);222#else223#define INIT___BZERO224#endif // SANITIZER_INTERCEPT___BZERO225 226#if SANITIZER_INTERCEPT_BZERO227INTERCEPTOR(void *, bzero, void *block, usize size) {228 void *ctx;229 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);230}231#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero);232#else233#define INIT_BZERO234#endif // SANITIZER_INTERCEPT_BZERO235 236namespace __sanitizer {237// This does not need to be called if InitializeCommonInterceptors() is called.238void InitializeMemintrinsicInterceptors() {239 INIT_MEMSET;240 INIT_MEMMOVE;241 INIT_MEMCPY;242 INIT_AEABI_MEM;243 INIT___BZERO;244 INIT_BZERO;245}246} // namespace __sanitizer247