master
  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#elif SANITIZER_AIX
 40#  define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
 41#else
 42#  define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
 43#endif  // SANITIZER_APPLE
 44
 45#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
 46#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#endif
 56
 57#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL
 58#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#endif
 70
 71#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL
 72#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#endif
 85
 86#if SANITIZER_INTERCEPT_MEMSET
 87INTERCEPTOR(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#else
 94#define INIT_MEMSET
 95#endif
 96
 97#if SANITIZER_INTERCEPT_MEMMOVE
 98INTERCEPTOR(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#else
105#define INIT_MEMMOVE
106#endif
107
108#if SANITIZER_INTERCEPT_MEMCPY
109INTERCEPTOR(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 same
112  // implementation.  We need to use internal_memmove here.
113  // N.B.: If we switch this to internal_ we'll have to use internal_memmove
114  // due to memcpy being an alias of memmove on OS X.
115  void *ctx;
116#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
117    COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
118#else
119    COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
120#endif
121}
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#else
134#define INIT_MEMCPY
135#endif
136
137#if SANITIZER_INTERCEPT_AEABI_MEM
138INTERCEPTOR(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#else
213#define INIT_AEABI_MEM
214#endif  // SANITIZER_INTERCEPT_AEABI_MEM
215
216#if SANITIZER_INTERCEPT___BZERO
217INTERCEPTOR(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#else
223#define INIT___BZERO
224#endif  // SANITIZER_INTERCEPT___BZERO
225
226#if SANITIZER_INTERCEPT_BZERO
227INTERCEPTOR(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#else
233#define INIT_BZERO
234#endif  // SANITIZER_INTERCEPT_BZERO
235
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 __sanitizer