1; KMSAN instrumentation tests 2; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck %s -check-prefixes=CHECK 3 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7; Check the instrumentation prologue. 8define void @Empty() nounwind uwtable sanitize_memory { 9entry: 10 ret void 11} 12 13; CHECK-LABEL: @Empty 14; CHECK: entry: 15; CHECK: @__msan_get_context_state() 16; %param_shadow: 17; CHECK: getelementptr {{.*}} i32 0, i32 0 18; %retval_shadow: 19; CHECK: getelementptr {{.*}} i32 0, i32 1 20; %va_arg_shadow: 21; CHECK: getelementptr {{.*}} i32 0, i32 2 22; %va_arg_origin: 23; CHECK: getelementptr {{.*}} i32 0, i32 3 24; %va_arg_overflow_size: 25; CHECK: getelementptr {{.*}} i32 0, i32 4 26; %param_origin: 27; CHECK: getelementptr {{.*}} i32 0, i32 5 28; %retval_origin: 29; CHECK: getelementptr {{.*}} i32 0, i32 6 30; CHECK: entry.split: 31 32; Check instrumentation of stores 33 34define void @Store1(i8* nocapture %p, i8 %x) nounwind uwtable sanitize_memory { 35entry: 36 store i8 %x, i8* %p 37 ret void 38} 39 40; CHECK-LABEL: @Store1 41; CHECK-LABEL: entry: 42; CHECK: @__msan_get_context_state() 43; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 44; CHECK-LABEL: entry.split: 45; CHECK: [[BASE2:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]] 46; CHECK: [[BASE:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]] 47; CHECK: [[SHADOW:%[a-z0-9_]+]] = inttoptr {{.*}} [[BASE]] 48; Load the shadow of %p and check it 49; CHECK: load i64, i64* [[SHADOW]] 50; CHECK: icmp 51; CHECK: br i1 52; CHECK-LABEL: <label> 53; CHECK: @__msan_metadata_ptr_for_store_1(i8* %p) 54; CHECK: store i8 55; If the new shadow is non-zero, jump to __msan_chain_origin() 56; CHECK: icmp 57; CHECK: br i1 58; CHECK: <label> 59; CHECK: @__msan_chain_origin 60; Storing origin here: 61; CHECK: store i32 62; CHECK: br label 63; CHECK: <label> 64; CHECK: store i8 65; CHECK: ret void 66 67define void @Store2(i16* nocapture %p, i16 %x) nounwind uwtable sanitize_memory { 68entry: 69 store i16 %x, i16* %p 70 ret void 71} 72 73; CHECK-LABEL: @Store2 74; CHECK-LABEL: entry: 75; CHECK: @__msan_get_context_state() 76; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 77; CHECK-LABEL: entry.split: 78; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 79; Load the shadow of %p and check it 80; CHECK: load i64 81; CHECK: icmp 82; CHECK: br i1 83; CHECK-LABEL: <label> 84; CHECK: [[REG:%[0-9]+]] = bitcast i16* %p to i8* 85; CHECK: @__msan_metadata_ptr_for_store_2(i8* [[REG]]) 86; CHECK: store i16 87; If the new shadow is non-zero, jump to __msan_chain_origin() 88; CHECK: icmp 89; CHECK: br i1 90; CHECK: <label> 91; CHECK: @__msan_chain_origin 92; Storing origin here: 93; CHECK: store i32 94; CHECK: br label 95; CHECK: <label> 96; CHECK: store i16 97; CHECK: ret void 98 99 100define void @Store4(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory { 101entry: 102 store i32 %x, i32* %p 103 ret void 104} 105 106; CHECK-LABEL: @Store4 107; CHECK-LABEL: entry: 108; CHECK: @__msan_get_context_state() 109; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 110; CHECK-LABEL: entry.split: 111; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 112; Load the shadow of %p and check it 113; CHECK: load i32 114; CHECK: icmp 115; CHECK: br i1 116; CHECK-LABEL: <label> 117; CHECK: [[REG:%[0-9]+]] = bitcast i32* %p to i8* 118; CHECK: @__msan_metadata_ptr_for_store_4(i8* [[REG]]) 119; CHECK: store i32 120; If the new shadow is non-zero, jump to __msan_chain_origin() 121; CHECK: icmp 122; CHECK: br i1 123; CHECK: <label> 124; CHECK: @__msan_chain_origin 125; Storing origin here: 126; CHECK: store i32 127; CHECK: br label 128; CHECK: <label> 129; CHECK: store i32 130; CHECK: ret void 131 132define void @Store8(i64* nocapture %p, i64 %x) nounwind uwtable sanitize_memory { 133entry: 134 store i64 %x, i64* %p 135 ret void 136} 137 138; CHECK-LABEL: @Store8 139; CHECK-LABEL: entry: 140; CHECK: @__msan_get_context_state() 141; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 142; CHECK-LABEL: entry.split: 143; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 144; Load the shadow of %p and check it 145; CHECK: load i64 146; CHECK: icmp 147; CHECK: br i1 148; CHECK-LABEL: <label> 149; CHECK: [[REG:%[0-9]+]] = bitcast i64* %p to i8* 150; CHECK: @__msan_metadata_ptr_for_store_8(i8* [[REG]]) 151; CHECK: store i64 152; If the new shadow is non-zero, jump to __msan_chain_origin() 153; CHECK: icmp 154; CHECK: br i1 155; CHECK: <label> 156; CHECK: @__msan_chain_origin 157; Storing origin here: 158; CHECK: store i32 159; CHECK: br label 160; CHECK: <label> 161; CHECK: store i64 162; CHECK: ret void 163 164define void @Store16(i128* nocapture %p, i128 %x) nounwind uwtable sanitize_memory { 165entry: 166 store i128 %x, i128* %p 167 ret void 168} 169 170; CHECK-LABEL: @Store16 171; CHECK-LABEL: entry: 172; CHECK: @__msan_get_context_state() 173; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 174; CHECK-LABEL: entry.split: 175; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 176; Load the shadow of %p and check it 177; CHECK: load i64 178; CHECK: icmp 179; CHECK: br i1 180; CHECK-LABEL: <label> 181; CHECK: [[REG:%[0-9]+]] = bitcast i128* %p to i8* 182; CHECK: @__msan_metadata_ptr_for_store_n(i8* [[REG]], i64 16) 183; CHECK: store i128 184; If the new shadow is non-zero, jump to __msan_chain_origin() 185; CHECK: icmp 186; CHECK: br i1 187; CHECK: <label> 188; CHECK: @__msan_chain_origin 189; Storing origin here: 190; CHECK: store i32 191; CHECK: br label 192; CHECK: <label> 193; CHECK: store i128 194; CHECK: ret void 195 196 197; Check instrumentation of loads 198 199define i8 @Load1(i8* nocapture %p) nounwind uwtable sanitize_memory { 200entry: 201 %0 = load i8, i8* %p 202 ret i8 %0 203} 204 205; CHECK-LABEL: @Load1 206; CHECK-LABEL: entry: 207; CHECK: @__msan_get_context_state() 208; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 209; CHECK-LABEL: entry.split: 210; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 211; Load the shadow of %p and check it 212; CHECK: load i64 213; CHECK: icmp 214; CHECK: br i1 215; CHECK-LABEL: <label> 216; Load the value from %p. This is done before accessing the shadow 217; to ease atomic handling. 218; CHECK: load i8 219; CHECK: @__msan_metadata_ptr_for_load_1(i8* %p) 220; Load the shadow and origin. 221; CHECK: load i8 222; CHECK: load i32 223 224 225define i16 @Load2(i16* nocapture %p) nounwind uwtable sanitize_memory { 226entry: 227 %0 = load i16, i16* %p 228 ret i16 %0 229} 230 231; CHECK-LABEL: @Load2 232; CHECK-LABEL: entry: 233; CHECK: @__msan_get_context_state() 234; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 235; CHECK-LABEL: entry.split: 236; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 237; Load the shadow of %p and check it 238; CHECK: load i64 239; CHECK: icmp 240; CHECK: br i1 241; CHECK-LABEL: <label> 242; Load the value from %p. This is done before accessing the shadow 243; to ease atomic handling. 244; CHECK: load i16 245; CHECK: [[REG:%[0-9]+]] = bitcast i16* %p to i8* 246; CHECK: @__msan_metadata_ptr_for_load_2(i8* [[REG]]) 247; Load the shadow and origin. 248; CHECK: load i16 249; CHECK: load i32 250 251 252define i32 @Load4(i32* nocapture %p) nounwind uwtable sanitize_memory { 253entry: 254 %0 = load i32, i32* %p 255 ret i32 %0 256} 257 258; CHECK-LABEL: @Load4 259; CHECK-LABEL: entry: 260; CHECK: @__msan_get_context_state() 261; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 262; CHECK-LABEL: entry.split: 263; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 264; Load the shadow of %p and check it 265; CHECK: load i64 266; CHECK: icmp 267; CHECK: br i1 268; CHECK-LABEL: <label> 269; Load the value from %p. This is done before accessing the shadow 270; to ease atomic handling. 271; CHECK: load i32 272; CHECK: [[REG:%[0-9]+]] = bitcast i32* %p to i8* 273; CHECK: @__msan_metadata_ptr_for_load_4(i8* [[REG]]) 274; Load the shadow and origin. 275; CHECK: load i32 276; CHECK: load i32 277 278define i64 @Load8(i64* nocapture %p) nounwind uwtable sanitize_memory { 279entry: 280 %0 = load i64, i64* %p 281 ret i64 %0 282} 283 284; CHECK-LABEL: @Load8 285; CHECK-LABEL: entry: 286; CHECK: @__msan_get_context_state() 287; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 288; CHECK-LABEL: entry.split: 289; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 290; Load the shadow of %p and check it 291; CHECK: load i64 292; CHECK: icmp 293; CHECK: br i1 294; CHECK-LABEL: <label> 295; Load the value from %p. This is done before accessing the shadow 296; to ease atomic handling. 297; CHECK: load i64 298; CHECK: [[REG:%[0-9]+]] = bitcast i64* %p to i8* 299; CHECK: @__msan_metadata_ptr_for_load_8(i8* [[REG]]) 300; Load the shadow and origin. 301; CHECK: load i64 302; CHECK: load i32 303 304define i128 @Load16(i128* nocapture %p) nounwind uwtable sanitize_memory { 305entry: 306 %0 = load i128, i128* %p 307 ret i128 %0 308} 309 310; CHECK-LABEL: @Load16 311; CHECK-LABEL: entry: 312; CHECK: @__msan_get_context_state() 313; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 314; CHECK-LABEL: entry.split: 315; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]] 316; Load the shadow of %p and check it 317; CHECK: load i64 318; CHECK: icmp 319; CHECK: br i1 320; CHECK-LABEL: <label> 321; Load the value from %p. This is done before accessing the shadow 322; to ease atomic handling. 323; CHECK: load i128 324; CHECK: [[REG:%[0-9]+]] = bitcast i128* %p to i8* 325; CHECK: @__msan_metadata_ptr_for_load_n(i8* [[REG]], i64 16) 326; Load the shadow and origin. 327; CHECK: load i128 328; CHECK: load i32 329 330 331; Test kernel-specific va_list instrumentation 332 333%struct.__va_list_tag = type { i32, i32, i8*, i8* } 334declare void @llvm.va_start(i8*) nounwind 335declare void @llvm.va_end(i8*) 336@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 337declare dso_local i32 @VAListFn(i8*, %struct.__va_list_tag*) local_unnamed_addr 338 339; Function Attrs: nounwind uwtable 340define dso_local i32 @VarArgFn(i8* %fmt, ...) local_unnamed_addr sanitize_memory #0 { 341entry: 342 %args = alloca [1 x %struct.__va_list_tag], align 16 343 %0 = bitcast [1 x %struct.__va_list_tag]* %args to i8* 344 %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %args, i64 0, i64 0 345 call void @llvm.va_start(i8* nonnull %0) 346 %call = call i32 @VAListFn(i8* %fmt, %struct.__va_list_tag* nonnull %arraydecay) 347 call void @llvm.va_end(i8* nonnull %0) 348 ret i32 %call 349} 350 351; Kernel is built without SSE support. 352attributes #0 = { "target-features"="+fxsr,+x87,-sse" } 353 354; CHECK-LABEL: @VarArgFn 355; CHECK: @__msan_get_context_state() 356; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2 357; CHECK: [[VA_ARG_ORIGIN:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 3 358; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4 359 360; CHECK-LABEL: entry.split: 361; CHECK: [[OSIZE:%[0-9]+]] = load i64, i64* [[VA_ARG_OVERFLOW_SIZE]] 362; Register save area is 48 bytes for non-SSE builds. 363; CHECK: [[SIZE:%[0-9]+]] = add i64 48, [[OSIZE]] 364; CHECK: [[SHADOWS:%[0-9]+]] = alloca i8, i64 [[SIZE]] 365; CHECK: [[VA_ARG_SHADOW]] 366; CHECK: call void @llvm.memcpy{{.*}}(i8* align 8 [[SHADOWS]], {{.*}}, i64 [[SIZE]] 367; CHECK: [[ORIGINS:%[0-9]+]] = alloca i8, i64 [[SIZE]] 368; CHECK: [[VA_ARG_ORIGIN]] 369; CHECK: call void @llvm.memcpy{{.*}}(i8* align 8 [[ORIGINS]], {{.*}}, i64 [[SIZE]] 370; CHECK: call i32 @VAListFn 371 372; Function Attrs: nounwind uwtable 373define dso_local void @VarArgCaller() local_unnamed_addr sanitize_memory { 374entry: 375 %call = tail call i32 (i8*, ...) @VarArgFn(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 123) 376 ret void 377} 378 379; CHECK-LABEL: @VarArgCaller 380 381; CHECK-LABEL: entry: 382; CHECK: @__msan_get_context_state() 383; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0 384; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2 385; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4 386 387; CHECK-LABEL: entry.split: 388; CHECK: [[PARAM_SI:%[_a-z0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]] 389; CHECK: [[ARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[PARAM_SI]] to i64* 390; First argument is initialized 391; CHECK: store i64 0, i64* [[ARG1_S]] 392 393; Dangling cast of va_arg_shadow[0], unused because the first argument is fixed. 394; CHECK: [[VA_CAST0:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64 395 396; CHECK: [[VA_CAST1:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64 397; CHECK: [[ARG1_SI:%[_a-z0-9]+]] = add i64 [[VA_CAST1]], 8 398; CHECK: [[PARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[ARG1_SI]] to i32* 399 400; Shadow for 123 is 0. 401; CHECK: store i32 0, i32* [[ARG1_S]] 402 403; CHECK: store i64 0, i64* [[VA_ARG_OVERFLOW_SIZE]] 404; CHECK: call i32 (i8*, ...) @VarArgFn({{.*}} @.str{{.*}} i32 123) 405