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
__asan_memcpy(void * to,const void * from,uptr size)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
__asan_memset(void * block,int c,uptr size)6668d75effSDimitry Andric void *__asan_memset(void *block, int c, uptr size) {
6768d75effSDimitry Andric ASAN_MEMSET_IMPL(nullptr, block, c, size);
6868d75effSDimitry Andric }
6968d75effSDimitry Andric
__asan_memmove(void * to,const void * from,uptr size)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