-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang][rtsan] Add sanitize_realtime_unsafe attr to [[clang::blocking]] function IR #111055
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
Conversation
@llvm/pr-subscribers-clang Author: None (davidtrevelyan) ChangesClang CodeGen for [[clang::blocking]] with RTSanFollows #106754 and #109543. This is the final patch for the feature. MotivationCalls to system library functions such as malloc are easy for RealtimeSanitizer to intercept. If such a call is made in a [[clang::nonblocking]] function (a real-time context), RealtimeSanitizer will error. Real-time programmers also write their own blocking (real-time unsafe) functions that may or may not call intercepted functions. We wish to introduce a mechanism whereby RealtimeSanitizer can error on calls to these, too, if called within a real-time context. At the same time as introducing [[clang::nonblocking]], the [[clang::blocking]] attribute was also introduced. With the function effects warnings (as errors) activated, blocking functions cannot be called from non-blocking functions, and this is enforced at compile time. The purpose of this series of PRs is to introduce similar functionality into RealtimeSanitizer, so that it can make the equivalent check at run time. ImplementationWe recently merged the Once the feature is switched on, RealtimeSanitizer will error if any calls to functions attributed with Integration RoadmapThe above functionality is currently split into three patches.
Full diff: https://github.com/llvm/llvm-project/pull/111055.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 24723e392c2a3a..e1fd9b72b8d7b2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -850,6 +850,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
for (const FunctionEffectWithCondition &Fe : FD->getFunctionEffects()) {
if (Fe.Effect.kind() == FunctionEffect::Kind::NonBlocking)
Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);
+ else if (Fe.Effect.kind() == FunctionEffect::Kind::Blocking)
+ Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeUnsafe);
}
// Apply fuzzing attribute to the function.
diff --git a/clang/test/CodeGen/rtsan_attribute_inserted.c b/clang/test/CodeGen/rtsan_attribute_inserted.c
index 05a1d9a8c2047a..b21ecb6b6b06a9 100644
--- a/clang/test/CodeGen/rtsan_attribute_inserted.c
+++ b/clang/test/CodeGen/rtsan_attribute_inserted.c
@@ -1,7 +1,11 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=realtime %s -emit-llvm -o - %s | FileCheck %s
float process(float *a) [[clang::nonblocking]] { return *a; }
-
-// CHECK-LABEL: @process{{.*}}#0 {
+// CHECK: @process{{.*}} #0 {
// CHECK: attributes #0 = {
-// CHECK-SAME: {{.*sanitize_realtime.*}}
+// CHECK-SAME: {{.*sanitize_realtime .*}}
+
+int spinlock(int *a) [[clang::blocking]] { return *a; }
+// CHECK: @spinlock{{.*}} #1 {
+// CHECK: attributes #1 = {
+// CHECK-SAME: {{.*sanitize_realtime_unsafe .*}}
diff --git a/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c b/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c
index 43ad6ed1a429ee..0f43007c5e4c16 100644
--- a/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c
+++ b/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
float process(float *a) [[clang::nonblocking]] { return *a; }
+int spinlock(int *a) [[clang::blocking]] { return *a; }
-// Without the -fsanitize=realtime flag, we shouldn't attach the attribute.
-// CHECK-NOT: {{.*sanitize_realtime.*}}
+// Without the -fsanitize=realtime flag, we shouldn't attach the attributes.
+// CHECK-NOT: {{.*sanitize_realtime .*}}
+// CHECK-NOT: {{.*sanitize_realtime_unsafe .*}}
|
@llvm/pr-subscribers-clang-codegen Author: None (davidtrevelyan) ChangesClang CodeGen for [[clang::blocking]] with RTSanFollows #106754 and #109543. This is the final patch for the feature. MotivationCalls to system library functions such as malloc are easy for RealtimeSanitizer to intercept. If such a call is made in a [[clang::nonblocking]] function (a real-time context), RealtimeSanitizer will error. Real-time programmers also write their own blocking (real-time unsafe) functions that may or may not call intercepted functions. We wish to introduce a mechanism whereby RealtimeSanitizer can error on calls to these, too, if called within a real-time context. At the same time as introducing [[clang::nonblocking]], the [[clang::blocking]] attribute was also introduced. With the function effects warnings (as errors) activated, blocking functions cannot be called from non-blocking functions, and this is enforced at compile time. The purpose of this series of PRs is to introduce similar functionality into RealtimeSanitizer, so that it can make the equivalent check at run time. ImplementationWe recently merged the Once the feature is switched on, RealtimeSanitizer will error if any calls to functions attributed with Integration RoadmapThe above functionality is currently split into three patches.
Full diff: https://github.com/llvm/llvm-project/pull/111055.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 24723e392c2a3a..e1fd9b72b8d7b2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -850,6 +850,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
for (const FunctionEffectWithCondition &Fe : FD->getFunctionEffects()) {
if (Fe.Effect.kind() == FunctionEffect::Kind::NonBlocking)
Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);
+ else if (Fe.Effect.kind() == FunctionEffect::Kind::Blocking)
+ Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeUnsafe);
}
// Apply fuzzing attribute to the function.
diff --git a/clang/test/CodeGen/rtsan_attribute_inserted.c b/clang/test/CodeGen/rtsan_attribute_inserted.c
index 05a1d9a8c2047a..b21ecb6b6b06a9 100644
--- a/clang/test/CodeGen/rtsan_attribute_inserted.c
+++ b/clang/test/CodeGen/rtsan_attribute_inserted.c
@@ -1,7 +1,11 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=realtime %s -emit-llvm -o - %s | FileCheck %s
float process(float *a) [[clang::nonblocking]] { return *a; }
-
-// CHECK-LABEL: @process{{.*}}#0 {
+// CHECK: @process{{.*}} #0 {
// CHECK: attributes #0 = {
-// CHECK-SAME: {{.*sanitize_realtime.*}}
+// CHECK-SAME: {{.*sanitize_realtime .*}}
+
+int spinlock(int *a) [[clang::blocking]] { return *a; }
+// CHECK: @spinlock{{.*}} #1 {
+// CHECK: attributes #1 = {
+// CHECK-SAME: {{.*sanitize_realtime_unsafe .*}}
diff --git a/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c b/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c
index 43ad6ed1a429ee..0f43007c5e4c16 100644
--- a/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c
+++ b/clang/test/CodeGen/rtsan_no_attribute_sanitizer_disabled.c
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
float process(float *a) [[clang::nonblocking]] { return *a; }
+int spinlock(int *a) [[clang::blocking]] { return *a; }
-// Without the -fsanitize=realtime flag, we shouldn't attach the attribute.
-// CHECK-NOT: {{.*sanitize_realtime.*}}
+// Without the -fsanitize=realtime flag, we shouldn't attach the attributes.
+// CHECK-NOT: {{.*sanitize_realtime .*}}
+// CHECK-NOT: {{.*sanitize_realtime_unsafe .*}}
|
@cjappl for review (and please could you also request reviews from the key interested parties?) PS I'll apply for membership after this PR so I hope this is the last time you'll have to do this for me :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will wait to merge for a bit to let others chime in, but LGTM
What is the reason we need to check something again at runtime that was already checked at compile-time? In case people didn't |
Yes indeed - that's one of a few scenarios where we believe this is needed:
RTSan differs from the performance constraints attributes in that it only flags violations that happen at run time, in contrast to flagging those that could happen at compile time. In this scenario, if a One of the design goals of the works was that these systems should be able to be used easily together, or separately, and that they should have analogous functionalities where possible. Hope that makes some sense! |
Thanks for confirming. Optionally mention this somewhere in a comment in the code for future reference. |
Clang CodeGen for [[clang::blocking]] with RTSan
Follows #106754 and #109543. This is the final patch for the feature.
Motivation
Calls to system library functions such as malloc are easy for RealtimeSanitizer to intercept. If such a call is made in a [[clang::nonblocking]] function (a real-time context), RealtimeSanitizer will error. Real-time programmers also write their own blocking (real-time unsafe) functions that may or may not call intercepted functions. We wish to introduce a mechanism whereby RealtimeSanitizer can error on calls to these, too, if called within a real-time context.
At the same time as introducing [[clang::nonblocking]], the [[clang::blocking]] attribute was also introduced. With the function effects warnings (as errors) activated, blocking functions cannot be called from non-blocking functions, and this is enforced at compile time. The purpose of this series of PRs is to introduce similar functionality into RealtimeSanitizer, so that it can make the equivalent check at run time.
Implementation
We recently merged the
sanitize_realtime_unsafe
LLVM function attribute intomain
, as well as the LLVM pass to notify the sanitizer runtime of the blocking call. Our final step is to switch on the feature by updating Clang's CodeGen. This patch just adds thesanitize_realtime_unsafe
attribute to the IR for functions attributed with[[clang::blocking]]
.Once the feature is switched on, RealtimeSanitizer will error if any calls to functions attributed with
[[clang::blocking]]
are made from[[clang::nonblocking]]
functions.Integration Roadmap
The above functionality is currently split into three patches.
sanitize_realtime_unsafe
attribute #106754,sanitize_realtime_unsafe
attribute to functions attributed with[[clang::blocking]]
(this PR)