xref: /freebsd/contrib/llvm-project/compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- memprof_interceptors_memintrinsics.cpp ---------------------------===//
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 // This file is a part of MemProfiler, a memory profiler.
10 //
11 // MemProf versions of memcpy, memmove, and memset.
12 //===---------------------------------------------------------------------===//
13 
14 #define SANITIZER_COMMON_NO_REDEFINE_BUILTINS
15 
16 #include "memprof_interceptors_memintrinsics.h"
17 
18 #include "memprof_interceptors.h"
19 #include "memprof_stack.h"
20 
21 using namespace __memprof;
22 
23 // memcpy is called during __memprof_init() from the internals of printf(...).
24 // We do not treat memcpy with to==from as a bug.
25 // See http://llvm.org/bugs/show_bug.cgi?id=11763.
26 #define MEMPROF_MEMCPY_IMPL(to, from, size)                                    \
27   do {                                                                         \
28     if (UNLIKELY(!memprof_inited))                                             \
29       return internal_memcpy(to, from, size);                                  \
30     if (memprof_init_is_running) {                                             \
31       return REAL(memcpy)(to, from, size);                                     \
32     }                                                                          \
33     ENSURE_MEMPROF_INITED();                                                   \
34     MEMPROF_READ_RANGE(from, size);                                            \
35     MEMPROF_WRITE_RANGE(to, size);                                             \
36     return REAL(memcpy)(to, from, size);                                       \
37   } while (0)
38 
39 // memset is called inside Printf.
40 #define MEMPROF_MEMSET_IMPL(block, c, size)                                    \
41   do {                                                                         \
42     if (UNLIKELY(!memprof_inited))                                             \
43       return internal_memset(block, c, size);                                  \
44     if (memprof_init_is_running) {                                             \
45       return REAL(memset)(block, c, size);                                     \
46     }                                                                          \
47     ENSURE_MEMPROF_INITED();                                                   \
48     MEMPROF_WRITE_RANGE(block, size);                                          \
49     return REAL(memset)(block, c, size);                                       \
50   } while (0)
51 
52 #define MEMPROF_MEMMOVE_IMPL(to, from, size)                                   \
53   do {                                                                         \
54     if (UNLIKELY(!memprof_inited))                                             \
55       return internal_memmove(to, from, size);                                 \
56     ENSURE_MEMPROF_INITED();                                                   \
57     MEMPROF_READ_RANGE(from, size);                                            \
58     MEMPROF_WRITE_RANGE(to, size);                                             \
59     return internal_memmove(to, from, size);                                   \
60   } while (0)
61 
62 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size)                   \
63   do {                                                                         \
64     MEMPROF_INTERCEPTOR_ENTER(ctx, memmove);                                   \
65     MEMPROF_MEMMOVE_IMPL(to, from, size);                                      \
66   } while (false)
67 
68 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size)                    \
69   do {                                                                         \
70     MEMPROF_INTERCEPTOR_ENTER(ctx, memcpy);                                    \
71     MEMPROF_MEMCPY_IMPL(to, from, size);                                       \
72   } while (false)
73 
74 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size)                    \
75   do {                                                                         \
76     MEMPROF_INTERCEPTOR_ENTER(ctx, memset);                                    \
77     MEMPROF_MEMSET_IMPL(block, c, size);                                       \
78   } while (false)
79 
80 #include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"
81 
82 void *__memprof_memcpy(void *to, const void *from, uptr size) {
83   MEMPROF_MEMCPY_IMPL(to, from, size);
84 }
85 
86 void *__memprof_memset(void *block, int c, uptr size) {
87   MEMPROF_MEMSET_IMPL(block, c, size);
88 }
89 
90 void *__memprof_memmove(void *to, const void *from, uptr size) {
91   MEMPROF_MEMMOVE_IMPL(to, from, size);
92 }
93