Skip to content

Commit

Permalink
[compiler-rt] Refactor memintrinsic interceptors
Browse files Browse the repository at this point in the history
This moves memintrinsic interceptors (memcpy/memmove/memset) into a new
file sanitizer_common_interceptors_memintrinsics.inc.

This is in preparation of redefining builtins, however, we must be
careful to not redefine builtins in TUs that define interceptors of the
same name.

In all cases except for MSan, memintrinsic interceptors were moved to a
new TU $tool_interceptors_memintrinsics.cpp. In the case of MSan, it
turns out this is not yet necessary (as shown by the later patch
introducing memcpy tests).

NFC.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D151552
  • Loading branch information
melver committed May 30, 2023
1 parent 3ccb770 commit c551c9c
Show file tree
Hide file tree
Showing 19 changed files with 451 additions and 376 deletions.
24 changes: 0 additions & 24 deletions compiler-rt/lib/asan/asan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,6 @@ using namespace __asan;
DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)

#define ASAN_INTERCEPTOR_ENTER(ctx, func) \
AsanInterceptorContext _ctx = {#func}; \
ctx = (void *)&_ctx; \
(void) ctx; \

#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
ASAN_INTERCEPT_FUNC_VER(name, ver)
#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \
Expand Down Expand Up @@ -152,24 +146,6 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
*begin = *end = 0; \
}

#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
ASAN_INTERCEPTOR_ENTER(ctx, memmove); \
ASAN_MEMMOVE_IMPL(ctx, to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
do { \
ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \
ASAN_MEMCPY_IMPL(ctx, to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
do { \
ASAN_INTERCEPTOR_ENTER(ctx, memset); \
ASAN_MEMSET_IMPL(ctx, block, c, size); \
} while (false)

#if CAN_SANITIZE_LEAKS
#define COMMON_INTERCEPTOR_STRERROR() \
__lsan::ScopedInterceptorDisabler disabler
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/asan/asan_interceptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,10 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2)

#endif // !SANITIZER_FUCHSIA

#define ASAN_INTERCEPTOR_ENTER(ctx, func) \
AsanInterceptorContext _ctx = {#func}; \
ctx = (void *)&_ctx; \
(void) ctx;
#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)

#endif // ASAN_INTERCEPTORS_H
59 changes: 59 additions & 0 deletions compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,71 @@
//===---------------------------------------------------------------------===//

#include "asan_interceptors_memintrinsics.h"

#include "asan_interceptors.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_suppressions.h"

using namespace __asan;

// memcpy is called during __asan_init() from the internals of printf(...).
// We do not treat memcpy with to==from as a bug.
// See http://llvm.org/bugs/show_bug.cgi?id=11763.
#define ASAN_MEMCPY_IMPL(ctx, to, from, size) \
do { \
if (LIKELY(replace_intrin_cached)) { \
if (LIKELY(to != from)) { \
CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); \
} \
ASAN_READ_RANGE(ctx, from, size); \
ASAN_WRITE_RANGE(ctx, to, size); \
} else if (UNLIKELY(!asan_inited)) { \
return internal_memcpy(to, from, size); \
} \
return REAL(memcpy)(to, from, size); \
} while (0)

// memset is called inside Printf.
#define ASAN_MEMSET_IMPL(ctx, block, c, size) \
do { \
if (LIKELY(replace_intrin_cached)) { \
ASAN_WRITE_RANGE(ctx, block, size); \
} else if (UNLIKELY(!asan_inited)) { \
return internal_memset(block, c, size); \
} \
return REAL(memset)(block, c, size); \
} while (0)

#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
if (LIKELY(replace_intrin_cached)) { \
ASAN_READ_RANGE(ctx, from, size); \
ASAN_WRITE_RANGE(ctx, to, size); \
} \
return internal_memmove(to, from, size); \
} while (0)

#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
ASAN_INTERCEPTOR_ENTER(ctx, memmove); \
ASAN_MEMMOVE_IMPL(ctx, to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
do { \
ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \
ASAN_MEMCPY_IMPL(ctx, to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
do { \
ASAN_INTERCEPTOR_ENTER(ctx, memset); \
ASAN_MEMSET_IMPL(ctx, block, c, size); \
} while (false)

#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"

void *__asan_memcpy(void *to, const void *from, uptr size) {
ASAN_MEMCPY_IMPL(nullptr, to, from, size);
}
Expand Down
37 changes: 0 additions & 37 deletions compiler-rt/lib/asan/asan_interceptors_memintrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,43 +79,6 @@ struct AsanInterceptorContext {
} \
} while (0)

// memcpy is called during __asan_init() from the internals of printf(...).
// We do not treat memcpy with to==from as a bug.
// See http://llvm.org/bugs/show_bug.cgi?id=11763.
#define ASAN_MEMCPY_IMPL(ctx, to, from, size) \
do { \
if (LIKELY(replace_intrin_cached)) { \
if (LIKELY(to != from)) { \
CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); \
} \
ASAN_READ_RANGE(ctx, from, size); \
ASAN_WRITE_RANGE(ctx, to, size); \
} else if (UNLIKELY(!asan_inited)) { \
return internal_memcpy(to, from, size); \
} \
return REAL(memcpy)(to, from, size); \
} while (0)

// memset is called inside Printf.
#define ASAN_MEMSET_IMPL(ctx, block, c, size) \
do { \
if (LIKELY(replace_intrin_cached)) { \
ASAN_WRITE_RANGE(ctx, block, size); \
} else if (UNLIKELY(!asan_inited)) { \
return internal_memset(block, c, size); \
} \
return REAL(memset)(block, c, size); \
} while (0)

#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
if (LIKELY(replace_intrin_cached)) { \
ASAN_READ_RANGE(ctx, from, size); \
ASAN_WRITE_RANGE(ctx, to, size); \
} \
return internal_memmove(to, from, size); \
} while (0)

#define ASAN_READ_RANGE(ctx, offset, size) \
ACCESS_MEMORY_RANGE(ctx, offset, size, false)
#define ASAN_WRITE_RANGE(ctx, offset, size) \
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/hwasan/hwasan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \
} while (false)

