[llvm] r348112 - [KMSAN] Enable -msan-handle-asm-conservative by default

Alexander Potapenko via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 3 02:15:44 PST 2018


Author: glider
Date: Mon Dec  3 02:15:43 2018
New Revision: 348112

URL: http://llvm.org/viewvc/llvm-project?rev=348112&view=rev
Log:
[KMSAN] Enable -msan-handle-asm-conservative by default

This change enables conservative assembly instrumentation in KMSAN builds
by default.
It's still possible to disable it with -msan-handle-asm-conservative=0
if something breaks. It's now impossible to enable conservative
instrumentation for userspace builds, but it's not used anyway.

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
    llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll
    llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=348112&r1=348111&r2=348112&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Mon Dec  3 02:15:43 2018
@@ -255,10 +255,13 @@ static cl::opt<bool> ClHandleICmpExact("
 // passed into an assembly call. Note that this may cause false positives.
 // Because it's impossible to figure out the array sizes, we can only unpoison
 // the first sizeof(type) bytes for each type* pointer.
+// The instrumentation is only enabled in KMSAN builds, and only if
+// -msan-handle-asm-conservative is on. This is done because we may want to
+// quickly disable assembly instrumentation when it breaks.
 static cl::opt<bool> ClHandleAsmConservative(
     "msan-handle-asm-conservative",
     cl::desc("conservative handling of inline assembly"), cl::Hidden,
-    cl::init(false));
+    cl::init(true));
 
 // This flag controls whether we check the shadow of the address
 // operand of load or store. Such bugs are very rare, since load from
