OSDN Git Service

Support MSAN with Subzero JIT compiled code.
authorNicolas Capens <capn@google.com>
Fri, 6 Jul 2018 19:54:07 +0000 (15:54 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 6 Jul 2018 20:55:53 +0000 (20:55 +0000)
MemorySanitizer doesn't automatically work with dynamically generated
code or inline assembly, since it can't instrument it to know what
memory it touches. We can help it by marking all the memory that is
written to by Reactor with the Subzero back-end as initialized by
calling __msan_unpoison.

Note that writes to memory don't guarantee proper initialization. It
could be copying or writing other uninitialized values.

See also https://sites.google.com/a/chromium.org/dev/developers/testing/memorysanitizer

Bug chromium:860533

Change-Id: Idf64e43c6ab9b8f71f64723fc7e3653f6ea2fb30
Reviewed-on: https://swiftshader-review.googlesource.com/19789
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
src/Common/Memory.cpp
src/Reactor/SubzeroReactor.cpp
src/Renderer/Blitter.cpp

index 938223e..45fef40 100644 (file)
@@ -234,9 +234,9 @@ void deallocateExecutable(void *memory, size_t bytes)
 
 void clear(uint16_t *memory, uint16_t element, size_t count)
 {
-       #if defined(_MSC_VER) && defined(__x86__)
+       #if defined(_MSC_VER) && defined(__x86__) && !defined(MEMORY_SANITIZER)
                __stosw(memory, element, count);
-       #elif defined(__GNUC__) && defined(__x86__)
+       #elif defined(__GNUC__) && defined(__x86__) && !defined(MEMORY_SANITIZER)
                __asm__("rep stosw" : : "D"(memory), "a"(element), "c"(count));
        #else
                for(size_t i = 0; i < count; i++)
@@ -248,9 +248,9 @@ void clear(uint16_t *memory, uint16_t element, size_t count)
 
 void clear(uint32_t *memory, uint32_t element, size_t count)
 {
-       #if defined(_MSC_VER) && defined(__x86__)
+       #if defined(_MSC_VER) && defined(__x86__) && !defined(MEMORY_SANITIZER)
                __stosd((unsigned long*)memory, element, count);
-       #elif defined(__GNUC__) && defined(__x86__)
+       #elif defined(__GNUC__) && defined(__x86__) && !defined(MEMORY_SANITIZER)
                __asm__("rep stosl" : : "D"(memory), "a"(element), "c"(count));
        #else
                for(size_t i = 0; i < count; i++)
index 66099ec..e499496 100644 (file)
 
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_os_ostream.h"
+#include "llvm/Support/Compiler.h"
+
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
 
 #if defined(_WIN32)
 #ifndef WIN32_LEAN_AND_MEAN
@@ -894,6 +899,17 @@ namespace sw
 
        Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
        {
+               #if __has_feature(memory_sanitizer)
+                       // Mark all (non-stack) memory writes as initialized by calling __msan_unpoison
+                       if(align != 0)
+                       {
+                               auto call = Ice::InstCall::create(::function, 2, nullptr, ::context->getConstantInt64(reinterpret_cast<intptr_t>(__msan_unpoison)), false);
+                               call->addArg(ptr);
+                               call->addArg(::context->getConstantInt64(typeSize(type)));
+                               ::basicBlock->appendInst(call);
+                       }
+               #endif
+
                int valueType = (int)reinterpret_cast<intptr_t>(type);
 
                if((valueType & EmulatedBits) && (align != 0))   // Narrow vector not stored on stack.
index c5417d9..4245cd4 100644 (file)
@@ -141,13 +141,10 @@ namespace sw
                        return;
                }
 
-               // The memory sanitizer doesn't work with JIT compiled code
-               #if !defined(MEMORY_SANITIZER)
-                       if(blitReactor(source, sourceRect, dest, destRect, options))
-                       {
-                               return;
-                       }
-               #endif
+               if(blitReactor(source, sourceRect, dest, destRect, options))
+               {
+                       return;
+               }
 
                SliceRectF sRect = sourceRect;
                SliceRect dRect = destRect;