From 77654a65a373da9c4829de821e7b393ea811ee40 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Sat, 3 Sep 2022 22:24:33 -0700 Subject: [PATCH] [tsan] Replace mem intrinsics with calls to interceptors After https://reviews.llvm.org/rG463aa814182a23 tsan replaces llvm intrinsics with calls to glibc functions. However this approach is fragile, as slight changes in pipeline can return llvm intrinsics back. In particular InstCombine can do that. Msan/Asan already declare own version of these memory functions for the similar purpose. KCSAN, or anything that uses something else than compiler-rt, needs to implement this callbacks. Reviewed By: melver Differential Revision: https://reviews.llvm.org/D133268 --- compiler-rt/lib/tsan/rtl/tsan.syms.extra | 3 +++ compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 14 ++++++++++++++ compiler-rt/lib/tsan/rtl/tsan_interface.h | 7 +++++++ llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 6 +++--- llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll | 10 +++++----- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan.syms.extra b/compiler-rt/lib/tsan/rtl/tsan.syms.extra index 4838bb0..a5bd171 100644 --- a/compiler-rt/lib/tsan/rtl/tsan.syms.extra +++ b/compiler-rt/lib/tsan/rtl/tsan.syms.extra @@ -9,6 +9,9 @@ __tsan_java* __tsan_unaligned* __tsan_release __tsan_acquire +__tsan_memcpy +__tsan_memmove +__tsan_memset __tsan_mutex_create __tsan_mutex_destroy __tsan_mutex_pre_lock diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 17f6b1f..1f90679 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -3059,3 +3059,17 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __tsan_testonly_barrier_wait( FutexWait(barrier, cur); } } + +extern "C" { +__attribute__((alias(SANITIZER_STRINGIFY(WRAP(memcpy))), + visibility("default"))) void * +__tsan_memcpy(void *dst, const void *src, uptr size); + +__attribute__((alias(SANITIZER_STRINGIFY(WRAP(memset))), + visibility("default"))) void * +__tsan_memset(void *dst, int c, uptr size); + +__attribute__((alias(SANITIZER_STRINGIFY(WRAP(memmove))), + visibility("default"))) void * +__tsan_memmove(void *dst, const void *src, uptr size); +} diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface.h b/compiler-rt/lib/tsan/rtl/tsan_interface.h index 711f064..5b9d664 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interface.h @@ -72,6 +72,13 @@ SANITIZER_INTERFACE_ATTRIBUTE void __tsan_vptr_read(void **vptr_p); SANITIZER_INTERFACE_ATTRIBUTE void __tsan_vptr_update(void **vptr_p, void *new_val); +SANITIZER_INTERFACE_ATTRIBUTE +void *__tsan_memcpy(void *dest, const void *src, uptr count); +SANITIZER_INTERFACE_ATTRIBUTE +void *__tsan_memset(void *dest, int ch, uptr count); +SANITIZER_INTERFACE_ATTRIBUTE +void *__tsan_memmove(void *dest, const void *src, uptr count); + SANITIZER_INTERFACE_ATTRIBUTE void __tsan_func_entry(void *call_pc); SANITIZER_INTERFACE_ATTRIBUTE void __tsan_func_exit(); diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 863b085..0cda196 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -341,13 +341,13 @@ void ThreadSanitizer::initialize(Module &M) { } MemmoveFn = - M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(), + M.getOrInsertFunction("__tsan_memmove", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy); MemcpyFn = - M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(), + M.getOrInsertFunction("__tsan_memcpy", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy); MemsetFn = - M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(), + M.getOrInsertFunction("__tsan_memset", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy); } diff --git a/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll b/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll index 9a1ef9e..d59efd9 100644 --- a/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll +++ b/llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll @@ -35,7 +35,7 @@ entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false) ret void ; CHECK: define void @MemCpyTest -; CHECK: call i8* @memcpy +; CHECK: call i8* @__tsan_memcpy ; CHECK: ret void } @@ -44,7 +44,7 @@ entry: tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false) ret void ; CHECK: define void @MemCpyInlineTest -; CHECK: call i8* @memcpy +; CHECK: call i8* @__tsan_memcpy ; CHECK: ret void } @@ -53,7 +53,7 @@ entry: tail call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false) ret void ; CHECK: define void @MemMoveTest -; CHECK: call i8* @memmove +; CHECK: call i8* @__tsan_memmove ; CHECK: ret void } @@ -62,7 +62,7 @@ entry: tail call void @llvm.memset.p0i8.i64(i8* align 4 %x, i8 77, i64 16, i1 false) ret void ; CHECK: define void @MemSetTest -; CHECK: call i8* @memset +; CHECK: call i8* @__tsan_memset ; CHECK: ret void } @@ -71,7 +71,7 @@ entry: tail call void @llvm.memset.inline.p0i8.i64(i8* align 4 %x, i8 77, i64 16, i1 false) ret void ; CHECK: define void @MemSetInlineTest -; CHECK: call i8* @memset +; CHECK: call i8* @__tsan_memset ; CHECK: ret void } -- 2.7.4