# include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"
# include "sanitizer_common/sanitizer_common_interceptors.inc"

struct ThreadStartArg {
Expand Down
23 changes: 0 additions & 23 deletions compiler-rt/lib/memprof/memprof_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ using namespace __memprof;
DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)

#define MEMPROF_INTERCEPTOR_ENTER(ctx, func) \
ctx = 0; \
(void)ctx;

#define COMMON_INTERCEPT_FUNCTION(name) MEMPROF_INTERCEPT_FUNC(name)
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
MEMPROF_INTERCEPT_FUNC_VER(name, ver)
#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \
Expand Down Expand Up @@ -105,24 +100,6 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
*begin = *end = 0; \
}

#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
MEMPROF_INTERCEPTOR_ENTER(ctx, memmove); \
MEMPROF_MEMMOVE_IMPL(to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
do { \
MEMPROF_INTERCEPTOR_ENTER(ctx, memcpy); \
MEMPROF_MEMCPY_IMPL(to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
do { \
MEMPROF_INTERCEPTOR_ENTER(ctx, memset); \
MEMPROF_MEMSET_IMPL(block, c, size); \
} while (false)

#include "sanitizer_common/sanitizer_common_interceptors.inc"

#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) MEMPROF_READ_RANGE(p, s)
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/memprof/memprof_interceptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,10 @@ DECLARE_REAL(char *, strstr, const char *s1, const char *s2)
ver, #name); \
} while (0)

#define MEMPROF_INTERCEPTOR_ENTER(ctx, func) \
ctx = 0; \
(void)ctx;

#define COMMON_INTERCEPT_FUNCTION(name) MEMPROF_INTERCEPT_FUNC(name)

#endif // MEMPROF_INTERCEPTORS_H
61 changes: 61 additions & 0 deletions compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,71 @@
//===---------------------------------------------------------------------===//

#include "memprof_interceptors_memintrinsics.h"

#include "memprof_interceptors.h"
#include "memprof_stack.h"

using namespace __memprof;

// memcpy is called during __memprof_init() from the internals of printf(...).
// We do not treat memcpy with to==from as a bug.
// See http://llvm.org/bugs/show_bug.cgi?id=11763.
#define MEMPROF_MEMCPY_IMPL(to, from, size) \
do { \
if (UNLIKELY(!memprof_inited)) \
return internal_memcpy(to, from, size); \
if (memprof_init_is_running) { \
return REAL(memcpy)(to, from, size); \
} \
ENSURE_MEMPROF_INITED(); \
MEMPROF_READ_RANGE(from, size); \
MEMPROF_WRITE_RANGE(to, size); \
return REAL(memcpy)(to, from, size); \
} while (0)

// memset is called inside Printf.
#define MEMPROF_MEMSET_IMPL(block, c, size) \
do { \
if (UNLIKELY(!memprof_inited)) \
return internal_memset(block, c, size); \
if (memprof_init_is_running) { \
return REAL(memset)(block, c, size); \
} \
ENSURE_MEMPROF_INITED(); \
MEMPROF_WRITE_RANGE(block, size); \
return REAL(memset)(block, c, size); \
} while (0)

#define MEMPROF_MEMMOVE_IMPL(to, from, size) \
do { \
if (UNLIKELY(!memprof_inited)) \
return internal_memmove(to, from, size); \
ENSURE_MEMPROF_INITED(); \
MEMPROF_READ_RANGE(from, size); \
MEMPROF_WRITE_RANGE(to, size); \
return internal_memmove(to, from, size); \
} while (0)

#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
MEMPROF_INTERCEPTOR_ENTER(ctx, memmove); \
MEMPROF_MEMMOVE_IMPL(to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
do { \
MEMPROF_INTERCEPTOR_ENTER(ctx, memcpy); \
MEMPROF_MEMCPY_IMPL(to, from, size); \
} while (false)

#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
do { \
MEMPROF_INTERCEPTOR_ENTER(ctx, memset); \
MEMPROF_MEMSET_IMPL(block, c, size); \
} while (false)

#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"

void *__memprof_memcpy(void *to, const void *from, uptr size) {
MEMPROF_MEMCPY_IMPL(to, from, size);
}
Expand Down
39 changes: 0 additions & 39 deletions compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,45 +32,6 @@ namespace __memprof {
__memprof_record_access_range(offset, size); \
} while (0)

// memcpy is called during __memprof_init() from the internals of printf(...).
// We do not treat memcpy with to==from as a bug.
// See http://llvm.org/bugs/show_bug.cgi?id=11763.
#define MEMPROF_MEMCPY_IMPL(to, from, size) \
do { \
if (UNLIKELY(!memprof_inited)) \
return internal_memcpy(to, from, size); \
if (memprof_init_is_running) { \
return REAL(memcpy)(to, from, size); \
} \
ENSURE_MEMPROF_INITED(); \
MEMPROF_READ_RANGE(from, size); \
MEMPROF_WRITE_RANGE(to, size); \
return REAL(memcpy)(to, from, size); \
} while (0)

// memset is called inside Printf.
#define MEMPROF_MEMSET_IMPL(block, c, size) \
do { \
if (UNLIKELY(!memprof_inited)) \
return internal_memset(block, c, size); \
if (memprof_init_is_running) { \
return REAL(memset)(block, c, size); \
} \
ENSURE_MEMPROF_INITED(); \
MEMPROF_WRITE_RANGE(block, size); \
return REAL(memset)(block, c, size); \
} while (0)

#define MEMPROF_MEMMOVE_IMPL(to, from, size) \
do { \
if (UNLIKELY(!memprof_inited)) \
return internal_memmove(to, from, size); \
ENSURE_MEMPROF_INITED(); \
MEMPROF_READ_RANGE(from, size); \
MEMPROF_WRITE_RANGE(to, size); \
return internal_memmove(to, from, size); \
} while (0)

#define MEMPROF_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size)
#define MEMPROF_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size)

Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/msan/msan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,7 @@ int OnExit() {
} while (false)

#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"
#include "sanitizer_common/sanitizer_common_interceptors.inc"

static uptr signal_impl(int signo, uptr cb);
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/sanitizer_common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ set(SANITIZER_IMPL_HEADERS
sanitizer_common_interceptors.inc
sanitizer_common_interceptors_format.inc
sanitizer_common_interceptors_ioctl.inc
sanitizer_common_interceptors_memintrinsics.inc
sanitizer_common_interface.inc
sanitizer_common_interface_posix.inc
sanitizer_common_syscalls.inc
Expand Down
Loading

0 comments on commit c551c9c

Please sign in to comment.