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