From 9aee7ef069d2013c7331c53ae5a28e3da773ac5c Mon Sep 17 00:00:00 2001 From: Chris Apple Date: Thu, 8 Aug 2024 17:35:38 -0700 Subject: [PATCH] [LLVM][rtsan] Add LLVM nosanitize_realtime attribute --- llvm/docs/LangRef.rst | 5 +++++ llvm/include/llvm/Bitcode/LLVMBitCodes.h | 1 + llvm/include/llvm/IR/Attributes.td | 3 +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 ++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 ++ llvm/lib/IR/Verifier.cpp | 6 ++++++ llvm/lib/Transforms/Utils/CodeExtractor.cpp | 1 + llvm/test/Bitcode/attributes.ll | 7 +++++++ llvm/test/Bitcode/compatibility.ll | 8 ++++++-- llvm/test/Verifier/rtsan-attrs.ll | 9 +++++++++ 10 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Verifier/rtsan-attrs.ll diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 445980a18e7e9..4887ae6ee9966 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2189,6 +2189,10 @@ example: ``nosanitize_coverage`` This attribute indicates that SanitizerCoverage instrumentation is disabled for this function. +``nosanitize_realtime`` + This attribute indicates that the Realtime Sanitizer instrumentation is + disabled for this function. + This attribute is incompatible with the ``sanitize_realtime`` attribute. ``null_pointer_is_valid`` If ``null_pointer_is_valid`` is set, then the ``null`` address in address-space 0 is considered to be a valid address for memory loads and @@ -2315,6 +2319,7 @@ example: This attribute indicates that RealtimeSanitizer checks (realtime safety analysis - no allocations, syscalls or exceptions) are enabled for this function. + This attribute is incompatible with the ``nosanitize_realtime`` attribute. ``speculative_load_hardening`` This attribute indicates that `Speculative Load Hardening `_ diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 4beac37a58344..8a2e6583af87c 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -759,6 +759,7 @@ enum AttributeKindCodes { ATTR_KIND_INITIALIZES = 94, ATTR_KIND_HYBRID_PATCHABLE = 95, ATTR_KIND_SANITIZE_REALTIME = 96, + ATTR_KIND_NO_SANITIZE_REALTIME = 97, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index 891e34fec0c79..80936c0ee8335 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -212,6 +212,9 @@ def NoSanitizeBounds : EnumAttr<"nosanitize_bounds", [FnAttr]>; /// No SanitizeCoverage instrumentation. def NoSanitizeCoverage : EnumAttr<"nosanitize_coverage", [FnAttr]>; +/// No SanitizeRealtime instrumentation. +def NoSanitizeRealtime : EnumAttr<"nosanitize_realtime", [FnAttr]>; + /// Null pointer in address space zero is valid. def NullPointerIsValid : EnumAttr<"null_pointer_is_valid", [FnAttr]>; diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index d4dbab04e8ecd..6767c7ca288bc 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2093,6 +2093,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoSanitizeBounds; case bitc::ATTR_KIND_NO_SANITIZE_COVERAGE: return Attribute::NoSanitizeCoverage; + case bitc::ATTR_KIND_NO_SANITIZE_REALTIME: + return Attribute::NoSanitizeRealtime; case bitc::ATTR_KIND_NULL_POINTER_IS_VALID: return Attribute::NullPointerIsValid; case bitc::ATTR_KIND_OPTIMIZE_FOR_DEBUGGING: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 2f3e90d6e3821..d21ff10d51d00 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -795,6 +795,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NO_SANITIZE_BOUNDS; case Attribute::NoSanitizeCoverage: return bitc::ATTR_KIND_NO_SANITIZE_COVERAGE; + case llvm::Attribute::NoSanitizeRealtime: + return bitc::ATTR_KIND_NO_SANITIZE_REALTIME; case Attribute::NullPointerIsValid: return bitc::ATTR_KIND_NULL_POINTER_IS_VALID; case Attribute::OptimizeForDebugging: diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index ac754b5d9638d..5ff1f3dfb0dc9 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2223,6 +2223,12 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, "Attributes 'optdebug and optnone' are incompatible!", V); } + Check(!(Attrs.hasFnAttr(Attribute::SanitizeRealtime) && + Attrs.hasFnAttr(Attribute::NoSanitizeRealtime)), + "Attributes " + "'sanitize_realtime and nosanitize_realtime' are incompatible!", + V); + if (Attrs.hasFnAttr(Attribute::OptimizeForDebugging)) { Check(!Attrs.hasFnAttr(Attribute::OptimizeForSize), "Attributes 'optsize and optdebug' are incompatible!", V); diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 81d3243c887fc..0b6f738a58dca 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -934,6 +934,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::NoUnwind: case Attribute::NoSanitizeBounds: case Attribute::NoSanitizeCoverage: + case Attribute::NoSanitizeRealtime: case Attribute::NullPointerIsValid: case Attribute::OptimizeForDebugging: case Attribute::OptForFuzzing: diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index 4402289ac170d..835622276ef27 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -511,6 +511,12 @@ define void @f92() sanitize_realtime ret void; } +; CHECK: define void @f93() #54 +define void @f93() nosanitize_realtime +{ + ret void; +} + ; CHECK: define void @f87() [[FNRETTHUNKEXTERN:#[0-9]+]] define void @f87() fn_ret_thunk_extern { ret void } @@ -606,6 +612,7 @@ define void @initializes(ptr initializes((-4, 0), (4, 8)) %a) { ; CHECK: attributes #51 = { uwtable(sync) } ; CHECK: attributes #52 = { nosanitize_bounds } ; CHECK: attributes #53 = { sanitize_realtime } +; CHECK: attributes #54 = { nosanitize_realtime } ; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern } ; CHECK: attributes [[SKIPPROFILE]] = { skipprofile } ; CHECK: attributes [[OPTDEBUG]] = { optdebug } diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll index fd60c49a4be39..c401cde8e146e 100644 --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -1562,7 +1562,7 @@ exit: ; CHECK: select <2 x i1> , <2 x i8> , <2 x i8> call void @f.nobuiltin() builtin - ; CHECK: call void @f.nobuiltin() #53 + ; CHECK: call void @f.nobuiltin() #54 call fastcc noalias ptr @f.noalias() noinline ; CHECK: call fastcc noalias ptr @f.noalias() #12 @@ -1992,6 +1992,9 @@ declare void @f.sanitize_numerical_stability() sanitize_numerical_stability declare void @f.sanitize_realtime() sanitize_realtime ; CHECK: declare void @f.sanitize_realtime() #52 +declare void @f.nosanitize_realtime() nosanitize_realtime +; CHECK: declare void @f.nosanitize_realtime() #53 + ; CHECK: declare nofpclass(snan) float @nofpclass_snan(float nofpclass(snan)) declare nofpclass(snan) float @nofpclass_snan(float nofpclass(snan)) @@ -2115,7 +2118,8 @@ define float @nofpclass_callsites(float %arg) { ; CHECK: attributes #50 = { allockind("alloc,uninitialized") } ; CHECK: attributes #51 = { sanitize_numerical_stability } ; CHECK: attributes #52 = { sanitize_realtime } -; CHECK: attributes #53 = { builtin } +; CHECK: attributes #53 = { nosanitize_realtime } +; CHECK: attributes #54 = { builtin } ;; Metadata diff --git a/llvm/test/Verifier/rtsan-attrs.ll b/llvm/test/Verifier/rtsan-attrs.ll new file mode 100644 index 0000000000000..42ab85163642b --- /dev/null +++ b/llvm/test/Verifier/rtsan-attrs.ll @@ -0,0 +1,9 @@ +; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s + +; CHECK: Attributes 'sanitize_realtime and nosanitize_realtime' are incompatible! +; CHECK-NEXT: ptr @sanitize_nosanitize +define void @sanitize_nosanitize() #0 { + ret void +} + +attributes #0 = { sanitize_realtime nosanitize_realtime }