[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
This commit is contained in:
Vitaly Buka 2022-09-03 22:24:33 -07:00
parent 6cc52d594f
commit 77654a65a3
5 changed files with 32 additions and 8 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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
}