xref: /freebsd/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
168d75effSDimitry Andric //===-- asan_interceptors_memintrinsics.cpp -------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===---------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // This file is a part of AddressSanitizer, an address sanity checker.
1068d75effSDimitry Andric //
1168d75effSDimitry Andric // ASan versions of memcpy, memmove, and memset.
1268d75effSDimitry Andric //===---------------------------------------------------------------------===//
1368d75effSDimitry Andric 
1406c3fb27SDimitry Andric #define SANITIZER_COMMON_NO_REDEFINE_BUILTINS
1506c3fb27SDimitry Andric 
1668d75effSDimitry Andric #include "asan_interceptors_memintrinsics.h"
1706c3fb27SDimitry Andric 
1806c3fb27SDimitry Andric #include "asan_interceptors.h"
1968d75effSDimitry Andric #include "asan_report.h"
2068d75effSDimitry Andric #include "asan_stack.h"
2168d75effSDimitry Andric #include "asan_suppressions.h"
2268d75effSDimitry Andric 
2368d75effSDimitry Andric using namespace __asan;
2468d75effSDimitry Andric 
2506c3fb27SDimitry Andric // memcpy is called during __asan_init() from the internals of printf(...).
2606c3fb27SDimitry Andric // We do not treat memcpy with to==from as a bug.
2706c3fb27SDimitry Andric // See http://llvm.org/bugs/show_bug.cgi?id=11763.
2806c3fb27SDimitry Andric #define ASAN_MEMCPY_IMPL(ctx, to, from, size)                 \
2906c3fb27SDimitry Andric   do {                                                        \
3006c3fb27SDimitry Andric     if (LIKELY(replace_intrin_cached)) {                      \
3106c3fb27SDimitry Andric       if (LIKELY(to != from)) {                               \
3206c3fb27SDimitry Andric         CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); \
3306c3fb27SDimitry Andric       }                                                       \
3406c3fb27SDimitry Andric       ASAN_READ_RANGE(ctx, from, size);                       \
3506c3fb27SDimitry Andric       ASAN_WRITE_RANGE(ctx, to, size);                        \
36*5f757f3fSDimitry Andric     } else if (UNLIKELY(!AsanInited())) {                     \
3706c3fb27SDimitry Andric       return internal_memcpy(to, from, size);                 \
3806c3fb27SDimitry Andric     }                                                         \
3906c3fb27SDimitry Andric     return REAL(memcpy)(to, from, size);                      \
4006c3fb27SDimitry Andric   } while (0)
4106c3fb27SDimitry Andric 
4206c3fb27SDimitry Andric // memset is called inside Printf.
4306c3fb27SDimitry Andric #define ASAN_MEMSET_IMPL(ctx, block, c, size) \
4406c3fb27SDimitry Andric   do {                                        \
4506c3fb27SDimitry Andric     if (LIKELY(replace_intrin_cached)) {      \
4606c3fb27SDimitry Andric       ASAN_WRITE_RANGE(ctx, block, size);     \
47*5f757f3fSDimitry Andric     } else if (UNLIKELY(!AsanInited())) {     \
4806c3fb27SDimitry Andric       return internal_memset(block, c, size); \
4906c3fb27SDimitry Andric     }                                         \
5006c3fb27SDimitry Andric     return REAL(memset)(block, c, size);      \
5106c3fb27SDimitry Andric   } while (0)
5206c3fb27SDimitry Andric 
5306c3fb27SDimitry Andric #define ASAN_MEMMOVE_IMPL(ctx, to, from, size) \
5406c3fb27SDimitry Andric   do {                                         \
5506c3fb27SDimitry Andric     if (LIKELY(replace_intrin_cached)) {       \
5606c3fb27SDimitry Andric       ASAN_READ_RANGE(ctx, from, size);        \
5706c3fb27SDimitry Andric       ASAN_WRITE_RANGE(ctx, to, size);         \
5806c3fb27SDimitry Andric     }                                          \
5906c3fb27SDimitry Andric     return internal_memmove(to, from, size);   \
6006c3fb27SDimitry Andric   } while (0)
6106c3fb27SDimitry Andric 
6268d75effSDimitry Andric void *__asan_memcpy(void *to, const void *from, uptr size) {
6368d75effSDimitry Andric   ASAN_MEMCPY_IMPL(nullptr, to, from, size);
6468d75effSDimitry Andric }
6568d75effSDimitry Andric 
6668d75effSDimitry Andric void *__asan_memset(void *block, int c, uptr size) {
6768d75effSDimitry Andric   ASAN_MEMSET_IMPL(nullptr, block, c, size);
6868d75effSDimitry Andric }
6968d75effSDimitry Andric 
7068d75effSDimitry Andric void *__asan_memmove(void *to, const void *from, uptr size) {
7168d75effSDimitry Andric   ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
7268d75effSDimitry Andric }
7368d75effSDimitry Andric 
74fe6060f1SDimitry Andric #if SANITIZER_FUCHSIA
7568d75effSDimitry Andric 
76fe6060f1SDimitry Andric // Fuchsia doesn't use sanitizer_common_interceptors.inc, but
7768d75effSDimitry Andric // the only things there it wants are these three.  Just define them
7868d75effSDimitry Andric // as aliases here rather than repeating the contents.
7968d75effSDimitry Andric 
8068d75effSDimitry Andric extern "C" decltype(__asan_memcpy) memcpy[[gnu::alias("__asan_memcpy")]];
8168d75effSDimitry Andric extern "C" decltype(__asan_memmove) memmove[[gnu::alias("__asan_memmove")]];
8268d75effSDimitry Andric extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];
8368d75effSDimitry Andric 
8406c3fb27SDimitry Andric #else  // SANITIZER_FUCHSIA
8506c3fb27SDimitry Andric 
8606c3fb27SDimitry Andric #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
8706c3fb27SDimitry Andric   do {                                                       \
8806c3fb27SDimitry Andric     ASAN_INTERCEPTOR_ENTER(ctx, memmove);                    \
8906c3fb27SDimitry Andric     ASAN_MEMMOVE_IMPL(ctx, to, from, size);                  \
9006c3fb27SDimitry Andric   } while (false)
9106c3fb27SDimitry Andric 
9206c3fb27SDimitry Andric #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
9306c3fb27SDimitry Andric   do {                                                      \
9406c3fb27SDimitry Andric     ASAN_INTERCEPTOR_ENTER(ctx, memcpy);                    \
9506c3fb27SDimitry Andric     ASAN_MEMCPY_IMPL(ctx, to, from, size);                  \
9606c3fb27SDimitry Andric   } while (false)
9706c3fb27SDimitry Andric 
9806c3fb27SDimitry Andric #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
9906c3fb27SDimitry Andric   do {                                                      \
10006c3fb27SDimitry Andric     ASAN_INTERCEPTOR_ENTER(ctx, memset);                    \
10106c3fb27SDimitry Andric     ASAN_MEMSET_IMPL(ctx, block, c, size);                  \
10206c3fb27SDimitry Andric   } while (false)
10306c3fb27SDimitry Andric 
10406c3fb27SDimitry Andric #include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"
10506c3fb27SDimitry Andric 
106fe6060f1SDimitry Andric #endif  // SANITIZER_FUCHSIA
107