Fix MSAN LLVM jit false positives
Unpoison all buffers we store to.
Bug: b/140204746
Change-Id: I211d799b294932affe82cb310ed02d0c0ed5149a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40908
Tested-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index 1718957..29c29e1 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -48,6 +48,7 @@
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetOptions.h"
@@ -74,6 +75,10 @@
extern "C" void _chkstk();
#endif
+#if __has_feature(memory_sanitizer)
+# include <sanitizer/msan_interface.h>
+#endif
+
namespace {
// Cache provides a simple, thread-safe key-value store.
@@ -549,6 +554,9 @@
functions.emplace("sync_fetch_and_umax_4", reinterpret_cast<void *>(F::sync_fetch_and_umax_4));
functions.emplace("sync_fetch_and_umin_4", reinterpret_cast<void *>(F::sync_fetch_and_umin_4));
#endif
+#if __has_feature(memory_sanitizer)
+ functions.emplace("msan_unpoison", reinterpret_cast<void *>(__msan_unpoison));
+#endif
}
};
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index d3d021d..7d154b8 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -1049,6 +1049,22 @@
auto elTy = T(type);
ASSERT(V(ptr)->getType()->getContainedType(0) == elTy);
+#if __has_feature(memory_sanitizer)
+ // Mark all memory writes as initialized by calling __msan_unpoison
+ {
+ // void __msan_unpoison(const volatile void *a, size_t size)
+ auto voidTy = ::llvm::Type::getVoidTy(jit->context);
+ auto i8Ty = ::llvm::Type::getInt8Ty(jit->context);
+ auto voidPtrTy = i8Ty->getPointerTo();
+ auto sizetTy = ::llvm::IntegerType::get(jit->context, sizeof(size_t) * 8);
+ auto funcTy = ::llvm::FunctionType::get(voidTy, { voidPtrTy, sizetTy }, false);
+ auto func = jit->module->getOrInsertFunction("__msan_unpoison", funcTy);
+ auto size = jit->module->getDataLayout().getTypeStoreSize(elTy);
+ jit->builder->CreateCall(func, { jit->builder->CreatePointerCast(V(ptr), voidPtrTy),
+ ::llvm::ConstantInt::get(sizetTy, size) });
+ }
+#endif
+
if(!atomic)
{
jit->builder->CreateAlignedStore(V(value), V(ptr), alignment, isVolatile);