mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:50:30 +00:00
35b6dc44d1
The default assembly handling mode may introduce false positives in the cases when MSan doesn't understand that the assembly call initializes the memory pointed to by one of its arguments. We introduce the conservative mode, which initializes the first |sizeof(type)| bytes for every |type*| pointer passed into the assembly statement. llvm-svn: 329054
84 lines
3.0 KiB
LLVM
84 lines
3.0 KiB
LLVM
; 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
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
; The IR below was generated from the following source:
|
|
; int main() {
|
|
; bool bit;
|
|
; unsigned long value = 2;
|
|
; long nr = 0;
|
|
; unsigned long *addr = &value;
|
|
; asm("btsq %2, %1; setc %0" : "=qm" (bit), "=m" (addr): "Ir" (nr));
|
|
; if (bit)
|
|
; return 0
|
|
; else
|
|
; return 1;
|
|
; }
|
|
;
|
|
; In the regular instrumentation mode MSan is unable to understand that |bit|
|
|
; is initialized by the asm() call, and therefore reports a false positive on
|
|
; the if-statement.
|
|
; The conservative assembly handling mode initializes every memory location
|
|
; passed by pointer into an asm() call. This prevents false positive reports,
|
|
; but may introduce false negatives.
|
|
;
|
|
; This test makes sure that the conservative mode unpoisons the shadow of |bit|
|
|
; by writing 0 to it.
|
|
|
|
define dso_local i32 @main() sanitize_memory {
|
|
entry:
|
|
%retval = alloca i32, align 4
|
|
%bit = alloca i8, align 1
|
|
%value = alloca i64, align 8
|
|
%nr = alloca i64, align 8
|
|
%addr = alloca i64*, align 8
|
|
store i32 0, i32* %retval, align 4
|
|
store i64 2, i64* %value, align 8
|
|
store i64 0, i64* %nr, align 8
|
|
store i64* %value, i64** %addr, align 8
|
|
%0 = load i64, i64* %nr, align 8
|
|
call void asm "btsq $2, $1; setc $0", "=*qm,=*m,Ir,~{dirflag},~{fpsr},~{flags}"(i8* %bit, i64** %addr, i64 %0)
|
|
%1 = load i8, i8* %bit, align 1
|
|
%tobool = trunc i8 %1 to i1
|
|
br i1 %tobool, label %if.then, label %if.else
|
|
|
|
if.then: ; preds = %entry
|
|
ret i32 0
|
|
|
|
if.else: ; preds = %entry
|
|
ret i32 1
|
|
}
|
|
|
|
; Start with the asm call
|
|
; 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]], [[OFF:[0-9]*]]
|
|
; CHECK: [[SHADOW:%.*]] = inttoptr i64 [[SH_NUM]] {{.*}}
|
|
|
|
; In the conservative mode, unpoison the shadow.
|
|
; CHECK-CONS: store i8 0, i8* [[SHADOW]]
|
|
; Now calculate the shadow address again, because MSan does this for every
|
|
; shadow access.
|
|
; CHECK-CONS: [[PTR2:%.*]] = ptrtoint {{.*}} %bit to i64
|
|
; CHECK-CONS: [[SH_NUM2:%.*]] = xor i64 [[PTR2]], [[OFF]]
|
|
; CHECK-CONS: [[SHADOW2:%.*]] = inttoptr i64 [[SH_NUM2]] {{.*}}
|
|
|
|
; Now load the shadow value for the boolean.
|
|
; CHECK-NONCONS: [[MSLD:%.*]] = load {{.*}} [[SHADOW]]
|
|
; CHECK-CONS: [[MSLD:%.*]] = load {{.*}} [[SHADOW2]]
|
|
; CHECK: [[MSPROP:%.*]] = trunc i8 [[MSLD]] to i1
|
|
|
|
; Is the shadow poisoned?
|
|
; CHECK: [[MSCMP:%.*]] = icmp ne i1 [[MSPROP]], false
|
|
; CHECK: br i1 [[MSCMP]], label %[[IFTRUE:.*]], label {{.*}}
|
|
|
|
; If yes, raise a warning.
|
|
; CHECK: <label>:[[IFTRUE]]
|
|
; CHECK: call void @__msan_warning_noreturn()
|
|
|