@@ -3118,7 +3121,7 @@ struct MemorySanitizerVisitor : public I
       // outputs as clean. Note that any side effects of the inline asm that are
       // not immediately visible in its constraints are not handled.
       if (Call->isInlineAsm()) {
-        if (ClHandleAsmConservative)
+        if (ClHandleAsmConservative && MS.CompileKernel)
           visitAsmInstruction(I);
         else
           visitInstruction(I);

Modified: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll?rev=348112&r1=348111&r2=348112&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll (original)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll Mon Dec  3 02:15:43 2018
@@ -1,6 +1,6 @@
 ; Test for handling of asm constraints in MSan instrumentation.
-; RUN: opt < %s -msan -msan-check-access-address=0 -msan-handle-asm-conservative=0 -S | FileCheck -check-prefixes=CHECK,CHECK-NONCONS %s
-; RUN: opt < %s -msan -msan-check-access-address=0 -msan-handle-asm-conservative=1 -S | FileCheck -check-prefixes=CHECK,CHECK-CONS %s
+; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=0 -S | FileCheck -check-prefixes=CHECK,CHECK-NONCONS %s
+; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=1 -S | FileCheck -check-prefixes=CHECK,CHECK-CONS %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
@@ -40,9 +40,12 @@ entry:
 
 ; CHECK-LABEL: @f_1i_1o_reg
 ; CHECK: [[IS1_F1:%.*]] = load i32, i32* @is1, align 4
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
 ; CHECK: call i32 asm "",{{.*}}(i32 [[IS1_F1]])
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id1 to i64)
+; CHECK: [[PACK1_F1:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id1{{.*}})
+; CHECK: [[EXT1_F1:%.*]] = extractvalue { i8*, i32* } [[PACK1_F1]], 0
+; CHECK: [[CAST1_F1:%.*]] = bitcast i8* [[EXT1_F1]] to i32*
+; CHECK: store i32 0, i32* [[CAST1_F1]]
 
 
 ; Two input registers, two output registers:
@@ -62,11 +65,17 @@ entry:
 ; CHECK-LABEL: @f_2i_2o_reg
 ; CHECK: [[IS1_F2:%.*]] = load i32, i32* @is1, align 4
 ; CHECK: [[IS2_F2:%.*]] = load i32, i32* @is2, align 4
-; CHECK: call void @__msan_warning_noreturn()
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
+; CHECK: call void @__msan_warning
 ; CHECK: call { i32, i32 } asm "",{{.*}}(i32 [[IS1_F2]], i32 [[IS2_F2]])
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id1 to i64)
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id2 to i64)
+; CHECK: [[PACK1_F2:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id1{{.*}})
+; CHECK: [[EXT1_F2:%.*]] = extractvalue { i8*, i32* } [[PACK1_F2]], 0
+; CHECK: [[CAST1_F2:%.*]] = bitcast i8* [[EXT1_F2]] to i32*
+; CHECK: store i32 0, i32* [[CAST1_F2]]
+; CHECK: [[PACK2_F2:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id2{{.*}})
+; CHECK: [[EXT2_F2:%.*]] = extractvalue { i8*, i32* } [[PACK2_F2]], 0
+; CHECK: [[CAST2_F2:%.*]] = bitcast i8* [[EXT2_F2]] to i32*
+; CHECK: store i32 0, i32* [[CAST2_F2]]
 
 ; Input same as output, used twice:
 ;   asm("" : "=r" (id1), "=r" (id2) : "r" (id1), "r" (id2));
@@ -85,11 +94,17 @@ entry:
 ; CHECK-LABEL: @f_2i_2o_reuse2_reg
 ; CHECK: [[ID1_F3:%.*]] = load i32, i32* @id1, align 4
 ; CHECK: [[ID2_F3:%.*]] = load i32, i32* @id2, align 4
-; CHECK: call void @__msan_warning_noreturn()
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
+; CHECK: call void @__msan_warning
 ; CHECK: call { i32, i32 } asm "",{{.*}}(i32 [[ID1_F3]], i32 [[ID2_F3]])
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id1 to i64)
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id2 to i64)
+; CHECK: [[PACK1_F3:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id1{{.*}})
+; CHECK: [[EXT1_F3:%.*]] = extractvalue { i8*, i32* } [[PACK1_F3]], 0
+; CHECK: [[CAST1_F3:%.*]] = bitcast i8* [[EXT1_F3]] to i32*
+; CHECK: store i32 0, i32* [[CAST1_F3]]
+; CHECK: [[PACK2_F3:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id2{{.*}})
+; CHECK: [[EXT2_F3:%.*]] = extractvalue { i8*, i32* } [[PACK2_F3]], 0
+; CHECK: [[CAST2_F3:%.*]] = bitcast i8* [[EXT2_F3]] to i32*
+; CHECK: store i32 0, i32* [[CAST2_F3]]
 
 
 ; One of the input registers is also an output:
@@ -109,11 +124,17 @@ entry:
 ; CHECK-LABEL: @f_2i_2o_reuse1_reg
 ; CHECK: [[ID1_F4:%.*]] = load i32, i32* @id1, align 4
 ; CHECK: [[IS1_F4:%.*]] = load i32, i32* @is1, align 4
-; CHECK: call void @__msan_warning_noreturn()
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
+; CHECK: call void @__msan_warning
 ; CHECK: call { i32, i32 } asm "",{{.*}}(i32 [[ID1_F4]], i32 [[IS1_F4]])
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id1 to i64)
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id2 to i64)
+; CHECK: [[PACK1_F4:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id1{{.*}})
+; CHECK: [[EXT1_F4:%.*]] = extractvalue { i8*, i32* } [[PACK1_F4]], 0
+; CHECK: [[CAST1_F4:%.*]] = bitcast i8* [[EXT1_F4]] to i32*
+; CHECK: store i32 0, i32* [[CAST1_F4]]
+; CHECK: [[PACK2_F4:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id2{{.*}})
+; CHECK: [[EXT2_F4:%.*]] = extractvalue { i8*, i32* } [[PACK2_F4]], 0
+; CHECK: [[CAST2_F4:%.*]] = bitcast i8* [[EXT2_F4]] to i32*
+; CHECK: store i32 0, i32* [[CAST2_F4]]
 
 
 ; One input register, three output registers:
@@ -133,11 +154,20 @@ entry:
 
 ; CHECK-LABEL: @f_1i_3o_reg
 ; CHECK: [[IS1_F5:%.*]] = load i32, i32* @is1, align 4
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
 ; CHECK: call { i32, i32, i32 } asm "",{{.*}}(i32 [[IS1_F5]])
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id1 to i64)
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id2 to i64)
-; CHECK: store i32 0,{{.*}}ptrtoint (i32* @id3 to i64)
+; CHECK: [[PACK1_F5:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id1{{.*}})
+; CHECK: [[EXT1_F5:%.*]] = extractvalue { i8*, i32* } [[PACK1_F5]], 0
+; CHECK: [[CAST1_F5:%.*]] = bitcast i8* [[EXT1_F5]] to i32*
+; CHECK: store i32 0, i32* [[CAST1_F5]]
+; CHECK: [[PACK2_F5:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id2{{.*}})
+; CHECK: [[EXT2_F5:%.*]] = extractvalue { i8*, i32* } [[PACK2_F5]], 0
+; CHECK: [[CAST2_F5:%.*]] = bitcast i8* [[EXT2_F5]] to i32*
+; CHECK: store i32 0, i32* [[CAST2_F5]]
+; CHECK: [[PACK3_F5:%.*]] = call {{.*}} @__msan_metadata_ptr_for_store_4({{.*}}@id3{{.*}})
+; CHECK: [[EXT3_F5:%.*]] = extractvalue { i8*, i32* } [[PACK3_F5]], 0
+; CHECK: [[CAST3_F5:%.*]] = bitcast i8* [[EXT3_F5]] to i32*
+; CHECK: store i32 0, i32* [[CAST3_F5]]
 
 
 ; 2 input memory args, 2 output memory args:
@@ -170,7 +200,7 @@ entry:
 ; CHECK: [[IS1_F7:%.*]] = load i32, i32* @is1, align 4
 ; CHECK-CONS: call void @__msan_instrument_asm_load({{.*}}@is1{{.*}}, i64 4)
 ; CHECK-CONS: call void @__msan_instrument_asm_store({{.*}}@id1{{.*}}, i64 4)
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
 ; CHECK: call i32 asm "", "=r,=*m,r,*m,~{dirflag},~{fpsr},~{flags}"(i32* @id1, i32 [[IS1_F7]], i32* @is1)
 
 
@@ -212,9 +242,9 @@ entry:
 ; CHECK: [[C1_F9:%.*]] = load {{.*}} @c1
 ; CHECK: [[MEMCPY_S1_F9:%.*]] = load {{.*}} @memcpy_s1
 ; CHECK-CONS: call void @__msan_instrument_asm_store({{.*}}@pair2{{.*}}, i64 8)
-; CHECK: call void @__msan_warning_noreturn()
-; CHECK: call void @__msan_warning_noreturn()
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
+; CHECK: call void @__msan_warning
+; CHECK: call void @__msan_warning
 ; CHECK: call { i8, i8* (i8*, i8*, i32)* } asm "", "=*r,=r,=r,r,r,r,~{dirflag},~{fpsr},~{flags}"(%struct.pair* @pair2, {{.*}}[[PAIR1_F9]], i8 [[C1_F9]], {{.*}} [[MEMCPY_S1_F9]])
 
 ; Three inputs and three outputs of different types: a pair, a char, a function pointer.

Modified: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll?rev=348112&r1=348111&r2=348112&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll (original)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll Mon Dec  3 02:15:43 2018
@@ -1,6 +1,6 @@
 ; Test for the conservative assembly handling mode used by KMSAN.
-; RUN: opt < %s -msan -msan-check-access-address=0 -msan-handle-asm-conservative=0 -S | FileCheck -check-prefixes=CHECK,CHECK-NONCONS %s
-; RUN: opt < %s -msan -msan-check-access-address=0 -msan-handle-asm-conservative=1 -S | FileCheck -check-prefixes=CHECK,CHECK-CONS %s
+; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=0 -S | FileCheck -check-prefixes=CHECK,CHECK-NONCONS %s
+; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=1 -S | FileCheck -check-prefixes=CHECK,CHECK-CONS %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
@@ -52,9 +52,16 @@ if.else:
   ret i32 1
 }
 
+; %nr is first poisoned, then unpoisoned (written to). Need to optimize this in the future.
+; CHECK: [[NRC1:%.*]] = bitcast i64* %nr to i8*
+; CHECK: call void @__msan_poison_alloca(i8* [[NRC1]]{{.*}})
+; CHECK: [[NRC2:%.*]] = bitcast i64* %nr to i8*
+; CHECK: call { i8*, i32* } @__msan_metadata_ptr_for_store_8(i8* [[NRC2]])
+
 ; Hooks for inputs usually go before the assembly statement. But here we have none,
 ; because %nr is passed by value. However we check %nr for being initialized.
-; CHECK-CONS: [[NRC:%.*]] = ptrtoint i64* %nr to i64
+; CHECK-CONS: [[NRC3:%.*]] = bitcast i64* %nr to i8*
+; CHECK-CONS: call { i8*, i32* } @__msan_metadata_ptr_for_load_8(i8* [[NRC3]])
 
 ; In the conservative mode, call the store hooks for %bit and %addr:
 ; CHECK-CONS: call void @__msan_instrument_asm_store(i8* %bit, i64 1)
@@ -62,14 +69,17 @@ if.else:
 ; CHECK-CONS: call void @__msan_instrument_asm_store(i8* [[ADDR8S]], i64 8)
 
 ; Landing pad for the %nr check above.
-; CHECK-CONS: call void @__msan_warning_noreturn()
+; CHECK-CONS: call void @__msan_warning
 
 ; CHECK: call void asm "btsq $2, $1; setc $0"
 
 ; Calculating the shadow offset of %bit.
-; CHECK: [[PTR:%.*]] = ptrtoint {{.*}} %bit to i64
-; CHECK: [[SH_NUM:%.*]] = xor i64 [[PTR]]
-; CHECK: [[SHADOW:%.*]] = inttoptr i64 [[SH_NUM]] {{.*}}
+; CHECKz: [[PTR:%.*]] = ptrtoint {{.*}} %bit to i64
+; CHECKz: [[SH_NUM:%.*]] = xor i64 [[PTR]]
+; CHECKz: [[SHADOW:%.*]] = inttoptr i64 [[SH_NUM]] {{.*}}
+
+; CHECK: [[META:%.*]] = call {{.*}} @__msan_metadata_ptr_for_load_1(i8* %bit)
+; CHECK: [[SHADOW:%.*]] = extractvalue { i8*, i32* } [[META]], 0
 
 ; Now load the shadow value for the boolean.
 ; CHECK: [[MSLD:%.*]] = load {{.*}} [[SHADOW]]
@@ -81,5 +91,5 @@ if.else:
 
 ; If yes, raise a warning.
 ; CHECK: <label>:[[IFTRUE]]
-; CHECK: call void @__msan_warning_noreturn()
+; CHECK: call void @__msan_warning
 




More information about the llvm-commits mailing list