1 ; KMSAN instrumentation tests
2 ; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s \
3 ; RUN: -check-prefixes=CHECK
4 ; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck %s -check-prefixes=CHECK
6 target 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"
7 target triple = "x86_64-unknown-linux-gnu"
9 ; Check the instrumentation prologue.
10 define void @Empty() nounwind uwtable sanitize_memory {
17 ; CHECK: @__msan_get_context_state()
19 ; CHECK: getelementptr {{.*}} i32 0, i32 0
21 ; CHECK: getelementptr {{.*}} i32 0, i32 1
23 ; CHECK: getelementptr {{.*}} i32 0, i32 2
25 ; CHECK: getelementptr {{.*}} i32 0, i32 3
26 ; %va_arg_overflow_size:
27 ; CHECK: getelementptr {{.*}} i32 0, i32 4
29 ; CHECK: getelementptr {{.*}} i32 0, i32 5
31 ; CHECK: getelementptr {{.*}} i32 0, i32 6
34 ; Check instrumentation of stores
36 define void @Store1(i8* nocapture %p, i8 %x) nounwind uwtable sanitize_memory {
42 ; CHECK-LABEL: @Store1
44 ; CHECK: @__msan_get_context_state()
45 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
47 ; CHECK: [[BASE2:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
48 ; CHECK: [[BASE:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
49 ; CHECK: [[SHADOW:%[a-z0-9_]+]] = inttoptr {{.*}} [[BASE]]
50 ; Load the shadow of %p and check it
51 ; CHECK: load i64, i64* [[SHADOW]]
55 ; CHECK: @__msan_metadata_ptr_for_store_1(i8* %p)
57 ; If the new shadow is non-zero, jump to __msan_chain_origin()
61 ; CHECK: @__msan_chain_origin
62 ; Storing origin here:
69 define void @Store2(i16* nocapture %p, i16 %x) nounwind uwtable sanitize_memory {
75 ; CHECK-LABEL: @Store2
77 ; CHECK: @__msan_get_context_state()
78 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
80 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
81 ; Load the shadow of %p and check it
86 ; CHECK: [[REG:%[0-9]+]] = bitcast i16* %p to i8*
87 ; CHECK: @__msan_metadata_ptr_for_store_2(i8* [[REG]])
89 ; If the new shadow is non-zero, jump to __msan_chain_origin()
93 ; CHECK: @__msan_chain_origin
94 ; Storing origin here:
102 define void @Store4(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory {
104 store i32 %x, i32* %p
108 ; CHECK-LABEL: @Store4
110 ; CHECK: @__msan_get_context_state()
111 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
112 ; CHECK: entry.split:
113 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
114 ; Load the shadow of %p and check it
118 ; CHECK: {{^[0-9]+}}:
119 ; CHECK: [[REG:%[0-9]+]] = bitcast i32* %p to i8*
120 ; CHECK: @__msan_metadata_ptr_for_store_4(i8* [[REG]])
122 ; If the new shadow is non-zero, jump to __msan_chain_origin()
125 ; CHECK: {{^[0-9]+}}:
126 ; CHECK: @__msan_chain_origin
127 ; Storing origin here:
130 ; CHECK: {{^[0-9]+}}:
134 define void @Store8(i64* nocapture %p, i64 %x) nounwind uwtable sanitize_memory {
136 store i64 %x, i64* %p
140 ; CHECK-LABEL: @Store8
142 ; CHECK: @__msan_get_context_state()
143 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
144 ; CHECK: entry.split:
145 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
146 ; Load the shadow of %p and check it
150 ; CHECK: {{^[0-9]+}}:
151 ; CHECK: [[REG:%[0-9]+]] = bitcast i64* %p to i8*
152 ; CHECK: @__msan_metadata_ptr_for_store_8(i8* [[REG]])
154 ; If the new shadow is non-zero, jump to __msan_chain_origin()
157 ; CHECK: {{^[0-9]+}}:
158 ; CHECK: @__msan_chain_origin
159 ; Storing origin here:
162 ; CHECK: {{^[0-9]+}}:
166 define void @Store16(i128* nocapture %p, i128 %x) nounwind uwtable sanitize_memory {
168 store i128 %x, i128* %p
172 ; CHECK-LABEL: @Store16
174 ; CHECK: @__msan_get_context_state()
175 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
176 ; CHECK: entry.split:
177 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
178 ; Load the shadow of %p and check it
182 ; CHECK: {{^[0-9]+}}:
183 ; CHECK: [[REG:%[0-9]+]] = bitcast i128* %p to i8*
184 ; CHECK: @__msan_metadata_ptr_for_store_n(i8* [[REG]], i64 16)
186 ; If the new shadow is non-zero, jump to __msan_chain_origin()
189 ; CHECK: {{^[0-9]+}}:
190 ; CHECK: @__msan_chain_origin
191 ; Storing origin here:
194 ; CHECK: {{^[0-9]+}}:
199 ; Check instrumentation of loads
201 define i8 @Load1(i8* nocapture %p) nounwind uwtable sanitize_memory {
207 ; CHECK-LABEL: @Load1
209 ; CHECK: @__msan_get_context_state()
210 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
211 ; CHECK: entry.split:
212 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
213 ; Load the shadow of %p and check it
217 ; CHECK: {{^[0-9]+}}:
218 ; Load the value from %p. This is done before accessing the shadow
219 ; to ease atomic handling.
221 ; CHECK: @__msan_metadata_ptr_for_load_1(i8* %p)
222 ; Load the shadow and origin.
227 define i16 @Load2(i16* nocapture %p) nounwind uwtable sanitize_memory {
229 %0 = load i16, i16* %p
233 ; CHECK-LABEL: @Load2
235 ; CHECK: @__msan_get_context_state()
236 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
237 ; CHECK: entry.split:
238 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
239 ; Load the shadow of %p and check it
243 ; CHECK: {{^[0-9]+}}:
244 ; Load the value from %p. This is done before accessing the shadow
245 ; to ease atomic handling.
247 ; CHECK: [[REG:%[0-9]+]] = bitcast i16* %p to i8*
248 ; CHECK: @__msan_metadata_ptr_for_load_2(i8* [[REG]])
249 ; Load the shadow and origin.
254 define i32 @Load4(i32* nocapture %p) nounwind uwtable sanitize_memory {
256 %0 = load i32, i32* %p
260 ; CHECK-LABEL: @Load4
262 ; CHECK: @__msan_get_context_state()
263 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
264 ; CHECK: entry.split:
265 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
266 ; Load the shadow of %p and check it
270 ; CHECK: {{^[0-9]+}}:
271 ; Load the value from %p. This is done before accessing the shadow
272 ; to ease atomic handling.
274 ; CHECK: [[REG:%[0-9]+]] = bitcast i32* %p to i8*
275 ; CHECK: @__msan_metadata_ptr_for_load_4(i8* [[REG]])
276 ; Load the shadow and origin.
280 define i64 @Load8(i64* nocapture %p) nounwind uwtable sanitize_memory {
282 %0 = load i64, i64* %p
286 ; CHECK-LABEL: @Load8
288 ; CHECK: @__msan_get_context_state()
289 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
290 ; CHECK: entry.split:
291 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
292 ; Load the shadow of %p and check it
296 ; CHECK: {{^[0-9]+}}:
297 ; Load the value from %p. This is done before accessing the shadow
298 ; to ease atomic handling.
300 ; CHECK: [[REG:%[0-9]+]] = bitcast i64* %p to i8*
301 ; CHECK: @__msan_metadata_ptr_for_load_8(i8* [[REG]])
302 ; Load the shadow and origin.
306 define i128 @Load16(i128* nocapture %p) nounwind uwtable sanitize_memory {
308 %0 = load i128, i128* %p
312 ; CHECK-LABEL: @Load16
314 ; CHECK: @__msan_get_context_state()
315 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
316 ; CHECK: entry.split:
317 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
318 ; Load the shadow of %p and check it
322 ; CHECK: {{^[0-9]+}}:
323 ; Load the value from %p. This is done before accessing the shadow
324 ; to ease atomic handling.
326 ; CHECK: [[REG:%[0-9]+]] = bitcast i128* %p to i8*
327 ; CHECK: @__msan_metadata_ptr_for_load_n(i8* [[REG]], i64 16)
328 ; Load the shadow and origin.
333 ; Test kernel-specific va_list instrumentation
335 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
336 declare void @llvm.va_start(i8*) nounwind
337 declare void @llvm.va_end(i8*)
338 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
339 declare dso_local i32 @VAListFn(i8*, %struct.__va_list_tag*) local_unnamed_addr
341 ; Function Attrs: nounwind uwtable
342 define dso_local i32 @VarArgFn(i8* %fmt, ...) local_unnamed_addr sanitize_memory #0 {
344 %args = alloca [1 x %struct.__va_list_tag], align 16
345 %0 = bitcast [1 x %struct.__va_list_tag]* %args to i8*
346 %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %args, i64 0, i64 0
347 call void @llvm.va_start(i8* nonnull %0)
348 %call = call i32 @VAListFn(i8* %fmt, %struct.__va_list_tag* nonnull %arraydecay)
349 call void @llvm.va_end(i8* nonnull %0)
353 ; Kernel is built without SSE support.
354 attributes #0 = { "target-features"="+fxsr,+x87,-sse" }
356 ; CHECK-LABEL: @VarArgFn
357 ; CHECK: @__msan_get_context_state()
358 ; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2
359 ; CHECK: [[VA_ARG_ORIGIN:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 3
360 ; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4
362 ; CHECK: entry.split:
363 ; CHECK: [[OSIZE:%[0-9]+]] = load i64, i64* [[VA_ARG_OVERFLOW_SIZE]]
364 ; Register save area is 48 bytes for non-SSE builds.
365 ; CHECK: [[SIZE:%[0-9]+]] = add i64 48, [[OSIZE]]
366 ; CHECK: [[SHADOWS:%[0-9]+]] = alloca i8, i64 [[SIZE]]
367 ; CHECK: [[VA_ARG_SHADOW]]
368 ; CHECK: call void @llvm.memcpy{{.*}}(i8* align 8 [[SHADOWS]], {{.*}}, i64 [[SIZE]]
369 ; CHECK: [[ORIGINS:%[0-9]+]] = alloca i8, i64 [[SIZE]]
370 ; CHECK: [[VA_ARG_ORIGIN]]
371 ; CHECK: call void @llvm.memcpy{{.*}}(i8* align 8 [[ORIGINS]], {{.*}}, i64 [[SIZE]]
372 ; CHECK: call i32 @VAListFn
374 ; Function Attrs: nounwind uwtable
375 define dso_local void @VarArgCaller() local_unnamed_addr sanitize_memory {
377 %call = tail call i32 (i8*, ...) @VarArgFn(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 123)
381 ; CHECK-LABEL: @VarArgCaller
384 ; CHECK: @__msan_get_context_state()
385 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
386 ; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2
387 ; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4
389 ; CHECK: entry.split:
390 ; CHECK: [[PARAM_SI:%[_a-z0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
391 ; CHECK: [[ARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[PARAM_SI]] to i64*
392 ; First argument is initialized
393 ; CHECK: store i64 0, i64* [[ARG1_S]]
395 ; Dangling cast of va_arg_shadow[0], unused because the first argument is fixed.
396 ; CHECK: [[VA_CAST0:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64
398 ; CHECK: [[VA_CAST1:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64
399 ; CHECK: [[ARG1_SI:%[_a-z0-9]+]] = add i64 [[VA_CAST1]], 8
400 ; CHECK: [[PARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[ARG1_SI]] to i32*
402 ; Shadow for 123 is 0.
403 ; CHECK: store i32 0, i32* [[ARG1_S]]
405 ; CHECK: store i64 0, i64* [[VA_ARG_OVERFLOW_SIZE]]
406 ; CHECK: call i32 (i8*, ...) @VarArgFn({{.*}} @.str{{.*}} i32 123)