Skip to content

Commit 1b66306

Browse files
NMiehlbradtNicholas Miehlbradt
and
Nicholas Miehlbradt
authored
[KMSAN] Enable on PowerPC64 (#73611)
Enable -fsanitize=kernel-memory support in Clang. Add tests. --------- Co-authored-by: Nicholas Miehlbradt <[email protected]>
1 parent 307d91e commit 1b66306

File tree

3 files changed

+155
-4
lines changed

3 files changed

+155
-4
lines changed

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
815815
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ ||
816816
IsLoongArch64 || IsRISCV64)
817817
Res |= SanitizerKind::Thread;
818-
if (IsX86_64 || IsSystemZ)
818+
if (IsX86_64 || IsSystemZ || IsPowerPC64)
819819
Res |= SanitizerKind::KernelMemory;
820820
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||
821821
IsPowerPC64 || IsHexagon || IsLoongArch64 || IsRISCV64)

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,9 @@
124124
/// __msan_metadata_ptr_for_store_n(ptr, size);
125125
/// Note that the sanitizer code has to deal with how shadow/origin pairs
126126
/// returned by the these functions are represented in different ABIs. In
127-
/// the X86_64 ABI they are returned in RDX:RAX, and in the SystemZ ABI they
128-
/// are written to memory pointed to by a hidden parameter.
127+
/// the X86_64 ABI they are returned in RDX:RAX, in PowerPC64 they are
128+
/// returned in r3 and r4, and in the SystemZ ABI they are written to memory
129+
/// pointed to by a hidden parameter.
129130
/// - TLS variables are stored in a single per-task struct. A call to a
130131
/// function __msan_get_context_state() returning a pointer to that struct
131132
/// is inserted into every instrumented function before the entry block;
@@ -139,7 +140,8 @@
139140
/// Also, KMSAN currently ignores uninitialized memory passed into inline asm
140141
/// calls, making sure we're on the safe side wrt. possible false positives.
141142
///
142-
/// KernelMemorySanitizer only supports X86_64 and SystemZ at the moment.
143+
/// KernelMemorySanitizer only supports X86_64, SystemZ and PowerPC64 at the
144+
/// moment.
143145
///
144146
//
145147
// FIXME: This sanitizer does not yet handle scalable vectors
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
; RUN: opt < %s -S -msan-kernel=1 -passes=msan 2>&1 | FileCheck %s
2+
3+
target datalayout = "e-m:e-i64:64-n32:64"
4+
target triple = "powerpc64le--linux"
5+
6+
define void @Store1(ptr %p, i8 %x) sanitize_memory {
7+
entry:
8+
store i8 %x, ptr %p
9+
ret void
10+
}
11+
12+
; CHECK-LABEL: define {{[^@]+}}@Store1(
13+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_1(ptr %p)
14+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
15+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
16+
; CHECK: store i8 {{.+}}, ptr [[SHADOW]]
17+
; CHECK: ret void
18+
19+
define void @Store2(ptr %p, i16 %x) sanitize_memory {
20+
entry:
21+
store i16 %x, ptr %p
22+
ret void
23+
}
24+
25+
; CHECK-LABEL: define {{[^@]+}}@Store2(
26+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_2(ptr %p)
27+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
28+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
29+
; CHECK: store i16 {{.+}}, ptr [[SHADOW]]
30+
; CHECK: ret void
31+
32+
define void @Store4(ptr %p, i32 %x) sanitize_memory {
33+
entry:
34+
store i32 %x, ptr %p
35+
ret void
36+
}
37+
38+
; CHECK-LABEL: define {{[^@]+}}@Store4(
39+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_4(ptr %p)
40+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
41+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
42+
; CHECK: store i32 {{.+}}, ptr [[SHADOW]]
43+
; CHECK: ret void
44+
45+
define void @Store8(ptr %p, i64 %x) sanitize_memory {
46+
entry:
47+
store i64 %x, ptr %p
48+
ret void
49+
}
50+
51+
; CHECK-LABEL: define {{[^@]+}}@Store8(
52+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_8(ptr %p)
53+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
54+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
55+
; CHECK: store i64 {{.+}}, ptr [[SHADOW]]
56+
; CHECK: ret void
57+
58+
define void @Store16(ptr %p, i128 %x) sanitize_memory {
59+
entry:
60+
store i128 %x, ptr %p
61+
ret void
62+
}
63+
64+
; CHECK-LABEL: define {{[^@]+}}@Store16(
65+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_n(ptr %p, i64 16)
66+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
67+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
68+
; CHECK: store i128 {{.+}}, ptr [[SHADOW]]
69+
; CHECK: ret void
70+
71+
define i8 @Load1(ptr %p) sanitize_memory {
72+
entry:
73+
%0 = load i8, ptr %p
74+
ret i8 %0
75+
}
76+
77+
; CHECK-LABEL: define {{[^@]+}}@Load1(
78+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_1(ptr %p)
79+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
80+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
81+
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i8, ptr [[SHADOW]]
82+
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
83+
; CHECK: store i8 [[SHADOW_VAL]], ptr %retval_shadow
84+
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
85+
; CHECK: ret i8 {{.+}}
86+
87+
define i16 @Load2(ptr %p) sanitize_memory {
88+
entry:
89+
%0 = load i16, ptr %p
90+
ret i16 %0
91+
}
92+
93+
; CHECK-LABEL: define {{[^@]+}}@Load2(
94+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_2(ptr %p)
95+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
96+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
97+
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i16, ptr [[SHADOW]]
98+
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
99+
; CHECK: store i16 [[SHADOW_VAL]], ptr %retval_shadow
100+
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
101+
; CHECK: ret i16 {{.+}}
102+
103+
define i32 @Load4(ptr %p) sanitize_memory {
104+
entry:
105+
%0 = load i32, ptr %p
106+
ret i32 %0
107+
}
108+
109+
; CHECK-LABEL: define {{[^@]+}}@Load4(
110+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_4(ptr %p)
111+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
112+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
113+
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i32, ptr [[SHADOW]]
114+
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
115+
; CHECK: store i32 [[SHADOW_VAL]], ptr %retval_shadow
116+
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
117+
; CHECK: ret i32 {{.+}}
118+
119+
define i64 @Load8(ptr %p) sanitize_memory {
120+
entry:
121+
%0 = load i64, ptr %p
122+
ret i64 %0
123+
}
124+
125+
; CHECK-LABEL: define {{[^@]+}}@Load8(
126+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_8(ptr %p)
127+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
128+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
129+
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i64, ptr [[SHADOW]]
130+
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
131+
; CHECK: store i64 [[SHADOW_VAL]], ptr %retval_shadow
132+
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
133+
; CHECK: ret i64 {{.+}}
134+
135+
define i128 @Load16(ptr %p) sanitize_memory {
136+
entry:
137+
%0 = load i128, ptr %p
138+
ret i128 %0
139+
}
140+
141+
; CHECK-LABEL: define {{[^@]+}}@Load16(
142+
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_n(ptr %p, i64 16)
143+
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
144+
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
145+
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i128, ptr [[SHADOW]]
146+
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
147+
; CHECK: store i128 [[SHADOW_VAL]], ptr %retval_shadow
148+
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
149+
; CHECK: ret i128 {{.+}}

0 commit comments

Comments
 (0)