Skip to content

[KMSAN] Enable on PowerPC64 #73611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ ||
IsLoongArch64 || IsRISCV64)
Res |= SanitizerKind::Thread;
if (IsX86_64 || IsSystemZ)
if (IsX86_64 || IsSystemZ || IsPowerPC64)
Res |= SanitizerKind::KernelMemory;
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||
IsPowerPC64 || IsHexagon || IsLoongArch64 || IsRISCV64)
Expand Down
8 changes: 5 additions & 3 deletions llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@
/// __msan_metadata_ptr_for_store_n(ptr, size);
/// Note that the sanitizer code has to deal with how shadow/origin pairs
/// returned by the these functions are represented in different ABIs. In
/// the X86_64 ABI they are returned in RDX:RAX, and in the SystemZ ABI they
/// are written to memory pointed to by a hidden parameter.
/// the X86_64 ABI they are returned in RDX:RAX, in PowerPC64 they are
/// returned in r3 and r4, and in the SystemZ ABI they are written to memory
/// pointed to by a hidden parameter.
/// - TLS variables are stored in a single per-task struct. A call to a
/// function __msan_get_context_state() returning a pointer to that struct
/// is inserted into every instrumented function before the entry block;
Expand All @@ -139,7 +140,8 @@
/// Also, KMSAN currently ignores uninitialized memory passed into inline asm
/// calls, making sure we're on the safe side wrt. possible false positives.
///
/// KernelMemorySanitizer only supports X86_64 and SystemZ at the moment.
/// KernelMemorySanitizer only supports X86_64, SystemZ and PowerPC64 at the
/// moment.
///
//
// FIXME: This sanitizer does not yet handle scalable vectors
Expand Down
149 changes: 149 additions & 0 deletions llvm/test/Instrumentation/MemorySanitizer/PowerPC/kernel-ppc64le.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
; RUN: opt < %s -S -msan-kernel=1 -passes=msan 2>&1 | FileCheck %s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the directory name contains PowerPC, it's unnecessary to repeat ppc64le.

You can use basic-kernel.ll like SystemZ/ or kernel.ll.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other tests in the directory are named this way so I followed the convention.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

llvm/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll does not follow the convention. I think the new test should follow other tests which follow the convention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean. Would something like kernel-64le.ll work since PowerPC encompasses both 32 and 64 bit and big and little endian?


target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le--linux"

define void @Store1(ptr %p, i8 %x) sanitize_memory {
entry:
store i8 %x, ptr %p
ret void
}

; CHECK-LABEL: define {{[^@]+}}@Store1(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_1(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: store i8 {{.+}}, ptr [[SHADOW]]
; CHECK: ret void

define void @Store2(ptr %p, i16 %x) sanitize_memory {
entry:
store i16 %x, ptr %p
ret void
}

; CHECK-LABEL: define {{[^@]+}}@Store2(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_2(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: store i16 {{.+}}, ptr [[SHADOW]]
; CHECK: ret void

define void @Store4(ptr %p, i32 %x) sanitize_memory {
entry:
store i32 %x, ptr %p
ret void
}

; CHECK-LABEL: define {{[^@]+}}@Store4(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_4(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: store i32 {{.+}}, ptr [[SHADOW]]
; CHECK: ret void

define void @Store8(ptr %p, i64 %x) sanitize_memory {
entry:
store i64 %x, ptr %p
ret void
}

; CHECK-LABEL: define {{[^@]+}}@Store8(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_8(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: store i64 {{.+}}, ptr [[SHADOW]]
; CHECK: ret void

define void @Store16(ptr %p, i128 %x) sanitize_memory {
entry:
store i128 %x, ptr %p
ret void
}

; CHECK-LABEL: define {{[^@]+}}@Store16(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_store_n(ptr %p, i64 16)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: store i128 {{.+}}, ptr [[SHADOW]]
; CHECK: ret void

define i8 @Load1(ptr %p) sanitize_memory {
entry:
%0 = load i8, ptr %p
ret i8 %0
}

; CHECK-LABEL: define {{[^@]+}}@Load1(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_1(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i8, ptr [[SHADOW]]
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
; CHECK: store i8 [[SHADOW_VAL]], ptr %retval_shadow
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
; CHECK: ret i8 {{.+}}

define i16 @Load2(ptr %p) sanitize_memory {
entry:
%0 = load i16, ptr %p
ret i16 %0
}

; CHECK-LABEL: define {{[^@]+}}@Load2(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_2(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i16, ptr [[SHADOW]]
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
; CHECK: store i16 [[SHADOW_VAL]], ptr %retval_shadow
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
; CHECK: ret i16 {{.+}}

define i32 @Load4(ptr %p) sanitize_memory {
entry:
%0 = load i32, ptr %p
ret i32 %0
}

; CHECK-LABEL: define {{[^@]+}}@Load4(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_4(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i32, ptr [[SHADOW]]
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
; CHECK: store i32 [[SHADOW_VAL]], ptr %retval_shadow
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
; CHECK: ret i32 {{.+}}

define i64 @Load8(ptr %p) sanitize_memory {
entry:
%0 = load i64, ptr %p
ret i64 %0
}

; CHECK-LABEL: define {{[^@]+}}@Load8(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_8(ptr %p)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i64, ptr [[SHADOW]]
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
; CHECK: store i64 [[SHADOW_VAL]], ptr %retval_shadow
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
; CHECK: ret i64 {{.+}}

define i128 @Load16(ptr %p) sanitize_memory {
entry:
%0 = load i128, ptr %p
ret i128 %0
}

; CHECK-LABEL: define {{[^@]+}}@Load16(
; CHECK: [[META:%[a-z0-9_]+]] = call { ptr, ptr } @__msan_metadata_ptr_for_load_n(ptr %p, i64 16)
; CHECK: [[SHADOW:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 0
; CHECK: [[ORIGIN:%[a-z0-9_]+]] = extractvalue { ptr, ptr } [[META]], 1
; CHECK: [[SHADOW_VAL:%[a-z0-9_]+]] = load i128, ptr [[SHADOW]]
; CHECK: [[ORIGIN_VAL:%[a-z0-9_]+]] = load i32, ptr [[ORIGIN]]
; CHECK: store i128 [[SHADOW_VAL]], ptr %retval_shadow
; CHECK: store i32 [[ORIGIN_VAL]], ptr %retval_origin
; CHECK: ret i128 {{.+}}